u-isdn/cards/dumb/ncp_io.c

183 lines
4.7 KiB
C

inline static void
PostIRQ(struct _dumb * dumb)
{
}
inline static Byte
InISAC(struct _dumb * dumb, char offset) {
ByteOut(dumb->info.ioaddr+1,offset);
return ByteIn(dumb->info.ioaddr+2);
}
inline static void
OutISAC(struct _dumb * dumb, char offset, Byte data) {
ByteOut(dumb->info.ioaddr+1,offset);
ByteOut(dumb->info.ioaddr+2,data);
}
inline static Byte
InHSCX(struct _dumb * dumb, unsigned char hscx, char offset) {
ByteOut(dumb->info.ioaddr+1,offset+((hscx&1)?0x80:0xC0));
return ByteIn(dumb->info.ioaddr+2);
}
inline static void
OutHSCX(struct _dumb * dumb, unsigned char hscx, char offset, Byte what) {
ByteOut(dumb->info.ioaddr+1,offset+((hscx&1)?0x80:0xC0));
ByteOut(dumb->info.ioaddr+2,what);
}
inline static Byte
Slot(struct _dumb * dumb, unsigned char hscx) {
printf(" Slot %d: ",hscx);
return (hscx&1) ? 0x2F : 0x03;
}
static int
Init(struct _dumb * dumb) {
int timout;
long flags;
char iflag;
if(dumb->info.ioaddr == 0)
return -EINVAL;
dumb->numHSCX = 2;
save_flags(flags);
timout = jiffies+(HZ/20)+1;
ByteOut(dumb->info.ioaddr,0xF0);
sti();
while(jiffies <= timout) ;
ByteOut(dumb->info.ioaddr,0xE0);
timout = jiffies+(HZ/20)+1;
while(jiffies <= timout) ;
restore_flags(flags);
switch(ByteIn(dumb->info.ioaddr) & 0xE0) {
case 0: break;
default:
printf (" unknown card code %d ",ByteIn(dumb->info.ioaddr) >> 5);
return -EIO;
}
switch(dumb->info.irq) {
case 3: iflag = 0; break;
case 5: iflag = 4; break;
case 7: iflag = 2; break;
case 2: iflag = 6; break;
case 9: iflag = 6; break;
case 4: iflag = 1; break;
case 6: iflag = 5; break;
case 0: iflag = 7; break;
default:
printf (" impossible irq %d ",dumb->info.irq);
return -EINVAL;
}
ByteOut(dumb->info.ioaddr,(iflag<<5));
return 0;
}
static void
InitISAC(struct _dumb * dumb)
{
dumb->chan[0].mode = M_OFF;
dumb->chan[0].listen = 0;
ByteOutISAC(dumb, ADF2, 0x80);
ByteOutISAC(dumb, SPCR, 0x00);
ByteOutISAC(dumb, SQXR, 0x0F);
ByteOutISAC(dumb, STCR, 0x70);
ByteOutISAC(dumb, MODE, 0xC3);
ByteOutISAC(dumb, CIX0, 0x03);
ByteOutISAC(dumb, ADF1, 0x00);
ByteOutISAC(dumb, TIMR, 0xE9);
ByteOutISAC(dumb, MASK, 0x00);
}
static void
InitHSCX_(struct _dumb * dumb, unsigned char hscx)
{
ByteOutHSCX(dumb,hscx,TSAX, Slot(dumb,hscx));
ByteOutHSCX(dumb,hscx,TSAR, Slot(dumb,hscx));
ByteOutHSCX(dumb,hscx,XCCR, 7);
ByteOutHSCX(dumb,hscx,RCCR, 7);
ByteOutHSCX(dumb,hscx,MODE, 0x06);
ByteOutHSCX(dumb,hscx,CCR1, 0x85); /* 0x85 */
ByteOutHSCX(dumb,hscx,CCR2, 0x32); /* 0x38 */
ByteOutHSCX(dumb,hscx,XAD1, 0x01);
ByteOutHSCX(dumb,hscx,XAD2, 0x03);
ByteOutHSCX(dumb,hscx,RAL1, 0x03);
ByteOutHSCX(dumb,hscx,RAL2, 0x01);
ByteOutHSCX(dumb,hscx,RAH1, 0);
ByteOutHSCX(dumb,hscx,RAH2, 0);
#if 0
ByteOutHSCX(dumb,hscx,TIMR, 0x70);
#endif
ByteOutHSCX(dumb,hscx,MASK, 0x00);
}
static int
HSCX_mode(struct _dumb * dumb, unsigned char hscx, Byte mode, Byte listen)
{
unsigned long ms = SetSPL(dumb->info.ipl);
if(dumb->chan[hscx].m_in != NULL) {
freemsg(dumb->chan[hscx].m_in);
dumb->chan[hscx].m_in = dumb->chan[hscx].m_in_run = NULL;
}
if(dumb->chan[hscx].m_out != NULL) {
freemsg(dumb->chan[hscx].m_out);
dumb->chan[hscx].m_out = dumb->chan[hscx].m_out_run = NULL;
}
ByteOutHSCX(dumb,hscx,CCR2, 0x32);
ByteOutHSCX(dumb,hscx,TSAX, Slot(dumb,hscx));
ByteOutHSCX(dumb,hscx,TSAR, Slot(dumb,hscx));
ByteOutHSCX(dumb,hscx,XCCR, 7);
ByteOutHSCX(dumb,hscx,RCCR, 7);
ByteOutHSCX(dumb,hscx,CCR1, 0x05);
switch(mode) {
case M_OFF:
case M_STANDBY:
ByteOutHSCX(dumb,hscx,MASK, 0x00);
ByteOutHSCX(dumb,hscx,MODE, 0x96);
ByteOutHSCX(dumb,hscx,XAD1, 0xFF);
ByteOutHSCX(dumb,hscx,XAD2, 0xFF);
ByteOutHSCX(dumb,hscx,RAH2, 0xFF);
ByteOutHSCX(dumb,hscx,CMDR, 0x41);
dumb->chan[hscx].mode = mode;
dumb->chan[hscx].locked = 0;
dumb->chan[hscx].listen = listen;
break;
case M_TRANS_HDLC:
case M_TRANS_ALAW:
case M_TRANS_V110:
case M_TRANSPARENT:
ByteOutHSCX(dumb,hscx,MODE, 0xE6);
ByteOutHSCX(dumb,hscx,CMDR, 0x41);
ByteOutHSCX(dumb,hscx,MASK, 0x00);
dumb->chan[hscx].mode = mode;
dumb->chan[hscx].locked = 0;
dumb->chan[hscx].listen = listen;
break;
case M_HDLC_7H:
ByteOutHSCX(dumb,hscx,CCR2, 0x02);
ByteOutHSCX(dumb,hscx,TSAX, Slot(dumb,hscx)+1);
ByteOutHSCX(dumb,hscx,TSAR, Slot(dumb,hscx)+1);
/* FALL THRU */
case M_HDLC_7L:
ByteOutHSCX(dumb,hscx,XCCR, 6);
ByteOutHSCX(dumb,hscx,RCCR, 6);
/* FALL THRU */
case M_HDLC:
ByteOutHSCX(dumb,hscx,MODE, 0x8E);
ByteOutHSCX(dumb,hscx,CMDR, 0x41);
ByteOutHSCX(dumb,hscx,MASK, 0x00);
dumb->chan[hscx].mode = mode;
dumb->chan[hscx].locked = 0;
dumb->chan[hscx].listen = listen;
break;
default:
printf("HSCX unknown mode %x\n",mode);
splx(ms);
return -EIO;
}
splx(ms);
return 0;
}