Commit ee29d109 authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] MCA bus basic cleanups

parent ecf2c214
......@@ -194,10 +194,9 @@ struct resource mca_standard_resources[] = {
#define MCA_STANDARD_RESOURCES (sizeof(mca_standard_resources)/sizeof(struct resource))
void __init mca_init(void)
int __init mca_init(void)
{
unsigned int i, j;
unsigned long flags;
/* WARNING: Be careful when making changes here. Putting an adapter
* and the motherboard simultaneously into setup mode may result in
......@@ -209,16 +208,16 @@ void __init mca_init(void)
/* Make sure the MCA bus is present */
if(!MCA_bus)
return;
printk("Micro Channel bus detected.\n");
return -ENODEV;
printk(KERN_INFO "Micro Channel bus detected.\n");
/* Allocate MCA_info structure (at address divisible by 8) */
mca_info = (struct MCA_info *)kmalloc(sizeof(struct MCA_info), GFP_KERNEL);
if(mca_info == NULL) {
printk("Failed to allocate memory for mca_info!");
return;
printk(KERN_ERR "Failed to allocate memory for mca_info!");
return -ENOMEM;
}
memset(mca_info, 0, sizeof(struct MCA_info));
......@@ -320,6 +319,8 @@ void __init mca_init(void)
#ifdef CONFIG_PROC_FS
mca_do_proc_init();
#endif
return 0;
}
subsys_initcall(mca_init);
......@@ -329,16 +330,16 @@ subsys_initcall(mca_init);
static void mca_handle_nmi_slot(int slot, int check_flag)
{
if(slot < MCA_MAX_SLOT_NR) {
printk("NMI: caused by MCA adapter in slot %d (%s)\n", slot+1,
printk(KERN_CRIT "NMI: caused by MCA adapter in slot %d (%s)\n", slot+1,
mca_info->slot[slot].name);
} else if(slot == MCA_INTEGSCSI) {
printk("NMI: caused by MCA integrated SCSI adapter (%s)\n",
printk(KERN_CRIT "NMI: caused by MCA integrated SCSI adapter (%s)\n",
mca_info->slot[slot].name);
} else if(slot == MCA_INTEGVIDEO) {
printk("NMI: caused by MCA integrated video adapter (%s)\n",
printk(KERN_CRIT "NMI: caused by MCA integrated video adapter (%s)\n",
mca_info->slot[slot].name);
} else if(slot == MCA_MOTHERBOARD) {
printk("NMI: caused by motherboard (%s)\n",
printk(KERN_CRIT "NMI: caused by motherboard (%s)\n",
mca_info->slot[slot].name);
}
......@@ -350,7 +351,7 @@ static void mca_handle_nmi_slot(int slot, int check_flag)
pos6 = mca_read_pos(slot, 6);
pos7 = mca_read_pos(slot, 7);
printk("NMI: POS 6 = 0x%x, POS 7 = 0x%x\n", pos6, pos7);
printk(KERN_CRIT "NMI: POS 6 = 0x%x, POS 7 = 0x%x\n", pos6, pos7);
}
} /* mca_handle_nmi_slot */
......@@ -367,21 +368,19 @@ void mca_handle_nmi(void)
* adapter was responsible for the error.
*/
for(i = 0; i < MCA_NUMADAPTERS; i++) {
/* Bit 7 of POS 5 is reset when this adapter has a hardware
* error. Bit 7 it reset if there's error information
* available in POS 6 and 7.
*/
pos5 = mca_read_pos(i, 5);
for(i = 0; i < MCA_NUMADAPTERS; i++)
{
/* Bit 7 of POS 5 is reset when this adapter has a hardware
* error. Bit 7 it reset if there's error information
* available in POS 6 and 7.
*/
pos5 = mca_read_pos(i, 5);
if(!(pos5 & 0x80)) {
if(!(pos5 & 0x80)) {
mca_handle_nmi_slot(i, !(pos5 & 0x40));
return;
}
}
mca_nmi_hook();
} /* mca_handle_nmi */
......
......@@ -69,6 +69,8 @@ special acknowledgements to:
chars!
June 1st, 2000
corrected version codes, added support for the latest 2.3 changes
Oct 28th, 2002
cleaned up for the 2.5 tree <alan@redhat.com>
*************************************************************************/
......@@ -103,8 +105,9 @@ special acknowledgements to:
* have to pack all state info into the device struct!
* ------------------------------------------------------------------------ */
static char *MediaNames[Media_Count] =
{ "10BaseT", "10Base5", "Unknown", "10Base2" };
static char *MediaNames[Media_Count] = {
"10BaseT", "10Base5", "Unknown", "10Base2"
};
/* ------------------------------------------------------------------------
* private subfunctions
......@@ -113,7 +116,7 @@ static char *MediaNames[Media_Count] =
#ifdef DEBUG
/* dump all registers */
static void dumpregs(struct IBMLANA_NETDEV *dev)
static void dumpregs(struct net_device *dev)
{
int z;
......@@ -128,7 +131,7 @@ static void dumpregs(struct IBMLANA_NETDEV *dev)
/* dump parts of shared memory - only needed during debugging */
static void dumpmem(struct IBMLANA_NETDEV *dev, u32 start, u32 len)
static void dumpmem(struct net_device *dev, u32 start, u32 len)
{
int z;
......@@ -136,7 +139,7 @@ static void dumpmem(struct IBMLANA_NETDEV *dev, u32 start, u32 len)
for (z = 0; z < len; z++) {
if ((z & 15) == 0)
printk("%04x:", z);
printk(" %02x", IBMLANA_READB(dev->mem_start + start + z));
printk(" %02x", isa_readb(dev->mem_start + start + z));
if ((z & 15) == 15)
printk("\n");
}
......@@ -187,12 +190,12 @@ static void getaddrs(int slot, int *base, int *memlen, int *iobase,
/* wait on register value with mask and timeout */
static int wait_timeout(struct IBMLANA_NETDEV *dev, int regoffs, u16 mask,
static int wait_timeout(struct net_device *dev, int regoffs, u16 mask,
u16 value, int timeout)
{
unsigned long fin = jiffies + timeout;
while (jiffies != fin)
while (time_before(jiffies,fin))
if ((inw(dev->base_addr + regoffs) & mask) == value)
return 1;
......@@ -202,7 +205,7 @@ static int wait_timeout(struct IBMLANA_NETDEV *dev, int regoffs, u16 mask,
/* reset the whole board */
static void ResetBoard(struct IBMLANA_NETDEV *dev)
static void ResetBoard(struct net_device *dev)
{
unsigned char bcmval;
......@@ -226,7 +229,7 @@ static void ResetBoard(struct IBMLANA_NETDEV *dev)
/* calculate RAM layout & set up descriptors in RAM */
static void InitDscrs(struct IBMLANA_NETDEV *dev)
static void InitDscrs(struct net_device *dev)
{
ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
u32 addr, baddr, raddr;
......@@ -237,7 +240,7 @@ static void InitDscrs(struct IBMLANA_NETDEV *dev)
/* initialize RAM */
IBMLANA_SETIO(dev->mem_start, 0xaa,
isa_memset_io(dev->mem_start, 0xaa,
dev->mem_start - dev->mem_start);
/* setup n TX descriptors - independent of RAM size */
......@@ -257,29 +260,27 @@ static void InitDscrs(struct IBMLANA_NETDEV *dev)
else
tda.link = addr + sizeof(tda_t);
tda.link |= 1;
IBMLANA_TOIO(dev->mem_start + addr, &tda, sizeof(tda_t));
isa_memcpy_to_io(dev->mem_start + addr, &tda, sizeof(tda_t));
addr += sizeof(tda_t);
baddr += PKTSIZE;
}
/* calculate how many receive buffers fit into remaining memory */
priv->rxbufcnt = (dev->mem_end - dev->mem_start - baddr) /
(sizeof(rra_t) + sizeof(rda_t) + PKTSIZE);
priv->rxbufcnt = (dev->mem_end - dev->mem_start - baddr) / (sizeof(rra_t) + sizeof(rda_t) + PKTSIZE);
/* calculate receive addresses */
priv->rrastart = raddr = priv->txbufstart + (TXBUFCNT * PKTSIZE);
priv->rdastart = addr =
priv->rrastart + (priv->rxbufcnt * sizeof(rra_t));
priv->rxbufstart = baddr =
priv->rdastart + (priv->rxbufcnt * sizeof(rda_t));
priv->rdastart = addr = priv->rrastart + (priv->rxbufcnt * sizeof(rra_t));
priv->rxbufstart = baddr = priv->rdastart + (priv->rxbufcnt * sizeof(rda_t));
for (z = 0; z < priv->rxbufcnt; z++) {
rra.startlo = baddr;
rra.starthi = 0;
rra.cntlo = PKTSIZE >> 1;
rra.cnthi = 0;
IBMLANA_TOIO(dev->mem_start + raddr, &rra, sizeof(rra_t));
isa_memcpy_to_io(dev->mem_start + raddr, &rra, sizeof(rra_t));
rda.status = 0;
rda.length = 0;
......@@ -291,7 +292,7 @@ static void InitDscrs(struct IBMLANA_NETDEV *dev)
else
rda.link = 1;
rda.inuse = 1;
IBMLANA_TOIO(dev->mem_start + addr, &rda, sizeof(rda_t));
isa_memcpy_to_io(dev->mem_start + addr, &rda, sizeof(rda_t));
baddr += PKTSIZE;
raddr += sizeof(rra_t);
......@@ -310,7 +311,7 @@ static void InitDscrs(struct IBMLANA_NETDEV *dev)
/* set up Rx + Tx descriptors in SONIC */
static int InitSONIC(struct IBMLANA_NETDEV *dev)
static int InitSONIC(struct net_device *dev)
{
ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
......@@ -318,8 +319,7 @@ static int InitSONIC(struct IBMLANA_NETDEV *dev)
outw(0, SONIC_URRA);
outw(priv->rrastart, dev->base_addr + SONIC_RSA);
outw(priv->rrastart + (priv->rxbufcnt * sizeof(rra_t)),
dev->base_addr + SONIC_REA);
outw(priv->rrastart + (priv->rxbufcnt * sizeof(rra_t)), dev->base_addr + SONIC_REA);
outw(priv->rrastart, dev->base_addr + SONIC_RRP);
outw(priv->rrastart, dev->base_addr + SONIC_RWP);
......@@ -331,9 +331,7 @@ static int InitSONIC(struct IBMLANA_NETDEV *dev)
outw(CMDREG_RRRA, dev->base_addr + SONIC_CMDREG);
if (!wait_timeout(dev, SONIC_CMDREG, CMDREG_RRRA, 0, 2)) {
printk
("%s: SONIC did not respond on RRRA command - giving up.",
dev->name);
printk(KERN_ERR "%s: SONIC did not respond on RRRA command - giving up.", dev->name);
return 0;
}
......@@ -351,12 +349,11 @@ static int InitSONIC(struct IBMLANA_NETDEV *dev)
/* stop SONIC so we can reinitialize it */
static void StopSONIC(struct IBMLANA_NETDEV *dev)
static void StopSONIC(struct net_device *dev)
{
/* disable interrupts */
outb(inb(dev->base_addr + BCMREG) & (~BCMREG_IEN),
dev->base_addr + BCMREG);
outb(inb(dev->base_addr + BCMREG) & (~BCMREG_IEN), dev->base_addr + BCMREG);
outb(0, dev->base_addr + SONIC_IMREG);
/* reset the SONIC */
......@@ -380,7 +377,7 @@ static void putcam(camentry_t * cams, int *camcnt, char *addr)
(*camcnt)++;
}
static void InitBoard(struct IBMLANA_NETDEV *dev)
static void InitBoard(struct net_device *dev)
{
int camcnt;
camentry_t cams[16];
......@@ -395,14 +392,12 @@ static void InitBoard(struct IBMLANA_NETDEV *dev)
/* clear all spurious interrupts */
outw(inw(dev->base_addr + SONIC_ISREG),
dev->base_addr + SONIC_ISREG);
outw(inw(dev->base_addr + SONIC_ISREG), dev->base_addr + SONIC_ISREG);
/* set up the SONIC's bus interface - constant for this adapter -
must be done while the SONIC is in reset */
outw(DCREG_USR1 | DCREG_USR0 | DCREG_WC1 | DCREG_DW32,
dev->base_addr + SONIC_DCREG);
outw(DCREG_USR1 | DCREG_USR0 | DCREG_WC1 | DCREG_DW32, dev->base_addr + SONIC_DCREG);
outw(0, dev->base_addr + SONIC_DCREG2);
/* remove reset form the SONIC */
......@@ -434,9 +429,8 @@ static void InitBoard(struct IBMLANA_NETDEV *dev)
/* feed CDA into SONIC, initialize RCR value (always get broadcasts) */
IBMLANA_TOIO(dev->mem_start, cams, sizeof(camentry_t) * camcnt);
IBMLANA_TOIO(dev->mem_start + (sizeof(camentry_t) * camcnt),
&cammask, sizeof(cammask));
isa_memcpy_to_io(dev->mem_start, cams, sizeof(camentry_t) * camcnt);
isa_memcpy_to_io(dev->mem_start + (sizeof(camentry_t) * camcnt), &cammask, sizeof(cammask));
#ifdef DEBUG
printk("CAM setup:\n");
......@@ -447,9 +441,7 @@ static void InitBoard(struct IBMLANA_NETDEV *dev)
outw(camcnt, dev->base_addr + SONIC_CAMCNT);
outw(CMDREG_LCAM, dev->base_addr + SONIC_CMDREG);
if (!wait_timeout(dev, SONIC_CMDREG, CMDREG_LCAM, 0, 2)) {
printk
("%s:SONIC did not respond on LCAM command - giving up.",
dev->name);
printk(KERN_ERR "%s:SONIC did not respond on LCAM command - giving up.", dev->name);
return;
} else {
/* clear interrupt condition */
......@@ -470,12 +462,9 @@ static void InitBoard(struct IBMLANA_NETDEV *dev)
for (z = 0; z < camcnt; z++) {
outw(z, dev->base_addr + SONIC_CAMEPTR);
printk("Entry %d: %04x %04x %04x\n", z,
inw(dev->base_addr +
SONIC_CAMADDR0),
inw(dev->base_addr +
SONIC_CAMADDR1),
inw(dev->base_addr +
SONIC_CAMADDR2));
inw(dev->base_addr + SONIC_CAMADDR0),
inw(dev->base_addr + SONIC_CAMADDR1),
inw(dev->base_addr + SONIC_CAMADDR2));
}
outw(0, dev->base_addr + SONIC_CMDREG);
}
......@@ -515,13 +504,11 @@ static void InitBoard(struct IBMLANA_NETDEV *dev)
/* enable transmitter + receiver interrupts */
outw(CMDREG_RXEN, dev->base_addr + SONIC_CMDREG);
outw(IMREG_PRXEN | IMREG_RBEEN | IMREG_PTXEN | IMREG_TXEREN,
dev->base_addr + SONIC_IMREG);
outw(IMREG_PRXEN | IMREG_RBEEN | IMREG_PTXEN | IMREG_TXEREN, dev->base_addr + SONIC_IMREG);
/* turn on card interrupts */
outb(inb(dev->base_addr + BCMREG) | BCMREG_IEN,
dev->base_addr + BCMREG);
outb(inb(dev->base_addr + BCMREG) | BCMREG_IEN, dev->base_addr + BCMREG);
#ifdef DEBUG
printk("Register dump after initialization:\n");
......@@ -531,7 +518,7 @@ static void InitBoard(struct IBMLANA_NETDEV *dev)
/* start transmission of a descriptor */
static void StartTx(struct IBMLANA_NETDEV *dev, int descr)
static void StartTx(struct net_device *dev, int descr)
{
ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
int addr;
......@@ -554,7 +541,7 @@ static void StartTx(struct IBMLANA_NETDEV *dev, int descr)
/* receive buffer area exhausted */
static void irqrbe_handler(struct IBMLANA_NETDEV *dev)
static void irqrbe_handler(struct net_device *dev)
{
ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
......@@ -566,7 +553,7 @@ static void irqrbe_handler(struct IBMLANA_NETDEV *dev)
/* receive interrupt */
static void irqrx_handler(struct IBMLANA_NETDEV *dev)
static void irqrx_handler(struct net_device *dev)
{
ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
rda_t rda;
......@@ -577,12 +564,9 @@ static void irqrx_handler(struct IBMLANA_NETDEV *dev)
while (1) {
/* read descriptor that was next to be filled by SONIC */
rdaaddr =
priv->rdastart + (priv->nextrxdescr * sizeof(rda_t));
lrdaaddr =
priv->rdastart + (priv->lastrxdescr * sizeof(rda_t));
IBMLANA_FROMIO(&rda, dev->mem_start + rdaaddr,
sizeof(rda_t));
rdaaddr = priv->rdastart + (priv->nextrxdescr * sizeof(rda_t));
lrdaaddr = priv->rdastart + (priv->lastrxdescr * sizeof(rda_t));
isa_memcpy_fromio(&rda, dev->mem_start + rdaaddr, sizeof(rda_t));
/* iron out upper word halves of fields we use - SONIC will duplicate
bits 0..15 to 16..31 */
......@@ -609,7 +593,7 @@ static void irqrx_handler(struct IBMLANA_NETDEV *dev)
else {
/* copy out data */
IBMLANA_FROMIO(skb_put(skb, rda.length),
isa_memcpy_fromio(skb_put(skb, rda.length),
dev->mem_start +
rda.startlo, rda.length);
......@@ -620,15 +604,11 @@ static void irqrx_handler(struct IBMLANA_NETDEV *dev)
skb->ip_summed = CHECKSUM_NONE;
/* bookkeeping */
dev->last_rx = jiffies;
priv->stat.rx_packets++;
#if (LINUX_VERSION_CODE >= 0x20119) /* byte counters for kernel >= 2.1.25 */
priv->stat.rx_bytes += rda.length;
#endif
/* pass to the upper layers */
netif_rx(skb);
}
}
......@@ -637,10 +617,8 @@ static void irqrx_handler(struct IBMLANA_NETDEV *dev)
else {
priv->stat.rx_errors++;
if (rda.status & RCREG_FAER)
priv->stat.rx_frame_errors++;
if (rda.status & RCREG_CRCR)
priv->stat.rx_crc_errors++;
}
......@@ -649,14 +627,14 @@ static void irqrx_handler(struct IBMLANA_NETDEV *dev)
rda.link = 1;
rda.inuse = 1;
IBMLANA_TOIO(dev->mem_start + rdaaddr, &rda,
isa_memcpy_to_io(dev->mem_start + rdaaddr, &rda,
sizeof(rda_t));
/* set up link and EOL = 0 in currently last descriptor. Only write
the link field since the SONIC may currently already access the
other fields. */
IBMLANA_TOIO(dev->mem_start + lrdaaddr + 20, &rdaaddr, 4);
isa_memcpy_to_io(dev->mem_start + lrdaaddr + 20, &rdaaddr, 4);
/* advance indices */
......@@ -668,57 +646,39 @@ static void irqrx_handler(struct IBMLANA_NETDEV *dev)
/* transmit interrupt */
static void irqtx_handler(struct IBMLANA_NETDEV *dev)
static void irqtx_handler(struct net_device *dev)
{
ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
tda_t tda;
/* fetch descriptor (we forgot the size ;-) */
IBMLANA_FROMIO(&tda,
dev->mem_start + priv->tdastart +
(priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t));
isa_memcpy_fromio(&tda, dev->mem_start + priv->tdastart + (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t));
/* update statistics */
priv->stat.tx_packets++;
#if (LINUX_VERSION_CODE >= 0x020119)
priv->stat.tx_bytes += tda.length;
#endif
/* update our pointers */
priv->txused[priv->currtxdescr] = 0;
priv->txusedcnt--;
/* if there are more descriptors present in RAM, start them */
if (priv->txusedcnt > 0)
StartTx(dev, (priv->currtxdescr + 1) % TXBUFCNT);
/* tell the upper layer we can go on transmitting */
#if LINUX_VERSION_CODE >= 0x02032a
netif_wake_queue(dev);
#else
dev->tbusy = 0;
mark_bh(NET_BH);
#endif
}
static void irqtxerr_handler(struct IBMLANA_NETDEV *dev)
static void irqtxerr_handler(struct net_device *dev)
{
ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
tda_t tda;
/* fetch descriptor to check status */
IBMLANA_FROMIO(&tda,
dev->mem_start + priv->tdastart +
(priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t));
isa_memcpy_fromio(&tda, dev->mem_start + priv->tdastart + (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t));
/* update statistics */
priv->stat.tx_errors++;
if (tda.status & (TCREG_NCRS | TCREG_CRSL))
priv->stat.tx_carrier_errors++;
......@@ -730,47 +690,29 @@ static void irqtxerr_handler(struct IBMLANA_NETDEV *dev)
priv->stat.tx_fifo_errors++;
/* update our pointers */
priv->txused[priv->currtxdescr] = 0;
priv->txusedcnt--;
/* if there are more descriptors present in RAM, start them */
if (priv->txusedcnt > 0)
StartTx(dev, (priv->currtxdescr + 1) % TXBUFCNT);
/* tell the upper layer we can go on transmitting */
#if LINUX_VERSION_CODE >= 0x02032a
netif_wake_queue(dev);
#else
dev->tbusy = 0;
mark_bh(NET_BH);
#endif
}
/* general interrupt entry */
static void irq_handler(int irq, void *device, struct pt_regs *regs)
{
struct IBMLANA_NETDEV *dev = (struct IBMLANA_NETDEV *) device;
struct net_device *dev = (struct net_device *) device;
u16 ival;
/* in case we're not meant... */
if (!(inb(dev->base_addr + BCMREG) & BCMREG_IPEND))
return;
#if (LINUX_VERSION_CODE >= 0x02032a)
#if 0
set_bit(LINK_STATE_RXSEM, &dev->state);
#endif
#else
dev->interrupt = 1;
#endif
/* loop through the interrupt bits until everything is clear */
while (1) {
ival = inw(dev->base_addr + SONIC_ISREG);
......@@ -778,32 +720,20 @@ static void irq_handler(int irq, void *device, struct pt_regs *regs)
irqrbe_handler(dev);
outw(ISREG_RBE, dev->base_addr + SONIC_ISREG);
}
if (ival & ISREG_PKTRX) {
irqrx_handler(dev);
outw(ISREG_PKTRX, dev->base_addr + SONIC_ISREG);
}
if (ival & ISREG_TXDN) {
irqtx_handler(dev);
outw(ISREG_TXDN, dev->base_addr + SONIC_ISREG);
}
if (ival & ISREG_TXER) {
irqtxerr_handler(dev);
outw(ISREG_TXER, dev->base_addr + SONIC_ISREG);
}
break;
}
#if (LINUX_VERSION_CODE >= 0x02032a)
#if 0
clear_bit(LINK_STATE_RXSEM, &dev->state);
#endif
#else
dev->interrupt = 0;
#endif
}
/* ------------------------------------------------------------------------
......@@ -815,7 +745,7 @@ static void irq_handler(int irq, void *device, struct pt_regs *regs)
static int ibmlana_getinfo(char *buf, int slot, void *d)
{
int len = 0, i;
struct IBMLANA_NETDEV *dev = (struct IBMLANA_NETDEV *) d;
struct net_device *dev = (struct net_device *) d;
ibmlana_priv *priv;
/* can't say anything about an uninitialized device... */
......@@ -830,11 +760,8 @@ static int ibmlana_getinfo(char *buf, int slot, void *d)
len += sprintf(buf + len, "IRQ: %d\n", priv->realirq);
len += sprintf(buf + len, "I/O: %#lx\n", dev->base_addr);
len += sprintf(buf + len, "Memory: %#lx-%#lx\n", dev->mem_start,
dev->mem_end - 1);
len +=
sprintf(buf + len, "Transceiver: %s\n",
MediaNames[priv->medium]);
len += sprintf(buf + len, "Memory: %#lx-%#lx\n", dev->mem_start, dev->mem_end - 1);
len += sprintf(buf + len, "Transceiver: %s\n", MediaNames[priv->medium]);
len += sprintf(buf + len, "Device: %s\n", dev->name);
len += sprintf(buf + len, "MAC address:");
for (i = 0; i < 6; i++)
......@@ -847,44 +774,31 @@ static int ibmlana_getinfo(char *buf, int slot, void *d)
/* open driver. Means also initialization and start of LANCE */
static int ibmlana_open(struct IBMLANA_NETDEV *dev)
static int ibmlana_open(struct net_device *dev)
{
int result;
ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
/* register resources - only necessary for IRQ */
result =
request_irq(priv->realirq, irq_handler,
SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
result = request_irq(priv->realirq, irq_handler, SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
if (result != 0) {
printk("%s: failed to register irq %d\n", dev->name,
dev->irq);
printk(KERN_ERR "%s: failed to register irq %d\n", dev->name, dev->irq);
return result;
}
dev->irq = priv->realirq;
/* set up the card and SONIC */
InitBoard(dev);
/* initialize operational flags */
#if (LINUX_VERSION_CODE >= 0x02032a)
netif_start_queue(dev);
#else
dev->interrupt = 0;
dev->tbusy = 0;
dev->start = 1;
MOD_INC_USE_COUNT;
#endif
return 0;
}
/* close driver. Shut down board and free allocated resources */
static int ibmlana_close(struct IBMLANA_NETDEV *dev)
static int ibmlana_close(struct net_device *dev)
{
/* turn off board */
......@@ -892,17 +806,12 @@ static int ibmlana_close(struct IBMLANA_NETDEV *dev)
if (dev->irq != 0)
free_irq(dev->irq, dev);
dev->irq = 0;
#if (LINUX_VERSION_CODE < 0x02032a)
MOD_DEC_USE_COUNT;
#endif
return 0;
}
/* transmit a block. */
static int ibmlana_tx(struct sk_buff *skb, struct IBMLANA_NETDEV *dev)
static int ibmlana_tx(struct sk_buff *skb, struct net_device *dev)
{
ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
int retval = 0, tmplen, addr;
......@@ -910,16 +819,6 @@ static int ibmlana_tx(struct sk_buff *skb, struct IBMLANA_NETDEV *dev)
tda_t tda;
int baddr;
/* if we get called with a NULL descriptor, the Ethernet layer thinks
our card is stuck an we should reset it. We'll do this completely: */
if (skb == NULL) {
printk("%s: Resetting SONIC\n", dev->name);
StopSONIC(dev);
InitBoard(dev);
return 0; /* don't try to free the block here ;-) */
}
/* find out if there are free slots for a frame to transmit. If not,
the upper layer is in deep desperation and we simply ignore the frame. */
......@@ -930,12 +829,11 @@ static int ibmlana_tx(struct sk_buff *skb, struct IBMLANA_NETDEV *dev)
}
/* copy the frame data into the next free transmit buffer - fillup missing */
tmplen = skb->len;
if (tmplen < 60)
tmplen = 60;
baddr = priv->txbufstart + (priv->nexttxdescr * PKTSIZE);
IBMLANA_TOIO(dev->mem_start + baddr, skb->data, skb->len);
isa_memcpy_to_io(dev->mem_start + baddr, skb->data, skb->len);
/* copy filler into RAM - in case we're filling up...
we're filling a bit more than necessary, but that doesn't harm
......@@ -947,81 +845,60 @@ static int ibmlana_tx(struct sk_buff *skb, struct IBMLANA_NETDEV *dev)
unsigned int destoffs = skb->len, l = strlen(fill);
while (destoffs < tmplen) {
IBMLANA_TOIO(dev->mem_start + baddr + destoffs,
fill, l);
isa_memcpy_to_io(dev->mem_start + baddr + destoffs, fill, l);
destoffs += l;
}
}
/* set up the new frame descriptor */
addr = priv->tdastart + (priv->nexttxdescr * sizeof(tda_t));
IBMLANA_FROMIO(&tda, dev->mem_start + addr, sizeof(tda_t));
isa_memcpy_fromio(&tda, dev->mem_start + addr, sizeof(tda_t));
tda.length = tda.fraglength = tmplen;
IBMLANA_TOIO(dev->mem_start + addr, &tda, sizeof(tda_t));
isa_memcpy_to_io(dev->mem_start + addr, &tda, sizeof(tda_t));
/* if there were no active descriptors, trigger the SONIC */
save_flags(flags);
cli();
spin_lock_irqsave(&priv->lock, flags);
priv->txusedcnt++;
priv->txused[priv->nexttxdescr] = 1;
/* are all transmission slots used up ? */
if (priv->txusedcnt >= TXBUFCNT)
#if (LINUX_VERSION_CODE >= 0x02032a)
netif_stop_queue(dev);
#else
dev->tbusy = 1;
#endif
if (priv->txusedcnt == 1)
StartTx(dev, priv->nexttxdescr);
priv->nexttxdescr = (priv->nexttxdescr + 1) % TXBUFCNT;
restore_flags(flags);
tx_done:
/* When did that change exactly ? */
#if (LINUX_VERSION_CODE >= 0x20200)
spin_unlock_irqrestore(&priv->lock, flags);
tx_done:
dev_kfree_skb(skb);
#else
dev_kfree_skb(skb, FREE_WRITE);
#endif
return retval;
}
/* return pointer to Ethernet statistics */
static struct net_device_stats *ibmlana_stats(struct IBMLANA_NETDEV *dev)
static struct net_device_stats *ibmlana_stats(struct net_device *dev)
{
ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
return &(priv->stat);
return &priv->stat;
}
/* we don't support runtime reconfiguration, since am MCA card can
be unambigously identified by its POS registers. */
static int ibmlana_config(struct IBMLANA_NETDEV *dev, struct ifmap *map)
static int ibmlana_config(struct net_device *dev, struct ifmap *map)
{
return 0;
}
/* switch receiver mode. */
static void ibmlana_set_multicast_list(struct IBMLANA_NETDEV *dev)
static void ibmlana_set_multicast_list(struct net_device *dev)
{
/* first stop the SONIC... */
StopSONIC(dev);
/* ...then reinit it with the new flags */
InitBoard(dev);
}
......@@ -1031,7 +908,7 @@ static void ibmlana_set_multicast_list(struct IBMLANA_NETDEV *dev)
static int startslot; /* counts through slots when probing multiple devices */
int ibmlana_probe(struct IBMLANA_NETDEV *dev)
int ibmlana_probe(struct net_device *dev)
{
int force_detect = 0;
int slot, z;
......@@ -1039,22 +916,17 @@ int ibmlana_probe(struct IBMLANA_NETDEV *dev)
ibmlana_priv *priv;
ibmlana_medium medium;
#if (LINUX_VERSION_CODE >= 0x02032a)
SET_MODULE_OWNER(dev);
#endif
/* can't work without an MCA bus ;-) */
if (MCA_bus == 0)
return -ENODEV;
/* start address of 1 --> forced detection */
if (dev->mem_start == 1)
force_detect = 1;
/* search through slots */
if (dev != NULL) {
base = dev->mem_start;
irq = dev->irq;
......@@ -1063,70 +935,51 @@ int ibmlana_probe(struct IBMLANA_NETDEV *dev)
while (slot != -1) {
/* deduce card addresses */
getaddrs(slot, &base, &memlen, &iobase, &irq, &medium);
#if (LINUX_VERSION_CODE >= 0x20300)
/* slot already in use ? */
if (mca_is_adapter_used(slot)) {
slot = mca_find_adapter(IBM_LANA_ID, slot + 1);
continue;
}
#endif
/* were we looking for something different ? */
if ((dev->irq != 0) || (dev->mem_start != 0)) {
if ((dev->irq != 0) && (dev->irq != irq)) {
slot =
mca_find_adapter(IBM_LANA_ID,
slot + 1);
if (dev->irq != 0 || dev->mem_start != 0) {
if (dev->irq != 0 && dev->irq != irq) {
slot = mca_find_adapter(IBM_LANA_ID, slot + 1);
continue;
}
if ((dev->mem_start != 0)
&& (dev->mem_start != base)) {
slot =
mca_find_adapter(IBM_LANA_ID,
slot + 1);
if (dev->mem_start != 0 && dev->mem_start != base)
{
slot = mca_find_adapter(IBM_LANA_ID, slot + 1);
continue;
}
}
/* found something that matches */
break;
}
/* nothing found ? */
if (slot == -1)
return ((base != 0) || (irq != 0)) ? -ENXIO : -ENODEV;
return (base != 0 || irq != 0) ? -ENXIO : -ENODEV;
/* announce success */
printk("%s: IBM LAN Adapter/A found in slot %d\n", dev->name,
slot + 1);
printk(KERN_INFO "%s: IBM LAN Adapter/A found in slot %d\n", dev->name, slot + 1);
/* try to obtain I/O range */
if (!request_region(iobase, IBM_LANA_IORANGE, dev->name)) {
printk("%s: cannot allocate I/O range at %#x!\n", dev->name, iobase);
printk(KERN_ERR "%s: cannot allocate I/O range at %#x!\n", dev->name, iobase);
startslot = slot + 1;
return -EBUSY;
}
/* make procfs entries */
mca_set_adapter_name(slot, "IBM LAN Adapter/A");
mca_set_adapter_procfn(slot, (MCA_ProcFn) ibmlana_getinfo, dev);
#if (LINUX_VERSION_CODE >= 0x20200)
mca_mark_as_used(slot);
#endif
/* allocate structure */
priv = dev->priv =
(ibmlana_priv *) kmalloc(sizeof(ibmlana_priv), GFP_KERNEL);
priv = dev->priv = (ibmlana_priv *) kmalloc(sizeof(ibmlana_priv), GFP_KERNEL);
if (!priv) {
release_region(iobase, IBM_LANA_IORANGE);
return -ENOMEM;
......@@ -1134,7 +987,8 @@ int ibmlana_probe(struct IBMLANA_NETDEV *dev)
priv->slot = slot;
priv->realirq = irq;
priv->medium = medium;
memset(&(priv->stat), 0, sizeof(struct net_device_stats));
spin_lock_init(&priv->lock);
memset(&priv->stat, 0, sizeof(struct net_device_stats));
/* set base + irq for this device (irq not allocated so far) */
......@@ -1165,13 +1019,13 @@ int ibmlana_probe(struct IBMLANA_NETDEV *dev)
/* print config */
printk("%s: IRQ %d, I/O %#lx, memory %#lx-%#lx, "
printk(KERN_INFO "%s: IRQ %d, I/O %#lx, memory %#lx-%#lx, "
"MAC address %02x:%02x:%02x:%02x:%02x:%02x.\n",
dev->name, priv->realirq, dev->base_addr,
dev->mem_start, dev->mem_end - 1,
dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
printk("%s: %s medium\n", dev->name, MediaNames[priv->medium]);
printk(KERN_INFO "%s: %s medium\n", dev->name, MediaNames[priv->medium]);
/* reset board */
......@@ -1192,9 +1046,10 @@ int ibmlana_probe(struct IBMLANA_NETDEV *dev)
#define DEVMAX 5
static struct IBMLANA_NETDEV moddevs[DEVMAX];
static struct net_device moddevs[DEVMAX];
static int irq;
static int io;
MODULE_PARM(irq, "i");
MODULE_PARM(io, "i");
MODULE_PARM_DESC(irq, "IBM LAN/A IRQ number");
......@@ -1214,21 +1069,15 @@ int init_module(void)
if (res != 0)
return (z > 0) ? 0 : -EIO;
}
return 0;
}
void cleanup_module(void)
{
struct IBMLANA_NETDEV *dev;
struct net_device *dev;
ibmlana_priv *priv;
int z;
if (MOD_IN_USE) {
printk("cannot unload, module in use\n");
return;
}
for (z = 0; z < DEVMAX; z++) {
dev = moddevs + z;
if (dev->priv != NULL) {
......@@ -1239,9 +1088,7 @@ void cleanup_module(void)
dev->irq = 0;
release_region(dev->base_addr, IBM_LANA_IORANGE);
unregister_netdev(dev);
#if (LINUX_VERSION_CODE >= 0x20200)
mca_mark_as_unused(priv->slot);
#endif
mca_set_adapter_name(priv->slot, "");
mca_set_adapter_procfn(priv->slot, NULL, NULL);
kfree(dev->priv);
......
......@@ -3,22 +3,6 @@
#ifdef _IBM_LANA_DRIVER_
/* version-dependent functions/structures */
#if LINUX_VERSION_CODE >= 0x020318
#define IBMLANA_READB(addr) isa_readb(addr)
#define IBMLANA_TOIO(dest, src, len) isa_memcpy_toio(dest, src, len)
#define IBMLANA_FROMIO(dest, src, len) isa_memcpy_fromio(dest, src, len)
#define IBMLANA_SETIO(dest, val, len) isa_memset_io(dest, val, len)
#define IBMLANA_NETDEV net_device
#else
#define IBMLANA_READB(addr) readb(addr)
#define IBMLANA_TOIO(dest, src, len) memcpy_toio(dest, src, len)
#define IBMLANA_FROMIO(dest, src, len) memcpy_fromio(dest, src, len)
#define IBMLANA_SETIO(dest, val, len) memset_io(dest, val, len)
#define IBMLANA_NETDEV device
#endif
/* maximum packet size */
#define PKTSIZE 1524
......@@ -33,25 +17,27 @@
/* media enumeration - defined in a way that it fits onto the LAN/A's
POS registers... */
typedef enum { Media_10BaseT, Media_10Base5,
typedef enum {
Media_10BaseT, Media_10Base5,
Media_Unknown, Media_10Base2, Media_Count
} ibmlana_medium;
/* private structure */
typedef struct {
unsigned int slot; /* MCA-Slot-# */
unsigned int slot; /* MCA-Slot-# */
struct net_device_stats stat; /* packet statistics */
int realirq; /* memorizes actual IRQ, even when
currently not allocated */
ibmlana_medium medium; /* physical cannector */
u32 tdastart, txbufstart, /* addresses */
rrastart, rxbufstart, rdastart, rxbufcnt, txusedcnt;
int nextrxdescr, /* next rx descriptor to be used */
lastrxdescr, /* last free rx descriptor */
nexttxdescr, /* last tx descriptor to be used */
currtxdescr, /* tx descriptor currently tx'ed */
txused[TXBUFCNT]; /* busy flags */
int realirq; /* memorizes actual IRQ, even when
currently not allocated */
ibmlana_medium medium; /* physical cannector */
u32 tdastart, txbufstart, /* addresses */
rrastart, rxbufstart, rdastart, rxbufcnt, txusedcnt;
int nextrxdescr, /* next rx descriptor to be used */
lastrxdescr, /* last free rx descriptor */
nexttxdescr, /* last tx descriptor to be used */
currtxdescr, /* tx descriptor currently tx'ed */
txused[TXBUFCNT]; /* busy flags */
spinlock_t lock;
} ibmlana_priv;
/* this card uses quite a lot of I/O ports...luckily the MCA bus decodes
......@@ -289,7 +275,7 @@ typedef struct {
#endif /* _IBM_LANA_DRIVER_ */
extern int ibmlana_probe(struct IBMLANA_NETDEV *);
extern int ibmlana_probe(struct net_device *);
#endif /* _IBM_LANA_INCLUDE_ */
......@@ -1780,7 +1780,7 @@ static int xl_change_mtu(struct net_device *dev, int mtu)
static void __devexit xl_remove_one (struct pci_dev *pdev)
{
struct net_device *dev = pdev->driver_data;
struct net_device *dev = pci_get_drvdata(pdev);
struct xl_private *xl_priv=(struct xl_private *)dev->priv;
unregister_trdev(dev);
......
......@@ -24,13 +24,12 @@
*
* To do:
* 1. Multicast support.
*
* Initial 2.5 cleanup Alan Cox <alan@redhat.com> 2002/10/28
*/
#ifdef MODULE
#include <linux/module.h>
#include <linux/version.h>
#endif
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
......@@ -341,7 +340,7 @@ static int smctr_alloc_shared_memory(struct net_device *dev)
struct net_local *tp = (struct net_local *)dev->priv;
if(smctr_debug > 10)
printk("%s: smctr_alloc_shared_memory\n", dev->name);
printk(KERN_DEBUG "%s: smctr_alloc_shared_memory\n", dev->name);
/* Allocate initial System Control Block pointer.
* This pointer is located in the last page, last offset - 4.
......@@ -456,10 +455,9 @@ static int smctr_bypass_state(struct net_device *dev)
int err;
if(smctr_debug > 10)
printk("%s: smctr_bypass_state\n", dev->name);
printk(KERN_DEBUG "%s: smctr_bypass_state\n", dev->name);
err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE,
JS_BYPASS_STATE);
err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, JS_BYPASS_STATE);
return (err);
}
......@@ -470,7 +468,7 @@ static int smctr_checksum_firmware(struct net_device *dev)
__u16 i, checksum = 0;
if(smctr_debug > 10)
printk("%s: smctr_checksum_firmware\n", dev->name);
printk(KERN_DEBUG "%s: smctr_checksum_firmware\n", dev->name);
smctr_enable_adapter_ctrl_store(dev);
......@@ -656,7 +654,7 @@ static int smctr_chg_rx_mask(struct net_device *dev)
int err = 0;
if(smctr_debug > 10)
printk("%s: smctr_chg_rx_mask\n", dev->name);
printk(KERN_DEBUG "%s: smctr_chg_rx_mask\n", dev->name);
smctr_enable_16bit(dev);
smctr_set_page(dev, (__u8 *)tp->ram_access);
......@@ -787,7 +785,7 @@ static int smctr_decode_firmware(struct net_device *dev)
__u16 *mem;
if(smctr_debug > 10)
printk("%s: smctr_decode_firmware\n", dev->name);
printk(KERN_DEBUG "%s: smctr_decode_firmware\n", dev->name);
weight = *(long *)(tp->ptr_ucode + WEIGHT_OFFSET);
tsize = *(__u8 *)(tp->ptr_ucode + TREE_SIZE_OFFSET);
......@@ -852,7 +850,7 @@ static int smctr_disable_adapter_ctrl_store(struct net_device *dev)
int ioaddr = dev->base_addr;
if(smctr_debug > 10)
printk("%s: smctr_disable_adapter_ctrl_store\n", dev->name);
printk(KERN_DEBUG "%s: smctr_disable_adapter_ctrl_store\n", dev->name);
tp->trc_mask |= CSR_WCSS;
outb(tp->trc_mask, ioaddr + CSR);
......@@ -898,7 +896,7 @@ static int smctr_enable_adapter_ctrl_store(struct net_device *dev)
int ioaddr = dev->base_addr;
if(smctr_debug > 10)
printk("%s: smctr_enable_adapter_ctrl_store\n", dev->name);
printk(KERN_DEBUG "%s: smctr_enable_adapter_ctrl_store\n", dev->name);
smctr_set_trc_reset(ioaddr);
smctr_enable_adapter_ram(dev);
......@@ -915,7 +913,7 @@ static int smctr_enable_adapter_ram(struct net_device *dev)
__u8 r;
if(smctr_debug > 10)
printk("%s: smctr_enable_adapter_ram\n", dev->name);
printk(KERN_DEBUG "%s: smctr_enable_adapter_ram\n", dev->name);
r = inb(ioaddr + MSR);
outb(MSR_MEMB | r, ioaddr + MSR);
......@@ -958,7 +956,7 @@ static int __init smctr_chk_isa(struct net_device *dev)
int i;
if(smctr_debug > 10)
printk("%s: smctr_chk_isa %#4x\n", dev->name, ioaddr);
printk(KERN_DEBUG "%s: smctr_chk_isa %#4x\n", dev->name, ioaddr);
if((ioaddr & 0x1F) != 0)
return (-ENODEV);
......@@ -979,7 +977,7 @@ static int __init smctr_chk_isa(struct net_device *dev)
b = inb(ioaddr + BDID);
if(b != BRD_ID_8115T)
{
printk("%s: The adapter found is not supported\n", dev->name);
printk(KERN_ERR "%s: The adapter found is not supported\n", dev->name);
return (-1);
}
......@@ -1079,7 +1077,7 @@ static int __init smctr_chk_isa(struct net_device *dev)
break;
default:
printk("%s: No IRQ found aborting\n", dev->name);
printk(KERN_ERR "%s: No IRQ found aborting\n", dev->name);
return(-1);
}
......@@ -1159,7 +1157,7 @@ static int __init smctr_chk_isa(struct net_device *dev)
/* see if the chip is corrupted
if(smctr_read_584_chksum(ioaddr))
{
printk("%s: EEPROM Checksum Failure\n", dev->name);
printk(KERN_ERR "%s: EEPROM Checksum Failure\n", dev->name);
return(-1);
}
*/
......@@ -1412,7 +1410,7 @@ static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue,
unsigned short *temp;
if(smctr_debug > 20)
printk("smctr_get_tx_fcb\n");
printk(KERN_DEBUG "smctr_get_tx_fcb\n");
/* check if there is enough FCB blocks */
if(tp->num_tx_fcbs_used[queue] >= tp->num_tx_fcbs[queue])
......@@ -1481,7 +1479,7 @@ static int smctr_hardware_send_packet(struct net_device *dev,
FCBlock *fcb;
if(smctr_debug > 10)
printk("%s: smctr_hardware_send_packet\n", dev->name);
printk(KERN_DEBUG"%s: smctr_hardware_send_packet\n", dev->name);
if(tp->status != OPEN)
return (-1);
......@@ -1533,7 +1531,7 @@ static int smctr_init_acbs(struct net_device *dev)
ACBlock *acb;
if(smctr_debug > 10)
printk("%s: smctr_init_acbs\n", dev->name);
printk(KERN_DEBUG "%s: smctr_init_acbs\n", dev->name);
acb = tp->acb_head;
acb->cmd_done_status = (ACB_COMMAND_DONE | ACB_COMMAND_SUCCESSFUL);
......@@ -1576,7 +1574,7 @@ static int smctr_init_adapter(struct net_device *dev)
int err;
if(smctr_debug > 10)
printk("%s: smctr_init_adapter\n", dev->name);
printk(KERN_DEBUG "%s: smctr_init_adapter\n", dev->name);
tp->status = CLOSED;
tp->page_offset_mask = (tp->ram_usable * 1024) - 1;
......@@ -1605,12 +1603,12 @@ static int smctr_init_adapter(struct net_device *dev)
if(smctr_checksum_firmware(dev))
{
printk("%s: Previously loaded firmware is missing\n",dev->name); return (-ENOENT);
printk(KERN_ERR "%s: Previously loaded firmware is missing\n",dev->name); return (-ENOENT);
}
if((err = smctr_ram_memory_test(dev)))
{
printk("%s: RAM memory test failed.\n", dev->name);
printk(KERN_ERR "%s: RAM memory test failed.\n", dev->name);
return (-EIO);
}
......@@ -1621,7 +1619,7 @@ static int smctr_init_adapter(struct net_device *dev)
smctr_reset_adapter(dev);
if((err = smctr_init_card_real(dev)))
{
printk("%s: Initialization of card failed (%d)\n",
printk(KERN_ERR "%s: Initialization of card failed (%d)\n",
dev->name, err);
return (-EINVAL);
}
......@@ -1629,7 +1627,7 @@ static int smctr_init_adapter(struct net_device *dev)
/* This routine clobbers the TRC's internal registers. */
if((err = smctr_internal_self_test(dev)))
{
printk("%s: Card failed internal self test (%d)\n",
printk(KERN_ERR "%s: Card failed internal self test (%d)\n",
dev->name, err);
return (-EINVAL);
}
......@@ -1638,7 +1636,7 @@ static int smctr_init_adapter(struct net_device *dev)
smctr_reset_adapter(dev);
if((err = smctr_init_card_real(dev)))
{
printk("%s: Initialization of card failed (%d)\n",
printk(KERN_ERR "%s: Initialization of card failed (%d)\n",
dev->name, err);
return (-EINVAL);
}
......@@ -1657,7 +1655,7 @@ static int smctr_init_adapter(struct net_device *dev)
static int __init smctr_init_card(struct net_device *dev)
{
if(smctr_debug > 10)
printk("%s: smctr_init_card\n", dev->name);
printk(KERN_DEBUG "%s: smctr_init_card\n", dev->name);
return (0);
}
......@@ -1668,7 +1666,7 @@ static int smctr_init_card_real(struct net_device *dev)
int err = 0;
if(smctr_debug > 10)
printk("%s: smctr_init_card_real\n", dev->name);
printk(KERN_DEBUG "%s: smctr_init_card_real\n", dev->name);
tp->sh_mem_used = 0;
tp->num_acbs = NUM_OF_ACBS;
......@@ -1731,7 +1729,7 @@ static int smctr_init_card_real(struct net_device *dev)
if((err = smctr_issue_init_txrx_cmd(dev)))
{
printk("%s: Hardware failure\n", dev->name);
printk(KERN_ERR "%s: Hardware failure\n", dev->name);
return (err);
}
......@@ -1746,7 +1744,7 @@ static int smctr_init_rx_bdbs(struct net_device *dev)
__u16 *buf;
if(smctr_debug > 10)
printk("%s: smctr_init_rx_bdbs\n", dev->name);
printk(KERN_DEBUG "%s: smctr_init_rx_bdbs\n", dev->name);
for(i = 0; i < NUM_RX_QS_USED; i++)
{
......@@ -1847,7 +1845,7 @@ static int smctr_init_shared_memory(struct net_device *dev)
__u32 *iscpb;
if(smctr_debug > 10)
printk("%s: smctr_init_shared_memory\n", dev->name);
printk(KERN_DEBUG "%s: smctr_init_shared_memory\n", dev->name);
smctr_set_page(dev, (__u8 *)(unsigned int)tp->iscpb_ptr);
......@@ -2017,16 +2015,19 @@ static void smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if(dev == NULL)
{
printk("%s: irq %d for unknown device.\n", dev->name, irq);
printk(KERN_CRIT "%s: irq %d for unknown device.\n", dev->name, irq);
return;
}
ioaddr = dev->base_addr;
tp = (struct net_local *)dev->priv;
if(tp->status == NOT_INITIALIZED)
return;
spin_lock(&tp->lock);
smctr_disable_bic_int(dev);
smctr_enable_16bit(dev);
......@@ -2046,6 +2047,7 @@ static void smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if(isb_type >= 0x10)
{
smctr_disable_16bit(dev);
spin_unlock(&tp->lock);
return;
}
......@@ -2063,56 +2065,45 @@ static void smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
switch(isb_subtype)
{
case 0:
tp->monitor_state
= MS_MONITOR_FSM_INACTIVE;
break;
tp->monitor_state = MS_MONITOR_FSM_INACTIVE;
break;
case 1:
tp->monitor_state
= MS_REPEAT_BEACON_STATE;
tp->monitor_state = MS_REPEAT_BEACON_STATE;
break;
case 2:
tp->monitor_state
= MS_REPEAT_CLAIM_TOKEN_STATE;
tp->monitor_state = MS_REPEAT_CLAIM_TOKEN_STATE;
break;
case 3:
tp->monitor_state
= MS_TRANSMIT_CLAIM_TOKEN_STATE; break;
tp->monitor_state = MS_TRANSMIT_CLAIM_TOKEN_STATE; break;
case 4:
tp->monitor_state
= MS_STANDBY_MONITOR_STATE;
tp->monitor_state = MS_STANDBY_MONITOR_STATE;
break;
case 5:
tp->monitor_state
= MS_TRANSMIT_BEACON_STATE;
tp->monitor_state = MS_TRANSMIT_BEACON_STATE;
break;
case 6:
tp->monitor_state
= MS_ACTIVE_MONITOR_STATE;
tp->monitor_state = MS_ACTIVE_MONITOR_STATE;
break;
case 7:
tp->monitor_state
= MS_TRANSMIT_RING_PURGE_STATE;
tp->monitor_state = MS_TRANSMIT_RING_PURGE_STATE;
break;
case 8: /* diagnostic state */
break;
case 9:
tp->monitor_state
= MS_BEACON_TEST_STATE;
tp->monitor_state = MS_BEACON_TEST_STATE;
if(smctr_lobe_media_test(dev))
{
tp->ring_status_flags
= RING_STATUS_CHANGED;
tp->ring_status
= AUTO_REMOVAL_ERROR;
tp->ring_status_flags = RING_STATUS_CHANGED;
tp->ring_status = AUTO_REMOVAL_ERROR;
smctr_ring_status_chg(dev);
smctr_bypass_state(dev);
}
......@@ -2162,16 +2153,14 @@ static void smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* BUG QUEUE for TRC stuck receive BUG */
if(isb_subtype & TX_PENDING_PRIORITY_2)
{
if((err = smctr_tx_complete(dev,
BUG_QUEUE)) != SUCCESS)
if((err = smctr_tx_complete(dev, BUG_QUEUE)) != SUCCESS)
break;
}
/* NON-MAC frames only */
if(isb_subtype & TX_PENDING_PRIORITY_1)
{
if((err = smctr_tx_complete(dev,
NON_MAC_QUEUE)) != SUCCESS)
if((err = smctr_tx_complete(dev, NON_MAC_QUEUE)) != SUCCESS)
break;
}
......@@ -2189,40 +2178,31 @@ static void smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
*/
interrupt_unmask_bits |= 0x800;
tp->tx_queue_status[BUG_QUEUE]
= NOT_TRANSMITING;
if((err = smctr_tx_complete(dev,
BUG_QUEUE)) != SUCCESS)
tp->tx_queue_status[BUG_QUEUE] = NOT_TRANSMITING;
if((err = smctr_tx_complete(dev, BUG_QUEUE)) != SUCCESS)
break;
if((err = smctr_restart_tx_chain(dev,
BUG_QUEUE)) != SUCCESS)
if((err = smctr_restart_tx_chain(dev, BUG_QUEUE)) != SUCCESS)
break;
}
/* NON-MAC queue only */
if(isb_subtype & TX_PENDING_PRIORITY_1)
{
tp->tx_queue_status[NON_MAC_QUEUE]
= NOT_TRANSMITING;
if((err = smctr_tx_complete(dev,
NON_MAC_QUEUE)) != SUCCESS)
tp->tx_queue_status[NON_MAC_QUEUE] = NOT_TRANSMITING;
if((err = smctr_tx_complete(dev, NON_MAC_QUEUE)) != SUCCESS)
break;
if((err = smctr_restart_tx_chain(dev,
NON_MAC_QUEUE)) != SUCCESS)
if((err = smctr_restart_tx_chain(dev, NON_MAC_QUEUE)) != SUCCESS)
break;
}
/* MAC queue only */
if(isb_subtype & TX_PENDING_PRIORITY_0)
{
tp->tx_queue_status[MAC_QUEUE]
= NOT_TRANSMITING;
if((err = smctr_tx_complete(dev,
MAC_QUEUE)) != SUCCESS)
tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING;
if((err = smctr_tx_complete(dev, MAC_QUEUE)) != SUCCESS)
break;
err = smctr_restart_tx_chain(dev,
MAC_QUEUE);
err = smctr_restart_tx_chain(dev, MAC_QUEUE);
}
break;
......@@ -2328,7 +2308,7 @@ static void smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* complete posted
*/
interrupt_unmask_bits &= (~0x800);
printk("Jay please send bug\n");// smctr_send_bug(dev);
printk(KERN_CRIT "Jay please send bug\n");// smctr_send_bug(dev);
}
if(tp->ptr_rx_fifo_overruns)
......@@ -2346,7 +2326,7 @@ static void smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
err = SUCCESS;
if(tp->acb_head->cmd == ACB_CMD_HIC_NOP)
{
printk("i1\n");
printk(KERN_ERR "i1\n");
smctr_disable_16bit(dev);
/* XXXXXXXXXXXXXXXXX */
......@@ -2387,8 +2367,7 @@ static void smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if(err != SUCCESS)
{
tp->acb_pending
= 0;
tp->acb_pending = 0;
break;
}
}
......@@ -2397,18 +2376,14 @@ static void smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
if(tp->ptr_una)
{
tp->ptr_una[0]
= SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[0]);
tp->ptr_una[1]
= SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[1]);
tp->ptr_una[2]
= SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[2]);
tp->ptr_una[0] = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[0]);
tp->ptr_una[1] = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[1]);
tp->ptr_una[2] = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[2]);
}
}
if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate
& READY_TO_SEND_RQ_INIT) {
if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & READY_TO_SEND_RQ_INIT) {
err = smctr_send_rq_init(dev);
}
}
......@@ -2446,45 +2421,37 @@ static void smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
break;
case 1:
tp->join_state
= JS_LOBE_TEST_STATE;
tp->join_state = JS_LOBE_TEST_STATE;
break;
case 2:
tp->join_state
= JS_DETECT_MONITOR_PRESENT_STATE;
tp->join_state = JS_DETECT_MONITOR_PRESENT_STATE;
break;
case 3:
tp->join_state
= JS_AWAIT_NEW_MONITOR_STATE;
tp->join_state = JS_AWAIT_NEW_MONITOR_STATE;
break;
case 4:
tp->join_state
= JS_DUPLICATE_ADDRESS_TEST_STATE;
tp->join_state = JS_DUPLICATE_ADDRESS_TEST_STATE;
break;
case 5:
tp->join_state
= JS_NEIGHBOR_NOTIFICATION_STATE;
tp->join_state = JS_NEIGHBOR_NOTIFICATION_STATE;
break;
case 6:
tp->join_state
= JS_REQUEST_INITIALIZATION_STATE;
tp->join_state = JS_REQUEST_INITIALIZATION_STATE;
break;
case 7:
tp->join_state
= JS_JOIN_COMPLETE_STATE;
tp->join_state = JS_JOIN_COMPLETE_STATE;
tp->status = OPEN;
err = smctr_status_chg(dev);
break;
case 8:
tp->join_state
= JS_BYPASS_WAIT_STATE;
tp->join_state = JS_BYPASS_WAIT_STATE;
break;
}
break ;
......@@ -2514,11 +2481,11 @@ static void smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* but we still want to issue ack to ISB
*/
if(!(interrupt_ack_code & 0xff00))
smctr_issue_int_ack(dev, interrupt_ack_code,
interrupt_unmask_bits);
smctr_issue_int_ack(dev, interrupt_ack_code, interrupt_unmask_bits);
smctr_disable_16bit(dev);
smctr_enable_bic_int(dev);
spin_unlock(&tp->lock);
return;
}
......@@ -2533,16 +2500,14 @@ static int smctr_issue_enable_int_cmd(struct net_device *dev,
return (err);
tp->sclb_ptr->int_mask_control = interrupt_enable_mask;
tp->sclb_ptr->valid_command = SCLB_VALID
| SCLB_CMD_CLEAR_INTERRUPT_MASK;
tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_CLEAR_INTERRUPT_MASK;
smctr_set_ctrl_attention(dev);
return (0);
}
static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code,
__u16 ibits)
static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, __u16 ibits)
{
struct net_local *tp = (struct net_local *)dev->priv;
......@@ -2551,9 +2516,7 @@ static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code,
tp->sclb_ptr->int_mask_control = ibits;
tp->sclb_ptr->iack_code = iack_code << 1; /* use the offset from base */ tp->sclb_ptr->resume_control = 0;
tp->sclb_ptr->valid_command =
SCLB_VALID | SCLB_IACK_CODE_VALID
| SCLB_CMD_CLEAR_INTERRUPT_MASK;
tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_IACK_CODE_VALID | SCLB_CMD_CLEAR_INTERRUPT_MASK;
smctr_set_ctrl_attention(dev);
......@@ -2729,7 +2692,7 @@ static int smctr_issue_init_txrx_cmd(struct net_device *dev)
if((err = smctr_wait_cmd(dev)))
{
printk("%s: Hardware failure\n", dev->name);
printk(KERN_ERR "%s: Hardware failure\n", dev->name);
return (err);
}
......@@ -2864,7 +2827,7 @@ static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue)
struct net_local *tp = (struct net_local *)dev->priv;
if(smctr_debug > 10)
printk("%s: smctr_issue_resume_rx_fcb_cmd\n", dev->name);
printk(KERN_DEBUG "%s: smctr_issue_resume_rx_fcb_cmd\n", dev->name);
if(smctr_wait_while_cbusy(dev))
return (-1);
......@@ -2886,7 +2849,7 @@ static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue)
struct net_local *tp = (struct net_local *)dev->priv;
if(smctr_debug > 10)
printk("%s: smctr_issue_resume_tx_fcb_cmd\n", dev->name);
printk(KERN_DEBUG "%s: smctr_issue_resume_tx_fcb_cmd\n", dev->name);
if(smctr_wait_while_cbusy(dev))
return (-1);
......@@ -3035,7 +2998,7 @@ static int smctr_load_firmware(struct net_device *dev)
int err = 0;
if(smctr_debug > 10)
printk("%s: smctr_load_firmware\n", dev->name);
printk(KERN_DEBUG "%s: smctr_load_firmware\n", dev->name);
tp->ptr_ucode = smctr_code;
tp->num_of_tx_buffs = 4;
......@@ -3151,7 +3114,7 @@ static int smctr_lobe_media_test(struct net_device *dev)
unsigned short saved_rcv_mask;
if(smctr_debug > 10)
printk("%s: smctr_lobe_media_test\n", dev->name);
printk(KERN_DEBUG "%s: smctr_lobe_media_test\n", dev->name);
/* Clear receive mask for lobe test. */
saved_rcv_mask = tp->receive_mask;
......@@ -3225,7 +3188,7 @@ static int smctr_lobe_media_test_cmd(struct net_device *dev)
int err;
if(smctr_debug > 10)
printk("%s: smctr_lobe_media_test_cmd\n", dev->name);
printk(KERN_DEBUG "%s: smctr_lobe_media_test_cmd\n", dev->name);
/* Change to lobe media test state. */
if(tp->monitor_state != MS_BEACON_TEST_STATE)
......@@ -3233,7 +3196,7 @@ static int smctr_lobe_media_test_cmd(struct net_device *dev)
smctr_lobe_media_test_state(dev);
if(smctr_wait_cmd(dev))
{
printk("Lobe Failed test state\n");
printk(KERN_ERR "Lobe Failed test state\n");
return (LOBE_MEDIA_TEST_FAILED);
}
}
......@@ -3548,7 +3511,7 @@ static int smctr_open(struct net_device *dev)
int err;
if(smctr_debug > 10)
printk("%s: smctr_open\n", dev->name);
printk(KERN_DEBUG "%s: smctr_open\n", dev->name);
err = smctr_init_adapter(dev);
if(err < 0)
......@@ -3569,7 +3532,7 @@ static int smctr_open_tr(struct net_device *dev)
int err;
if(smctr_debug > 10)
printk("%s: smctr_open_tr\n", dev->name);
printk(KERN_DEBUG "%s: smctr_open_tr\n", dev->name);
/* Now we can actually open the adapter. */
if(tp->status == OPEN)
......@@ -3577,9 +3540,10 @@ static int smctr_open_tr(struct net_device *dev)
if(tp->status != INITIALIZED)
return (-1);
save_flags(flags);
cli();
/* FIXME: it would work a lot better if we masked the irq sources
on the card here, then we could skip the locking and poll nicely */
spin_lock_irqsave(&tp->lock, flags);
smctr_set_page(dev, (__u8 *)tp->ram_access);
if((err = smctr_issue_resume_rx_fcb_cmd(dev, (short)MAC_QUEUE)))
......@@ -3642,14 +3606,14 @@ static int smctr_open_tr(struct net_device *dev)
else
{
if(err == LOBE_MEDIA_TEST_FAILED)
printk("%s: Lobe Media Test Failure - Check cable?\n", dev->name);
printk(KERN_WARNING "%s: Lobe Media Test Failure - Check cable?\n", dev->name);
}
}
}
}
out:
restore_flags(flags);
spin_unlock_irqrestore(&tp->lock, flags);
return (err);
}
......@@ -3704,6 +3668,8 @@ static int __init smctr_probe1(struct net_device *dev, int ioaddr)
goto out;
}
memset(tp, 0, sizeof(struct net_local));
spin_lock_init(&tp->lock);
dev->priv = tp;
dev->base_addr = ioaddr;
......@@ -3727,7 +3693,7 @@ static int __init smctr_probe1(struct net_device *dev, int ioaddr)
err = smctr_load_firmware(dev);
if(err != UCODE_PRESENT && err != SUCCESS)
{
printk("%s: Firmware load failed (%d)\n", dev->name, err);
printk(KERN_ERR "%s: Firmware load failed (%d)\n", dev->name, err);
err = -EIO;
goto out_tp;
}
......@@ -3738,7 +3704,7 @@ static int __init smctr_probe1(struct net_device *dev, int ioaddr)
else
tp->media_type = MEDIA_UTP_16;
printk("%s: %s %s at Io %#4x, Irq %d, Rom %#4x, Ram %#4x.\n",
printk(KERN_INFO "%s: %s %s at Io %#4x, Irq %d, Rom %#4x, Ram %#4x.\n",
dev->name, smctr_name, smctr_model,
(unsigned int)dev->base_addr,
dev->irq, tp->rom_base, tp->ram_base);
......@@ -3777,8 +3743,7 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size,
{
/* Received MAC Frames Processed by RS. */
case INIT:
if((rcode = smctr_rcv_init(dev, rmf,
&correlator)) == HARDWARE_FAILED)
if((rcode = smctr_rcv_init(dev, rmf, &correlator)) == HARDWARE_FAILED)
{
return (rcode);
}
......@@ -3993,7 +3958,7 @@ static int smctr_ram_memory_test(struct net_device *dev)
__u8 err = 0;
if(smctr_debug > 10)
printk("%s: smctr_ram_memory_test\n", dev->name);
printk(KERN_DEBUG "%s: smctr_ram_memory_test\n", dev->name);
start_pattern = 0x0001;
pages_of_ram = tp->ram_size / tp->ram_usable;
......@@ -4401,7 +4366,7 @@ static int smctr_restart_tx_chain(struct net_device *dev, short queue)
int err = 0;
if(smctr_debug > 10)
printk("%s: smctr_restart_tx_chain\n", dev->name);
printk(KERN_DEBUG "%s: smctr_restart_tx_chain\n", dev->name);
if(tp->num_tx_fcbs_used[queue] != 0
&& tp->tx_queue_status[queue] == NOT_TRANSMITING)
......@@ -4418,7 +4383,7 @@ static int smctr_ring_status_chg(struct net_device *dev)
struct net_local *tp = (struct net_local *)dev->priv;
if(smctr_debug > 10)
printk("%s: smctr_ring_status_chg\n", dev->name);
printk(KERN_DEBUG "%s: smctr_ring_status_chg\n", dev->name);
/* Check for ring_status_flag: whenever MONITOR_STATE_BIT
* Bit is set, check value of monitor_state, only then we
......@@ -4502,7 +4467,7 @@ static int smctr_ring_status_chg(struct net_device *dev)
break;
case SIGNAL_LOSS:
printk(KERN_INFO "%s: Singal Loss\n", dev->name);
printk(KERN_INFO "%s: Signal Loss\n", dev->name);
tp->current_ring_status |= SIGNAL_LOSS;
break;
......@@ -4522,9 +4487,8 @@ static int smctr_rx_frame(struct net_device *dev)
__u8 *pbuff;
if(smctr_debug > 10)
printk("%s: smctr_rx_frame\n", dev->name);
printk(KERN_DEBUG "%s: smctr_rx_frame\n", dev->name);
cli();
queue = tp->receive_queue_number;
while((status = tp->rx_fcb_curr[queue]->frame_status) != SUCCESS)
......@@ -4554,7 +4518,6 @@ static int smctr_rx_frame(struct net_device *dev)
skb_put(skb, rx_size);
memcpy(skb->data, pbuff, rx_size);
sti();
/* Update Counters */
tp->MacStat.rx_packets++;
......@@ -4566,7 +4529,6 @@ static int smctr_rx_frame(struct net_device *dev)
netif_rx(skb);
dev->last_rx = jiffies;
} else {
sti();
}
}
else
......@@ -4593,7 +4555,7 @@ static int smctr_send_dat(struct net_device *dev)
FCBlock *fcb;
if(smctr_debug > 10)
printk("%s: smctr_send_dat\n", dev->name);
printk(KERN_DEBUG "%s: smctr_send_dat\n", dev->name);
if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE,
sizeof(MAC_HEADER))) == (FCBlock *)(-1L))
......@@ -4670,7 +4632,7 @@ static int smctr_send_packet(struct sk_buff *skb, struct net_device *dev)
struct net_local *tp = (struct net_local *)dev->priv;
if(smctr_debug > 10)
printk("%s: smctr_send_packet\n", dev->name);
printk(KERN_DEBUG "%s: smctr_send_packet\n", dev->name);
/*
* Block a transmit overlap
......@@ -4700,7 +4662,7 @@ static int smctr_send_lobe_media_test(struct net_device *dev)
int err;
if(smctr_debug > 15)
printk("%s: smctr_send_lobe_media_test\n", dev->name);
printk(KERN_DEBUG "%s: smctr_send_lobe_media_test\n", dev->name);
if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(struct trh_hdr)
+ S_WRAP_DATA + S_WRAP_DATA)) == (FCBlock *)(-1L))
......@@ -5241,7 +5203,7 @@ static unsigned short smctr_set_ctrl_attention(struct net_device *dev)
static void smctr_set_multicast_list(struct net_device *dev)
{
if(smctr_debug > 10)
printk("%s: smctr_set_multicast_list\n", dev->name);
printk(KERN_DEBUG "%s: smctr_set_multicast_list\n", dev->name);
return;
}
......@@ -5310,7 +5272,7 @@ static int smctr_set_rx_look_ahead(struct net_device *dev)
__u16 sword, rword;
if(smctr_debug > 10)
printk("%s: smctr_set_rx_look_ahead_flag\n", dev->name);
printk(KERN_DEBUG "%s: smctr_set_rx_look_ahead_flag\n", dev->name);
tp->adapter_flags &= ~(FORCED_16BIT_MODE);
tp->adapter_flags |= RX_VALID_LOOKAHEAD;
......@@ -5353,7 +5315,7 @@ static int smctr_setup_single_cmd(struct net_device *dev,
unsigned int err;
if(smctr_debug > 10)
printk("%s: smctr_setup_single_cmd\n", dev->name);
printk(KERN_DEBUG "%s: smctr_setup_single_cmd\n", dev->name);
if((err = smctr_wait_while_cbusy(dev)))
return (err);
......@@ -5403,7 +5365,7 @@ static int smctr_status_chg(struct net_device *dev)
struct net_local *tp = (struct net_local *)dev->priv;
if(smctr_debug > 10)
printk("%s: smctr_status_chg\n", dev->name);
printk(KERN_DEBUG "%s: smctr_status_chg\n", dev->name);
switch(tp->status)
{
......@@ -5440,7 +5402,7 @@ static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb,
int err = 0;
if(smctr_debug > 10)
printk("%s: smctr_trc_send_packet\n", dev->name);
printk(KERN_DEBUG "%s: smctr_trc_send_packet\n", dev->name);
fcb->info = FCB_CHAIN_END | FCB_ENABLE_TFS;
if(tp->num_tx_fcbs[queue] != 1)
......@@ -5462,7 +5424,7 @@ static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue)
int cstatus;
if(smctr_debug > 10)
printk("%s: smctr_tx_complete\n", dev->name);
printk(KERN_DEBUG "%s: smctr_tx_complete\n", dev->name);
while((status = tp->tx_fcb_end[queue]->frame_status) != SUCCESS)
{
......@@ -5518,7 +5480,7 @@ static unsigned short smctr_tx_move_frame(struct net_device *dev,
__u8 *frag, *page;
if(smctr_debug > 10)
printk("%s: smctr_tx_move_frame\n", dev->name);
printk(KERN_DEBUG "%s: smctr_tx_move_frame\n", dev->name);
ram_usable = ((unsigned int)tp->ram_usable) << 10;
frag = skb->data;
......@@ -5636,7 +5598,7 @@ static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb,
struct net_local *tp = (struct net_local *)dev->priv;
if(smctr_debug > 20)
printk("smctr_update_tx_chain\n");
printk(KERN_DEBUG "smctr_update_tx_chain\n");
if(tp->num_tx_fcbs_used[queue] <= 0)
return (HARDWARE_FAILED);
......@@ -5673,7 +5635,7 @@ static int smctr_wait_cmd(struct net_device *dev)
unsigned int loop_count = 0x20000;
if(smctr_debug > 10)
printk("%s: smctr_wait_cmd\n", dev->name);
printk(KERN_DEBUG "%s: smctr_wait_cmd\n", dev->name);
while(loop_count)
{
......@@ -5764,7 +5726,7 @@ int init_module(void)
dev_smctr[i] = NULL;
if(i == 0)
{
printk("%s: register_trdev() returned (<0).\n",
printk(KERN_ERR "%s: register_trdev() returned (<0).\n",
cardname);
return (-EIO);
}
......
......@@ -1050,6 +1050,8 @@ typedef struct net_local {
__u16 QueueSkb;
struct tr_statistics MacStat; /* MAC statistics structure */
spinlock_t lock;
} NET_LOCAL;
/************************************
......
......@@ -96,7 +96,7 @@
#include "fd_mcs.h"
#define DRIVER_VERSION "v0.2 by ZP Gu<zpg@castle.net>"
/* START OF USER DEFINABLE OPTIONS */
#define DEBUG 0 /* Enable debugging output */
......@@ -112,7 +112,7 @@
#define DEBUG_MESSAGES 1 /* Debug MESSAGE IN phase */
#define DEBUG_ABORT 1 /* Debug abort() routine */
#define DEBUG_RESET 1 /* Debug reset() routine */
#define DEBUG_RACE 1 /* Debug interrupt-driven race condition */
#define DEBUG_RACE 1 /* Debug interrupt-driven race condition */
#else
#define EVERY_ACCESS 0 /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */
#define ERRORS_ONLY 0
......@@ -136,86 +136,86 @@
#endif
enum chip_type {
unknown = 0x00,
tmc1800 = 0x01,
tmc18c50 = 0x02,
tmc18c30 = 0x03,
unknown = 0x00,
tmc1800 = 0x01,
tmc18c50 = 0x02,
tmc18c30 = 0x03,
};
enum {
in_arbitration = 0x02,
in_selection = 0x04,
in_other = 0x08,
disconnect = 0x10,
aborted = 0x20,
sent_ident = 0x40,
in_arbitration = 0x02,
in_selection = 0x04,
in_other = 0x08,
disconnect = 0x10,
aborted = 0x20,
sent_ident = 0x40,
};
enum in_port_type {
Read_SCSI_Data = 0,
SCSI_Status = 1,
TMC_Status = 2,
FIFO_Status = 3, /* tmc18c50/tmc18c30 only */
Interrupt_Cond = 4, /* tmc18c50/tmc18c30 only */
LSB_ID_Code = 5,
MSB_ID_Code = 6,
Read_Loopback = 7,
SCSI_Data_NoACK = 8,
Interrupt_Status = 9,
Configuration1 = 10,
Configuration2 = 11, /* tmc18c50/tmc18c30 only */
Read_FIFO = 12,
FIFO_Data_Count = 14
Read_SCSI_Data = 0,
SCSI_Status = 1,
TMC_Status = 2,
FIFO_Status = 3, /* tmc18c50/tmc18c30 only */
Interrupt_Cond = 4, /* tmc18c50/tmc18c30 only */
LSB_ID_Code = 5,
MSB_ID_Code = 6,
Read_Loopback = 7,
SCSI_Data_NoACK = 8,
Interrupt_Status = 9,
Configuration1 = 10,
Configuration2 = 11, /* tmc18c50/tmc18c30 only */
Read_FIFO = 12,
FIFO_Data_Count = 14
};
enum out_port_type {
Write_SCSI_Data = 0,
SCSI_Cntl = 1,
Interrupt_Cntl = 2,
SCSI_Mode_Cntl = 3,
TMC_Cntl = 4,
Memory_Cntl = 5, /* tmc18c50/tmc18c30 only */
Write_Loopback = 7,
IO_Control = 11, /* tmc18c30 only */
Write_FIFO = 12
Write_SCSI_Data = 0,
SCSI_Cntl = 1,
Interrupt_Cntl = 2,
SCSI_Mode_Cntl = 3,
TMC_Cntl = 4,
Memory_Cntl = 5, /* tmc18c50/tmc18c30 only */
Write_Loopback = 7,
IO_Control = 11, /* tmc18c30 only */
Write_FIFO = 12
};
struct fd_hostdata {
unsigned long _bios_base;
int _bios_major;
int _bios_minor;
volatile int _in_command;
Scsi_Cmnd *_current_SC;
enum chip_type _chip;
int _adapter_mask;
int _fifo_count; /* Number of 512 byte blocks before INTR */
char _adapter_name[64];
unsigned long _bios_base;
int _bios_major;
int _bios_minor;
volatile int _in_command;
Scsi_Cmnd *_current_SC;
enum chip_type _chip;
int _adapter_mask;
int _fifo_count; /* Number of 512 byte blocks before INTR */
char _adapter_name[64];
#if DEBUG_RACE
volatile int _in_interrupt_flag;
volatile int _in_interrupt_flag;
#endif
int _SCSI_Mode_Cntl_port;
int _FIFO_Data_Count_port;
int _Interrupt_Cntl_port;
int _Interrupt_Status_port;
int _Interrupt_Cond_port;
int _Read_FIFO_port;
int _Read_SCSI_Data_port;
int _SCSI_Cntl_port;
int _SCSI_Data_NoACK_port;
int _SCSI_Status_port;
int _TMC_Cntl_port;
int _TMC_Status_port;
int _Write_FIFO_port;
int _Write_SCSI_Data_port;
int _FIFO_Size; /* = 0x2000; 8k FIFO for
int _SCSI_Mode_Cntl_port;
int _FIFO_Data_Count_port;
int _Interrupt_Cntl_port;
int _Interrupt_Status_port;
int _Interrupt_Cond_port;
int _Read_FIFO_port;
int _Read_SCSI_Data_port;
int _SCSI_Cntl_port;
int _SCSI_Data_NoACK_port;
int _SCSI_Status_port;
int _TMC_Cntl_port;
int _TMC_Status_port;
int _Write_FIFO_port;
int _Write_SCSI_Data_port;
int _FIFO_Size; /* = 0x2000; 8k FIFO for
pre-tmc18c30 chips */
/* simple stats */
int _Bytes_Read;
int _Bytes_Written;
int _INTR_Processed;
/* simple stats */
int _Bytes_Read;
int _Bytes_Written;
int _INTR_Processed;
};
#define FD_MAX_HOSTS 3 /* enough? */
......@@ -232,7 +232,7 @@ struct fd_hostdata {
#define adapter_name (HOSTDATA(shpnt)->_adapter_name)
#if DEBUG_RACE
#define in_interrupt_flag (HOSTDATA(shpnt)->_in_interrupt_flag)
#endif
#endif
#define SCSI_Mode_Cntl_port (HOSTDATA(shpnt)->_SCSI_Mode_Cntl_port)
#define FIFO_Data_Count_port (HOSTDATA(shpnt)->_FIFO_Data_Count_port)
#define Interrupt_Cntl_port (HOSTDATA(shpnt)->_Interrupt_Cntl_port)
......@@ -253,337 +253,324 @@ struct fd_hostdata {
#define INTR_Processed (HOSTDATA(shpnt)->_INTR_Processed)
struct fd_mcs_adapters_struct {
char* name;
int id;
enum chip_type fd_chip;
int fifo_size;
int fifo_count;
char *name;
int id;
enum chip_type fd_chip;
int fifo_size;
int fifo_count;
};
#define REPLY_ID 0x5137
static struct fd_mcs_adapters_struct fd_mcs_adapters[] = {
{ "Future Domain SCSI Adapter MCS-700(18C50)",
0x60e9,
tmc18c50,
0x2000,
4 },
{ "Future Domain SCSI Adapter MCS-600/700(TMC-1800)",
0x6127,
tmc1800,
0x2000,
4 },
{ "Reply Sound Blaster/SCSI Adapter",
REPLY_ID,
tmc18c30,
0x800,
2 },
{"Future Domain SCSI Adapter MCS-700(18C50)",
0x60e9,
tmc18c50,
0x2000,
4},
{"Future Domain SCSI Adapter MCS-600/700(TMC-1800)",
0x6127,
tmc1800,
0x2000,
4},
{"Reply Sound Blaster/SCSI Adapter",
REPLY_ID,
tmc18c30,
0x800,
2},
};
#define FD_BRDS sizeof(fd_mcs_adapters)/sizeof(struct fd_mcs_adapters_struct)
static void fd_mcs_intr( int irq, void *dev_id, struct pt_regs * regs );
static void fd_mcs_intr(int irq, void *dev_id, struct pt_regs *regs);
static unsigned long addresses[] = {0xc8000, 0xca000, 0xce000, 0xde000};
static unsigned long addresses[] = { 0xc8000, 0xca000, 0xce000, 0xde000 };
static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
static unsigned short ints[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
/* host information */
static int found = 0;
static struct Scsi_Host *hosts[FD_MAX_HOSTS+1] = { NULL };
static struct Scsi_Host *hosts[FD_MAX_HOSTS + 1] = { NULL };
static int user_fifo_count = 0;
static int user_fifo_size = 0;
void fd_mcs_setup( char *str, int *ints )
static void fd_mcs_setup(char *str, int *ints)
{
static int done_setup = 0;
static int done_setup = 0;
if (done_setup++ || ints[0] < 1 || ints[0] > 2 ||
ints[1] < 1 || ints[1] > 16) {
printk( "fd_mcs: usage: fd_mcs=FIFO_COUNT, FIFO_SIZE\n" );
}
if (done_setup++ || ints[0] < 1 || ints[0] > 2 || ints[1] < 1 || ints[1] > 16) {
printk("fd_mcs: usage: fd_mcs=FIFO_COUNT, FIFO_SIZE\n");
}
user_fifo_count = ints[0] >= 1 ? ints[1] : 0;
user_fifo_size = ints[0] >= 2 ? ints[2] : 0;
user_fifo_count = ints[0] >= 1 ? ints[1] : 0;
user_fifo_size = ints[0] >= 2 ? ints[2] : 0;
}
static void print_banner( struct Scsi_Host *shpnt )
__setup("fd_mcs=", fd_mcs_setup);
static void print_banner(struct Scsi_Host *shpnt)
{
printk( "scsi%d <fd_mcs>: ", shpnt->host_no);
if (bios_base) {
printk( "BIOS at 0x%lX", bios_base);
} else {
printk( "No BIOS");
}
printk( ", HostID %d, %s Chip, IRQ %d, IO 0x%lX\n",
shpnt->this_id,
chip == tmc18c50 ? "TMC-18C50"
: (chip == tmc18c30 ? "TMC-18C30" :
(chip == tmc1800 ? "TMC-1800" : "Unknown")),
shpnt->irq,
shpnt->io_port );
}
printk("scsi%d <fd_mcs>: ", shpnt->host_no);
if (bios_base) {
printk("BIOS at 0x%lX", bios_base);
} else {
printk("No BIOS");
}
static void do_pause( unsigned amount ) /* Pause for amount*10 milliseconds */
{
do {
udelay(10*1000);
} while (--amount);
printk(", HostID %d, %s Chip, IRQ %d, IO 0x%lX\n", shpnt->this_id, chip == tmc18c50 ? "TMC-18C50" : (chip == tmc18c30 ? "TMC-18C30" : (chip == tmc1800 ? "TMC-1800" : "Unknown")), shpnt->irq, shpnt->io_port);
}
inline static void fd_mcs_make_bus_idle( struct Scsi_Host *shpnt )
{
outb( 0, SCSI_Cntl_port );
outb( 0, SCSI_Mode_Cntl_port );
if (chip == tmc18c50 || chip == tmc18c30)
outb( 0x21 | PARITY_MASK, TMC_Cntl_port ); /* Clear forced intr. */
else
outb( 0x01 | PARITY_MASK, TMC_Cntl_port );
static void do_pause(unsigned amount)
{ /* Pause for amount*10 milliseconds */
do {
mdelay(10);
} while (--amount);
}
int fd_mcs_detect( Scsi_Host_Template *tpnt )
static void fd_mcs_make_bus_idle(struct Scsi_Host *shpnt)
{
int loop;
struct Scsi_Host *shpnt;
/* get id, port, bios, irq */
int slot;
u_char pos2, pos3, pos4;
int id, port, irq;
unsigned long bios;
/* if not MCA machine, return */
if (!MCA_bus)
return 0;
/* changeable? */
id = 7;
for( loop = 0; loop < FD_BRDS; loop++ ) {
slot = 0;
while ( MCA_NOTFOUND !=
(slot = mca_find_adapter(fd_mcs_adapters[loop].id,
slot)) ) {
/* if we get this far, an adapter has been detected and is
enabled */
printk("scsi <fd_mcs>: %s at slot %d\n",
fd_mcs_adapters[loop].name, slot + 1 );
pos2 = mca_read_stored_pos( slot, 2 );
pos3 = mca_read_stored_pos( slot, 3 );
pos4 = mca_read_stored_pos( slot, 4);
/* ready for next probe */
slot++;
if (fd_mcs_adapters[loop].id == REPLY_ID) { /* reply card */
static int reply_irq[] = {10, 11, 14, 15};
bios = 0; /* no bios */
if (pos2 & 0x2)
port = ports[pos4 & 0x3];
outb(0, SCSI_Cntl_port);
outb(0, SCSI_Mode_Cntl_port);
if (chip == tmc18c50 || chip == tmc18c30)
outb(0x21 | PARITY_MASK, TMC_Cntl_port); /* Clear forced intr. */
else
continue;
/* can't really disable it, same as irq=10 */
irq = reply_irq[((pos4 >> 2) & 0x1) + 2*((pos4 >> 4) & 0x1)];
} else {
bios = addresses[pos2 >> 6];
port = ports[(pos2 >> 4) & 0x03];
irq = ints[(pos2 >> 1) & 0x07];
}
if (irq) {
/* claim the slot */
mca_set_adapter_name( slot-1, fd_mcs_adapters[loop].name );
/* check irq/region */
if (check_region(port, 0x10) ||
request_irq(irq, fd_mcs_intr,
SA_SHIRQ, "fd_mcs", hosts)) {
printk( "fd_mcs: check_region() || request_irq() failed, Skip it\n");
continue;
}
/* register */
if (!(shpnt = scsi_register(tpnt, sizeof(struct fd_hostdata)))) {
printk( "fd_mcs: scsi_register() failed\n");
continue;
}
/* request I/O region */
request_region( port, 0x10, "fd_mcs" );
/* save name */
strcpy(adapter_name, fd_mcs_adapters[loop].name);
outb(0x01 | PARITY_MASK, TMC_Cntl_port);
}
/* chip/fifo */
chip = fd_mcs_adapters[loop].fd_chip;
/* use boot time value if available */
FIFO_COUNT =
user_fifo_count?user_fifo_count:fd_mcs_adapters[loop].fifo_count;
FIFO_Size =
user_fifo_size?user_fifo_size:fd_mcs_adapters[loop].fifo_size;
static int fd_mcs_detect(Scsi_Host_Template * tpnt)
{
int loop;
struct Scsi_Host *shpnt;
/* get id, port, bios, irq */
int slot;
u_char pos2, pos3, pos4;
int id, port, irq;
unsigned long bios;
/* if not MCA machine, return */
if (!MCA_bus)
return 0;
/* changeable? */
id = 7;
for (loop = 0; loop < FD_BRDS; loop++) {
slot = 0;
while (MCA_NOTFOUND != (slot = mca_find_adapter(fd_mcs_adapters[loop].id, slot))) {
/* if we get this far, an adapter has been detected and is
enabled */
printk(KERN_INFO "scsi <fd_mcs>: %s at slot %d\n", fd_mcs_adapters[loop].name, slot + 1);
pos2 = mca_read_stored_pos(slot, 2);
pos3 = mca_read_stored_pos(slot, 3);
pos4 = mca_read_stored_pos(slot, 4);
/* ready for next probe */
slot++;
if (fd_mcs_adapters[loop].id == REPLY_ID) { /* reply card */
static int reply_irq[] = { 10, 11, 14, 15 };
bios = 0; /* no bios */
if (pos2 & 0x2)
port = ports[pos4 & 0x3];
else
continue;
/* can't really disable it, same as irq=10 */
irq = reply_irq[((pos4 >> 2) & 0x1) + 2 * ((pos4 >> 4) & 0x1)];
} else {
bios = addresses[pos2 >> 6];
port = ports[(pos2 >> 4) & 0x03];
irq = ints[(pos2 >> 1) & 0x07];
}
if (irq) {
/* claim the slot */
mca_set_adapter_name(slot - 1, fd_mcs_adapters[loop].name);
/* check irq/region */
if (request_irq(irq, fd_mcs_intr, SA_SHIRQ, "fd_mcs", hosts)) {
printk(KERN_ERR "fd_mcs: interrupt is not available, skipping...\n");
continue;
}
/* request I/O region */
if (request_region(port, 0x10, "fd_mcs")) {
printk(KERN_ERR "fd_mcs: I/O region is already in use, skipping...\n");
continue;
}
/* register */
if (!(shpnt = scsi_register(tpnt, sizeof(struct fd_hostdata)))) {
printk(KERN_ERR "fd_mcs: scsi_register() failed\n");
release_region(port, 0x10);
free_irq(irq, hosts);
continue;
}
/* save name */
strcpy(adapter_name, fd_mcs_adapters[loop].name);
/* chip/fifo */
chip = fd_mcs_adapters[loop].fd_chip;
/* use boot time value if available */
FIFO_COUNT = user_fifo_count ? user_fifo_count : fd_mcs_adapters[loop].fifo_count;
FIFO_Size = user_fifo_size ? user_fifo_size : fd_mcs_adapters[loop].fifo_size;
#ifdef NOT_USED
/* *************************************************** */
/* Try to toggle 32-bit mode. This only
works on an 18c30 chip. (User reports
say this works, so we should switch to
it in the near future.) */
outb( 0x80, port + IO_Control );
if ((inb( port + Configuration2 ) & 0x80) == 0x80) {
outb( 0x00, port + IO_Control );
if ((inb( port + Configuration2 ) & 0x80) == 0x00) {
chip = tmc18c30;
FIFO_Size = 0x800; /* 2k FIFO */
printk("FIRST: chip=%s, fifo_size=0x%x\n",
(chip == tmc18c30)?"tmc18c30":"tmc18c50", FIFO_Size);
}
}
/* That should have worked, but appears to
have problems. Let's assume it is an
18c30 if the RAM is disabled. */
if (inb( port + Configuration2 ) & 0x02) {
chip = tmc18c30;
FIFO_Size = 0x800; /* 2k FIFO */
printk("SECOND: chip=%s, fifo_size=0x%x\n",
(chip == tmc18c30)?"tmc18c30":"tmc18c50", FIFO_Size);
}
/* *************************************************** */
/* *************************************************** */
/* Try to toggle 32-bit mode. This only
works on an 18c30 chip. (User reports
say this works, so we should switch to
it in the near future.) */
outb(0x80, port + IO_Control);
if ((inb(port + Configuration2) & 0x80) == 0x80) {
outb(0x00, port + IO_Control);
if ((inb(port + Configuration2) & 0x80) == 0x00) {
chip = tmc18c30;
FIFO_Size = 0x800; /* 2k FIFO */
printk("FIRST: chip=%s, fifo_size=0x%x\n", (chip == tmc18c30) ? "tmc18c30" : "tmc18c50", FIFO_Size);
}
}
/* That should have worked, but appears to
have problems. Let's assume it is an
18c30 if the RAM is disabled. */
if (inb(port + Configuration2) & 0x02) {
chip = tmc18c30;
FIFO_Size = 0x800; /* 2k FIFO */
printk("SECOND: chip=%s, fifo_size=0x%x\n", (chip == tmc18c30) ? "tmc18c30" : "tmc18c50", FIFO_Size);
}
/* *************************************************** */
#endif
/* IBM/ANSI scsi scan ordering */
/* Stick this back in when the scsi.c changes are there */
shpnt->reverse_ordering = 1;
/* saving info */
hosts[found++] = shpnt;
shpnt->this_id = id;
shpnt->irq = irq;
shpnt->io_port = port;
shpnt->n_io_port = 0x10;
/* save */
bios_base = bios;
adapter_mask = (1 << id);
/* save more */
SCSI_Mode_Cntl_port = port + SCSI_Mode_Cntl;
FIFO_Data_Count_port = port + FIFO_Data_Count;
Interrupt_Cntl_port = port + Interrupt_Cntl;
Interrupt_Status_port = port + Interrupt_Status;
Interrupt_Cond_port = port + Interrupt_Cond;
Read_FIFO_port = port + Read_FIFO;
Read_SCSI_Data_port = port + Read_SCSI_Data;
SCSI_Cntl_port = port + SCSI_Cntl;
SCSI_Data_NoACK_port = port + SCSI_Data_NoACK;
SCSI_Status_port = port + SCSI_Status;
TMC_Cntl_port = port + TMC_Cntl;
TMC_Status_port = port + TMC_Status;
Write_FIFO_port = port + Write_FIFO;
Write_SCSI_Data_port = port + Write_SCSI_Data;
Bytes_Read = 0;
Bytes_Written = 0;
INTR_Processed = 0;
/* say something */
print_banner( shpnt );
/* reset */
outb( 1, SCSI_Cntl_port );
do_pause( 2 );
outb( 0, SCSI_Cntl_port );
do_pause( 115 );
outb( 0, SCSI_Mode_Cntl_port );
outb( PARITY_MASK, TMC_Cntl_port );
/* done reset */
/* IBM/ANSI scsi scan ordering */
/* Stick this back in when the scsi.c changes are there */
shpnt->reverse_ordering = 1;
/* saving info */
hosts[found++] = shpnt;
shpnt->this_id = id;
shpnt->irq = irq;
shpnt->io_port = port;
shpnt->n_io_port = 0x10;
/* save */
bios_base = bios;
adapter_mask = (1 << id);
/* save more */
SCSI_Mode_Cntl_port = port + SCSI_Mode_Cntl;
FIFO_Data_Count_port = port + FIFO_Data_Count;
Interrupt_Cntl_port = port + Interrupt_Cntl;
Interrupt_Status_port = port + Interrupt_Status;
Interrupt_Cond_port = port + Interrupt_Cond;
Read_FIFO_port = port + Read_FIFO;
Read_SCSI_Data_port = port + Read_SCSI_Data;
SCSI_Cntl_port = port + SCSI_Cntl;
SCSI_Data_NoACK_port = port + SCSI_Data_NoACK;
SCSI_Status_port = port + SCSI_Status;
TMC_Cntl_port = port + TMC_Cntl;
TMC_Status_port = port + TMC_Status;
Write_FIFO_port = port + Write_FIFO;
Write_SCSI_Data_port = port + Write_SCSI_Data;
Bytes_Read = 0;
Bytes_Written = 0;
INTR_Processed = 0;
/* say something */
print_banner(shpnt);
/* reset */
outb(1, SCSI_Cntl_port);
do_pause(2);
outb(0, SCSI_Cntl_port);
do_pause(115);
outb(0, SCSI_Mode_Cntl_port);
outb(PARITY_MASK, TMC_Cntl_port);
/* done reset */
#if DO_DETECT
/* scan devices attached */
{
const int buflen = 255;
int i, j, retcode;
Scsi_Cmnd SCinit;
unsigned char do_inquiry[] = { INQUIRY, 0, 0, 0, buflen, 0 };
unsigned char do_request_sense[] = { REQUEST_SENSE,
0, 0, 0, buflen, 0 };
unsigned char do_read_capacity[] = { READ_CAPACITY,
0, 0, 0, 0, 0, 0, 0, 0, 0 };
unsigned char buf[buflen];
SCinit.request_buffer = SCinit.buffer = buf;
SCinit.request_bufflen = SCinit.bufflen = sizeof(buf)-1;
SCinit.use_sg = 0;
SCinit.lun = 0;
SCinit.host = shpnt;
printk( "fd_mcs: detection routine scanning for devices:\n" );
for (i = 0; i < 8; i++) {
if (i == shpnt->this_id) /* Skip host adapter */
continue;
SCinit.target = i;
memcpy(SCinit.cmnd, do_request_sense,
sizeof(do_request_sense));
retcode = fd_mcs_command(&SCinit);
if (!retcode) {
memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));
retcode = fd_mcs_command(&SCinit);
if (!retcode) {
printk( " SCSI ID %d: ", i );
for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++)
printk( "%c", buf[j] >= 20 ? buf[j] : ' ' );
memcpy(SCinit.cmnd, do_read_capacity,
sizeof(do_read_capacity));
retcode = fd_mcs_command(&SCinit);
if (!retcode) {
unsigned long blocks, size, capacity;
blocks = (buf[0] << 24) | (buf[1] << 16)
| (buf[2] << 8) | buf[3];
size = (buf[4] << 24) | (buf[5] << 16) |
(buf[6] << 8) | buf[7];
capacity = +( +(blocks / 1024L) * +(size * 10L)) / 1024L;
printk( "%lu MB (%lu byte blocks)\n",
((capacity + 5L) / 10L), size );
}
}
}
}
}
/* scan devices attached */
{
const int buflen = 255;
int i, j, retcode;
Scsi_Cmnd SCinit;
unsigned char do_inquiry[] = { INQUIRY, 0, 0, 0, buflen, 0 };
unsigned char do_request_sense[] = { REQUEST_SENSE,
0, 0, 0, buflen, 0
};
unsigned char do_read_capacity[] = { READ_CAPACITY,
0, 0, 0, 0, 0, 0, 0, 0, 0
};
unsigned char buf[buflen];
SCinit.request_buffer = SCinit.buffer = buf;
SCinit.request_bufflen = SCinit.bufflen = sizeof(buf) - 1;
SCinit.use_sg = 0;
SCinit.lun = 0;
SCinit.host = shpnt;
printk("fd_mcs: detection routine scanning for devices:\n");
for (i = 0; i < 8; i++) {
if (i == shpnt->this_id) /* Skip host adapter */
continue;
SCinit.target = i;
memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
retcode = fd_mcs_command(&SCinit);
if (!retcode) {
memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));
retcode = fd_mcs_command(&SCinit);
if (!retcode) {
printk(" SCSI ID %d: ", i);
for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++)
printk("%c", buf[j] >= 20 ? buf[j] : ' ');
memcpy(SCinit.cmnd, do_read_capacity, sizeof(do_read_capacity));
retcode = fd_mcs_command(&SCinit);
if (!retcode) {
unsigned long blocks, size, capacity;
blocks = (buf[0] << 24) | (buf[1] << 16)
| (buf[2] << 8) | buf[3];
size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
capacity = +(+(blocks / 1024L) * +(size * 10L)) / 1024L;
printk("%lu MB (%lu byte blocks)\n", ((capacity + 5L) / 10L), size);
}
}
}
}
}
#endif
}
}
}
}
if (found == FD_MAX_HOSTS) {
printk( "fd_mcs: detecting reached max=%d host adapters.\n",
FD_MAX_HOSTS);
break;
}
}
if (found == FD_MAX_HOSTS) {
printk("fd_mcs: detecting reached max=%d host adapters.\n", FD_MAX_HOSTS);
break;
}
}
return found;
return found;
}
const char *fd_mcs_info(struct Scsi_Host *shpnt)
static const char *fd_mcs_info(struct Scsi_Host *shpnt)
{
return adapter_name;
return adapter_name;
}
static int TOTAL_INTR = 0;
......@@ -598,869 +585,864 @@ static int TOTAL_INTR = 0;
* length: If inout==FALSE max number of bytes to be written into the buffer
* else number of bytes in the buffer
*/
int fd_mcs_proc_info( char *buffer, char **start, off_t offset,
int length, int hostno, int inout )
static int fd_mcs_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout)
{
struct Scsi_Host *shpnt;
int len = 0;
int i;
struct Scsi_Host *shpnt;
int len = 0;
int i;
if (inout)
return(-ENOSYS);
if (inout)
return (-ENOSYS);
*start = buffer + offset;
*start = buffer + offset;
for (i = 0; hosts[i] && hosts[i]->host_no != hostno; i++);
shpnt = hosts[i];
for (i = 0; hosts[i] && hosts[i]->host_no != hostno; i++);
shpnt = hosts[i];
if (!shpnt) {
return(-ENOENT);
} else {
len += sprintf(buffer+len, "Future Domain MCS-600/700 Driver %s\n",
DRIVER_VERSION);
if (!shpnt) {
return (-ENOENT);
} else {
len += sprintf(buffer + len, "Future Domain MCS-600/700 Driver %s\n", DRIVER_VERSION);
len += sprintf(buffer+len, "HOST #%d: %s\n",
hostno, adapter_name);
len += sprintf(buffer + len, "HOST #%d: %s\n", hostno, adapter_name);
len += sprintf(buffer+len, "FIFO Size=0x%x, FIFO Count=%d\n",
FIFO_Size, FIFO_COUNT);
len += sprintf(buffer + len, "FIFO Size=0x%x, FIFO Count=%d\n", FIFO_Size, FIFO_COUNT);
len += sprintf(buffer+len, "DriverCalls=%d, Interrupts=%d, BytesRead=%d, BytesWrite=%d\n\n",
TOTAL_INTR, INTR_Processed, Bytes_Read, Bytes_Written);
}
len += sprintf(buffer + len, "DriverCalls=%d, Interrupts=%d, BytesRead=%d, BytesWrite=%d\n\n", TOTAL_INTR, INTR_Processed, Bytes_Read, Bytes_Written);
}
if ((len -= offset) <= 0)
return 0;
if (len > length)
len = length;
return len;
if ((len -= offset) <= 0)
return 0;
if (len > length)
len = length;
return len;
}
static int fd_mcs_select(struct Scsi_Host *shpnt, int target )
static int fd_mcs_select(struct Scsi_Host *shpnt, int target)
{
int status;
unsigned long timeout;
int status;
unsigned long timeout;
outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */
outb( adapter_mask | (1 << target), SCSI_Data_NoACK_port );
outb(0x82, SCSI_Cntl_port); /* Bus Enable + Select */
outb(adapter_mask | (1 << target), SCSI_Data_NoACK_port);
/* Stop arbitration and enable parity */
outb( PARITY_MASK, TMC_Cntl_port );
/* Stop arbitration and enable parity */
outb(PARITY_MASK, TMC_Cntl_port);
timeout = 350; /* 350mS -- because of timeouts
timeout = 350; /* 350mS -- because of timeouts
(was 250mS) */
do {
status = inb( SCSI_Status_port ); /* Read adapter status */
if (status & 1) { /* Busy asserted */
/* Enable SCSI Bus (on error, should make bus idle with 0) */
outb( 0x80, SCSI_Cntl_port );
return 0;
}
udelay(1000); /* wait one msec */
} while (--timeout);
/* Make bus idle */
fd_mcs_make_bus_idle(shpnt);
do {
status = inb(SCSI_Status_port); /* Read adapter status */
if (status & 1) { /* Busy asserted */
/* Enable SCSI Bus (on error, should make bus idle with 0) */
outb(0x80, SCSI_Cntl_port);
return 0;
}
udelay(1000); /* wait one msec */
} while (--timeout);
/* Make bus idle */
fd_mcs_make_bus_idle(shpnt);
#if EVERY_ACCESS
if (!target) printk( "Selection failed\n" );
if (!target)
printk("Selection failed\n");
#endif
#if ERRORS_ONLY
if (!target) {
static int flag = 0;
if (!flag) /* Skip first failure for all chips. */
++flag;
else
printk( "fd_mcs: Selection failed\n" );
}
if (!target) {
static int flag = 0;
if (!flag) /* Skip first failure for all chips. */
++flag;
else
printk("fd_mcs: Selection failed\n");
}
#endif
return 1;
return 1;
}
static void my_done( struct Scsi_Host *shpnt, int error )
static void my_done(struct Scsi_Host *shpnt, int error)
{
if (in_command) {
in_command = 0;
outb( 0x00, Interrupt_Cntl_port );
fd_mcs_make_bus_idle(shpnt);
current_SC->result = error;
current_SC->scsi_done( current_SC );
} else {
panic( "fd_mcs: my_done() called outside of command\n" );
}
if (in_command) {
in_command = 0;
outb(0x00, Interrupt_Cntl_port);
fd_mcs_make_bus_idle(shpnt);
current_SC->result = error;
current_SC->scsi_done(current_SC);
} else {
panic("fd_mcs: my_done() called outside of command\n");
}
#if DEBUG_RACE
in_interrupt_flag = 0;
in_interrupt_flag = 0;
#endif
}
/* only my_done needs to be protected */
static void fd_mcs_intr( int irq, void *dev_id, struct pt_regs * regs )
static void fd_mcs_intr(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned long flags;
int status;
int done = 0;
unsigned data_count, tmp_count;
unsigned long flags;
int status;
int done = 0;
unsigned data_count, tmp_count;
int i = 0;
struct Scsi_Host *shpnt;
int i = 0;
struct Scsi_Host *shpnt;
TOTAL_INTR++;
TOTAL_INTR++;
/* search for one adapter-response on shared interrupt */
while ((shpnt = hosts[i++])) {
if ((inb(TMC_Status_port)) & 1)
break;
}
/* return if some other device on this IRQ caused the interrupt */
if (!shpnt) {
return;
}
/* search for one adapter-response on shared interrupt */
while ((shpnt = hosts[i++])) {
if ((inb(TMC_Status_port)) & 1)
break;
}
/* return if some other device on this IRQ caused the interrupt */
if (!shpnt) {
return;
}
INTR_Processed++;
INTR_Processed++;
outb( 0x00, Interrupt_Cntl_port );
outb(0x00, Interrupt_Cntl_port);
/* Abort calls my_done, so we do nothing here. */
if (current_SC->SCp.phase & aborted) {
/* Abort calls my_done, so we do nothing here. */
if (current_SC->SCp.phase & aborted) {
#if DEBUG_ABORT
printk( "Interrupt after abort, ignoring\n" );
printk("Interrupt after abort, ignoring\n");
#endif
/* return; */
}
/* return; */
}
#if DEBUG_RACE
++in_interrupt_flag;
++in_interrupt_flag;
#endif
if (current_SC->SCp.phase & in_arbitration) {
status = inb( TMC_Status_port ); /* Read adapter status */
if (!(status & 0x02)) {
if (current_SC->SCp.phase & in_arbitration) {
status = inb(TMC_Status_port); /* Read adapter status */
if (!(status & 0x02)) {
#if EVERY_ACCESS
printk( " AFAIL " );
printk(" AFAIL ");
#endif
spin_lock_irqsave(shpnt->host_lock, flags);
my_done( shpnt, DID_BUS_BUSY << 16 );
spin_unlock_irqrestore(shpnt->host_lock, flags);
return;
}
current_SC->SCp.phase = in_selection;
outb( 0x40 | FIFO_COUNT, Interrupt_Cntl_port );
outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */
outb( adapter_mask | (1 << current_SC->target), SCSI_Data_NoACK_port );
/* Stop arbitration and enable parity */
outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
spin_lock_irqsave(shpnt->host_lock, flags);
my_done(shpnt, DID_BUS_BUSY << 16);
spin_unlock_irqrestore(shpnt->host_lock, flags);
return;
}
current_SC->SCp.phase = in_selection;
outb(0x40 | FIFO_COUNT, Interrupt_Cntl_port);
outb(0x82, SCSI_Cntl_port); /* Bus Enable + Select */
outb(adapter_mask | (1 << current_SC->target), SCSI_Data_NoACK_port);
/* Stop arbitration and enable parity */
outb(0x10 | PARITY_MASK, TMC_Cntl_port);
#if DEBUG_RACE
in_interrupt_flag = 0;
in_interrupt_flag = 0;
#endif
return;
} else if (current_SC->SCp.phase & in_selection) {
status = inb( SCSI_Status_port );
if (!(status & 0x01)) {
/* Try again, for slow devices */
if (fd_mcs_select(shpnt, current_SC->target )) {
return;
} else if (current_SC->SCp.phase & in_selection) {
status = inb(SCSI_Status_port);
if (!(status & 0x01)) {
/* Try again, for slow devices */
if (fd_mcs_select(shpnt, current_SC->target)) {
#if EVERY_ACCESS
printk( " SFAIL " );
printk(" SFAIL ");
#endif
spin_lock_irqsave(shpnt->host_lock, flags);
my_done( shpnt, DID_NO_CONNECT << 16 );
spin_unlock_irqrestore(shpnt->host_lock, flags);
return;
} else {
spin_lock_irqsave(shpnt->host_lock, flags);
my_done(shpnt, DID_NO_CONNECT << 16);
spin_unlock_irqrestore(shpnt->host_lock, flags);
return;
} else {
#if EVERY_ACCESS
printk( " AltSel " );
printk(" AltSel ");
#endif
/* Stop arbitration and enable parity */
outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
}
}
current_SC->SCp.phase = in_other;
outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
outb( 0x80, SCSI_Cntl_port );
/* Stop arbitration and enable parity */
outb(0x10 | PARITY_MASK, TMC_Cntl_port);
}
}
current_SC->SCp.phase = in_other;
outb(0x90 | FIFO_COUNT, Interrupt_Cntl_port);
outb(0x80, SCSI_Cntl_port);
#if DEBUG_RACE
in_interrupt_flag = 0;
in_interrupt_flag = 0;
#endif
return;
}
/* current_SC->SCp.phase == in_other: this is the body of the routine */
status = inb( SCSI_Status_port );
if (status & 0x10) { /* REQ */
switch (status & 0x0e) {
case 0x08: /* COMMAND OUT */
outb( current_SC->cmnd[current_SC->SCp.sent_command++],
Write_SCSI_Data_port );
return;
}
/* current_SC->SCp.phase == in_other: this is the body of the routine */
status = inb(SCSI_Status_port);
if (status & 0x10) { /* REQ */
switch (status & 0x0e) {
case 0x08: /* COMMAND OUT */
outb(current_SC->cmnd[current_SC->SCp.sent_command++], Write_SCSI_Data_port);
#if EVERY_ACCESS
printk( "CMD = %x,",
current_SC->cmnd[ current_SC->SCp.sent_command - 1] );
printk("CMD = %x,", current_SC->cmnd[current_SC->SCp.sent_command - 1]);
#endif
break;
case 0x00: /* DATA OUT -- tmc18c50/tmc18c30 only */
if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
current_SC->SCp.have_data_in = -1;
outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
}
break;
case 0x04: /* DATA IN -- tmc18c50/tmc18c30 only */
if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
current_SC->SCp.have_data_in = 1;
outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
}
break;
case 0x0c: /* STATUS IN */
current_SC->SCp.Status = inb( Read_SCSI_Data_port );
break;
case 0x00: /* DATA OUT -- tmc18c50/tmc18c30 only */
if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
current_SC->SCp.have_data_in = -1;
outb(0xd0 | PARITY_MASK, TMC_Cntl_port);
}
break;
case 0x04: /* DATA IN -- tmc18c50/tmc18c30 only */
if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
current_SC->SCp.have_data_in = 1;
outb(0x90 | PARITY_MASK, TMC_Cntl_port);
}
break;
case 0x0c: /* STATUS IN */
current_SC->SCp.Status = inb(Read_SCSI_Data_port);
#if EVERY_ACCESS
printk( "Status = %x, ", current_SC->SCp.Status );
printk("Status = %x, ", current_SC->SCp.Status);
#endif
#if ERRORS_ONLY
if (current_SC->SCp.Status
&& current_SC->SCp.Status != 2
&& current_SC->SCp.Status != 8) {
printk( "ERROR fd_mcs: target = %d, command = %x, status = %x\n",
current_SC->target,
current_SC->cmnd[0],
current_SC->SCp.Status );
}
if (current_SC->SCp.Status && current_SC->SCp.Status != 2 && current_SC->SCp.Status != 8) {
printk("ERROR fd_mcs: target = %d, command = %x, status = %x\n", current_SC->target, current_SC->cmnd[0], current_SC->SCp.Status);
}
#endif
break;
case 0x0a: /* MESSAGE OUT */
outb( MESSAGE_REJECT, Write_SCSI_Data_port ); /* Reject */
break;
case 0x0e: /* MESSAGE IN */
current_SC->SCp.Message = inb( Read_SCSI_Data_port );
break;
case 0x0a: /* MESSAGE OUT */
outb(MESSAGE_REJECT, Write_SCSI_Data_port); /* Reject */
break;
case 0x0e: /* MESSAGE IN */
current_SC->SCp.Message = inb(Read_SCSI_Data_port);
#if EVERY_ACCESS
printk( "Message = %x, ", current_SC->SCp.Message );
printk("Message = %x, ", current_SC->SCp.Message);
#endif
if (!current_SC->SCp.Message) ++done;
if (!current_SC->SCp.Message)
++done;
#if DEBUG_MESSAGES || EVERY_ACCESS
if (current_SC->SCp.Message) {
printk( "fd_mcs: message = %x\n", current_SC->SCp.Message );
}
if (current_SC->SCp.Message) {
printk("fd_mcs: message = %x\n", current_SC->SCp.Message);
}
#endif
break;
}
}
if (chip == tmc1800
&& !current_SC->SCp.have_data_in
&& (current_SC->SCp.sent_command
>= current_SC->cmd_len)) {
/* We have to get the FIFO direction
correct, so I've made a table based
on the SCSI Standard of which commands
appear to require a DATA OUT phase.
*/
/*
p. 94: Command for all device types
CHANGE DEFINITION 40 DATA OUT
COMPARE 39 DATA OUT
COPY 18 DATA OUT
COPY AND VERIFY 3a DATA OUT
INQUIRY 12
LOG SELECT 4c DATA OUT
LOG SENSE 4d
MODE SELECT (6) 15 DATA OUT
MODE SELECT (10) 55 DATA OUT
MODE SENSE (6) 1a
MODE SENSE (10) 5a
READ BUFFER 3c
RECEIVE DIAGNOSTIC RESULTS 1c
REQUEST SENSE 03
SEND DIAGNOSTIC 1d DATA OUT
TEST UNIT READY 00
WRITE BUFFER 3b DATA OUT
p.178: Commands for direct-access devices (not listed on p. 94)
FORMAT UNIT 04 DATA OUT
LOCK-UNLOCK CACHE 36
PRE-FETCH 34
PREVENT-ALLOW MEDIUM REMOVAL 1e
READ (6)/RECEIVE 08
READ (10) 3c
READ CAPACITY 25
READ DEFECT DATA (10) 37
READ LONG 3e
REASSIGN BLOCKS 07 DATA OUT
RELEASE 17
RESERVE 16 DATA OUT
REZERO UNIT/REWIND 01
SEARCH DATA EQUAL (10) 31 DATA OUT
SEARCH DATA HIGH (10) 30 DATA OUT
SEARCH DATA LOW (10) 32 DATA OUT
SEEK (6) 0b
SEEK (10) 2b
SET LIMITS (10) 33
START STOP UNIT 1b
SYNCHRONIZE CACHE 35
VERIFY (10) 2f
WRITE (6)/PRINT/SEND 0a DATA OUT
WRITE (10)/SEND 2a DATA OUT
WRITE AND VERIFY (10) 2e DATA OUT
WRITE LONG 3f DATA OUT
WRITE SAME 41 DATA OUT ?
p. 261: Commands for sequential-access devices (not previously listed)
ERASE 19
LOAD UNLOAD 1b
LOCATE 2b
READ BLOCK LIMITS 05
READ POSITION 34
READ REVERSE 0f
RECOVER BUFFERED DATA 14
SPACE 11
WRITE FILEMARKS 10 ?
p. 298: Commands for printer devices (not previously listed)
****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****
SLEW AND PRINT 0b DATA OUT -- same as seek
STOP PRINT 1b
SYNCHRONIZE BUFFER 10
p. 315: Commands for processor devices (not previously listed)
p. 321: Commands for write-once devices (not previously listed)
MEDIUM SCAN 38
READ (12) a8
SEARCH DATA EQUAL (12) b1 DATA OUT
SEARCH DATA HIGH (12) b0 DATA OUT
SEARCH DATA LOW (12) b2 DATA OUT
SET LIMITS (12) b3
VERIFY (12) af
WRITE (12) aa DATA OUT
WRITE AND VERIFY (12) ae DATA OUT
p. 332: Commands for CD-ROM devices (not previously listed)
PAUSE/RESUME 4b
PLAY AUDIO (10) 45
PLAY AUDIO (12) a5
PLAY AUDIO MSF 47
PLAY TRACK RELATIVE (10) 49
PLAY TRACK RELATIVE (12) a9
READ HEADER 44
READ SUB-CHANNEL 42
READ TOC 43
p. 370: Commands for scanner devices (not previously listed)
GET DATA BUFFER STATUS 34
GET WINDOW 25
OBJECT POSITION 31
SCAN 1b
SET WINDOW 24 DATA OUT
p. 391: Commands for optical memory devices (not listed)
ERASE (10) 2c
ERASE (12) ac
MEDIUM SCAN 38 DATA OUT
READ DEFECT DATA (12) b7
READ GENERATION 29
READ UPDATED BLOCK 2d
UPDATE BLOCK 3d DATA OUT
p. 419: Commands for medium changer devices (not listed)
EXCHANGE MEDIUM 46
INITIALIZE ELEMENT STATUS 07
MOVE MEDIUM a5
POSITION TO ELEMENT 2b
READ ELEMENT STATUS b8
REQUEST VOL. ELEMENT ADDRESS b5
SEND VOLUME TAG b6 DATA OUT
p. 454: Commands for communications devices (not listed previously)
GET MESSAGE (6) 08
GET MESSAGE (10) 28
GET MESSAGE (12) a8
*/
switch (current_SC->cmnd[0]) {
case CHANGE_DEFINITION: case COMPARE: case COPY:
case COPY_VERIFY: case LOG_SELECT: case MODE_SELECT:
case MODE_SELECT_10: case SEND_DIAGNOSTIC: case WRITE_BUFFER:
case FORMAT_UNIT: case REASSIGN_BLOCKS: case RESERVE:
case SEARCH_EQUAL: case SEARCH_HIGH: case SEARCH_LOW:
case WRITE_6: case WRITE_10: case WRITE_VERIFY:
case 0x3f: case 0x41:
case 0xb1: case 0xb0: case 0xb2:
case 0xaa: case 0xae:
case 0x24:
case 0x38: case 0x3d:
case 0xb6:
case 0xea: /* alternate number for WRITE LONG */
current_SC->SCp.have_data_in = -1;
outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
break;
case 0x00:
default:
current_SC->SCp.have_data_in = 1;
outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
break;
}
}
if (current_SC->SCp.have_data_in == -1) { /* DATA OUT */
while ( (data_count = FIFO_Size - inw( FIFO_Data_Count_port )) > 512 ) {
break;
}
}
if (chip == tmc1800 && !current_SC->SCp.have_data_in && (current_SC->SCp.sent_command >= current_SC->cmd_len)) {
/* We have to get the FIFO direction
correct, so I've made a table based
on the SCSI Standard of which commands
appear to require a DATA OUT phase.
*/
/*
p. 94: Command for all device types
CHANGE DEFINITION 40 DATA OUT
COMPARE 39 DATA OUT
COPY 18 DATA OUT
COPY AND VERIFY 3a DATA OUT
INQUIRY 12
LOG SELECT 4c DATA OUT
LOG SENSE 4d
MODE SELECT (6) 15 DATA OUT
MODE SELECT (10) 55 DATA OUT
MODE SENSE (6) 1a
MODE SENSE (10) 5a
READ BUFFER 3c
RECEIVE DIAGNOSTIC RESULTS 1c
REQUEST SENSE 03
SEND DIAGNOSTIC 1d DATA OUT
TEST UNIT READY 00
WRITE BUFFER 3b DATA OUT
p.178: Commands for direct-access devices (not listed on p. 94)
FORMAT UNIT 04 DATA OUT
LOCK-UNLOCK CACHE 36
PRE-FETCH 34
PREVENT-ALLOW MEDIUM REMOVAL 1e
READ (6)/RECEIVE 08
READ (10) 3c
READ CAPACITY 25
READ DEFECT DATA (10) 37
READ LONG 3e
REASSIGN BLOCKS 07 DATA OUT
RELEASE 17
RESERVE 16 DATA OUT
REZERO UNIT/REWIND 01
SEARCH DATA EQUAL (10) 31 DATA OUT
SEARCH DATA HIGH (10) 30 DATA OUT
SEARCH DATA LOW (10) 32 DATA OUT
SEEK (6) 0b
SEEK (10) 2b
SET LIMITS (10) 33
START STOP UNIT 1b
SYNCHRONIZE CACHE 35
VERIFY (10) 2f
WRITE (6)/PRINT/SEND 0a DATA OUT
WRITE (10)/SEND 2a DATA OUT
WRITE AND VERIFY (10) 2e DATA OUT
WRITE LONG 3f DATA OUT
WRITE SAME 41 DATA OUT ?
p. 261: Commands for sequential-access devices (not previously listed)
ERASE 19
LOAD UNLOAD 1b
LOCATE 2b
READ BLOCK LIMITS 05
READ POSITION 34
READ REVERSE 0f
RECOVER BUFFERED DATA 14
SPACE 11
WRITE FILEMARKS 10 ?
p. 298: Commands for printer devices (not previously listed)
****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****
SLEW AND PRINT 0b DATA OUT -- same as seek
STOP PRINT 1b
SYNCHRONIZE BUFFER 10
p. 315: Commands for processor devices (not previously listed)
p. 321: Commands for write-once devices (not previously listed)
MEDIUM SCAN 38
READ (12) a8
SEARCH DATA EQUAL (12) b1 DATA OUT
SEARCH DATA HIGH (12) b0 DATA OUT
SEARCH DATA LOW (12) b2 DATA OUT
SET LIMITS (12) b3
VERIFY (12) af
WRITE (12) aa DATA OUT
WRITE AND VERIFY (12) ae DATA OUT
p. 332: Commands for CD-ROM devices (not previously listed)
PAUSE/RESUME 4b
PLAY AUDIO (10) 45
PLAY AUDIO (12) a5
PLAY AUDIO MSF 47
PLAY TRACK RELATIVE (10) 49
PLAY TRACK RELATIVE (12) a9
READ HEADER 44
READ SUB-CHANNEL 42
READ TOC 43
p. 370: Commands for scanner devices (not previously listed)
GET DATA BUFFER STATUS 34
GET WINDOW 25
OBJECT POSITION 31
SCAN 1b
SET WINDOW 24 DATA OUT
p. 391: Commands for optical memory devices (not listed)
ERASE (10) 2c
ERASE (12) ac
MEDIUM SCAN 38 DATA OUT
READ DEFECT DATA (12) b7
READ GENERATION 29
READ UPDATED BLOCK 2d
UPDATE BLOCK 3d DATA OUT
p. 419: Commands for medium changer devices (not listed)
EXCHANGE MEDIUM 46
INITIALIZE ELEMENT STATUS 07
MOVE MEDIUM a5
POSITION TO ELEMENT 2b
READ ELEMENT STATUS b8
REQUEST VOL. ELEMENT ADDRESS b5
SEND VOLUME TAG b6 DATA OUT
p. 454: Commands for communications devices (not listed previously)
GET MESSAGE (6) 08
GET MESSAGE (10) 28
GET MESSAGE (12) a8
*/
switch (current_SC->cmnd[0]) {
case CHANGE_DEFINITION:
case COMPARE:
case COPY:
case COPY_VERIFY:
case LOG_SELECT:
case MODE_SELECT:
case MODE_SELECT_10:
case SEND_DIAGNOSTIC:
case WRITE_BUFFER:
case FORMAT_UNIT:
case REASSIGN_BLOCKS:
case RESERVE:
case SEARCH_EQUAL:
case SEARCH_HIGH:
case SEARCH_LOW:
case WRITE_6:
case WRITE_10:
case WRITE_VERIFY:
case 0x3f:
case 0x41:
case 0xb1:
case 0xb0:
case 0xb2:
case 0xaa:
case 0xae:
case 0x24:
case 0x38:
case 0x3d:
case 0xb6:
case 0xea: /* alternate number for WRITE LONG */
current_SC->SCp.have_data_in = -1;
outb(0xd0 | PARITY_MASK, TMC_Cntl_port);
break;
case 0x00:
default:
current_SC->SCp.have_data_in = 1;
outb(0x90 | PARITY_MASK, TMC_Cntl_port);
break;
}
}
if (current_SC->SCp.have_data_in == -1) { /* DATA OUT */
while ((data_count = FIFO_Size - inw(FIFO_Data_Count_port)) > 512) {
#if EVERY_ACCESS
printk( "DC=%d, ", data_count ) ;
printk("DC=%d, ", data_count);
#endif
if (data_count > current_SC->SCp.this_residual)
data_count = current_SC->SCp.this_residual;
if (data_count > 0) {
if (data_count > current_SC->SCp.this_residual)
data_count = current_SC->SCp.this_residual;
if (data_count > 0) {
#if EVERY_ACCESS
printk( "%d OUT, ", data_count );
printk("%d OUT, ", data_count);
#endif
if (data_count == 1) {
Bytes_Written++;
outb( *current_SC->SCp.ptr++, Write_FIFO_port );
--current_SC->SCp.this_residual;
} else {
data_count >>= 1;
tmp_count = data_count << 1;
outsw( Write_FIFO_port, current_SC->SCp.ptr, data_count );
current_SC->SCp.ptr += tmp_count;
Bytes_Written += tmp_count;
current_SC->SCp.this_residual -= tmp_count;
}
}
if (!current_SC->SCp.this_residual) {
if (current_SC->SCp.buffers_residual) {
--current_SC->SCp.buffers_residual;
++current_SC->SCp.buffer;
current_SC->SCp.ptr = current_SC->SCp.buffer->address;
current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
} else
break;
}
}
} else if (current_SC->SCp.have_data_in == 1) { /* DATA IN */
while ((data_count = inw( FIFO_Data_Count_port )) > 0) {
if (data_count == 1) {
Bytes_Written++;
outb(*current_SC->SCp.ptr++, Write_FIFO_port);
--current_SC->SCp.this_residual;
} else {
data_count >>= 1;
tmp_count = data_count << 1;
outsw(Write_FIFO_port, current_SC->SCp.ptr, data_count);
current_SC->SCp.ptr += tmp_count;
Bytes_Written += tmp_count;
current_SC->SCp.this_residual -= tmp_count;
}
}
if (!current_SC->SCp.this_residual) {
if (current_SC->SCp.buffers_residual) {
--current_SC->SCp.buffers_residual;
++current_SC->SCp.buffer;
current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
} else
break;
}
}
} else if (current_SC->SCp.have_data_in == 1) { /* DATA IN */
while ((data_count = inw(FIFO_Data_Count_port)) > 0) {
#if EVERY_ACCESS
printk( "DC=%d, ", data_count );
printk("DC=%d, ", data_count);
#endif
if (data_count > current_SC->SCp.this_residual)
data_count = current_SC->SCp.this_residual;
if (data_count) {
if (data_count > current_SC->SCp.this_residual)
data_count = current_SC->SCp.this_residual;
if (data_count) {
#if EVERY_ACCESS
printk( "%d IN, ", data_count );
printk("%d IN, ", data_count);
#endif
if (data_count == 1) {
Bytes_Read++;
*current_SC->SCp.ptr++ = inb( Read_FIFO_port );
--current_SC->SCp.this_residual;
} else {
data_count >>= 1; /* Number of words */
tmp_count = data_count << 1;
insw( Read_FIFO_port, current_SC->SCp.ptr, data_count );
current_SC->SCp.ptr += tmp_count;
Bytes_Read += tmp_count;
current_SC->SCp.this_residual -= tmp_count;
if (data_count == 1) {
Bytes_Read++;
*current_SC->SCp.ptr++ = inb(Read_FIFO_port);
--current_SC->SCp.this_residual;
} else {
data_count >>= 1; /* Number of words */
tmp_count = data_count << 1;
insw(Read_FIFO_port, current_SC->SCp.ptr, data_count);
current_SC->SCp.ptr += tmp_count;
Bytes_Read += tmp_count;
current_SC->SCp.this_residual -= tmp_count;
}
}
if (!current_SC->SCp.this_residual && current_SC->SCp.buffers_residual) {
--current_SC->SCp.buffers_residual;
++current_SC->SCp.buffer;
current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
}
}
}
}
if (!current_SC->SCp.this_residual
&& current_SC->SCp.buffers_residual) {
--current_SC->SCp.buffers_residual;
++current_SC->SCp.buffer;
current_SC->SCp.ptr = current_SC->SCp.buffer->address;
current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
}
}
}
if (done) {
if (done) {
#if EVERY_ACCESS
printk( " ** IN DONE %d ** ", current_SC->SCp.have_data_in );
printk(" ** IN DONE %d ** ", current_SC->SCp.have_data_in);
#endif
#if ERRORS_ONLY
if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {
if ((unsigned char)(*((char *)current_SC->request_buffer+2)) & 0x0f) {
unsigned char key;
unsigned char code;
unsigned char qualifier;
key = (unsigned char)(*((char *)current_SC->request_buffer + 2))
& 0x0f;
code = (unsigned char)(*((char *)current_SC->request_buffer + 12));
qualifier = (unsigned char)(*((char *)current_SC->request_buffer
+ 13));
if (key != UNIT_ATTENTION
&& !(key == NOT_READY
&& code == 0x04
&& (!qualifier || qualifier == 0x02 || qualifier == 0x01))
&& !(key == ILLEGAL_REQUEST && (code == 0x25
|| code == 0x24
|| !code)))
printk( "fd_mcs: REQUEST SENSE "
"Key = %x, Code = %x, Qualifier = %x\n",
key, code, qualifier );
}
}
if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {
if ((unsigned char) (*((char *) current_SC->request_buffer + 2)) & 0x0f) {
unsigned char key;
unsigned char code;
unsigned char qualifier;
key = (unsigned char) (*((char *) current_SC->request_buffer + 2)) & 0x0f;
code = (unsigned char) (*((char *) current_SC->request_buffer + 12));
qualifier = (unsigned char) (*((char *) current_SC->request_buffer + 13));
if (key != UNIT_ATTENTION && !(key == NOT_READY && code == 0x04 && (!qualifier || qualifier == 0x02 || qualifier == 0x01))
&& !(key == ILLEGAL_REQUEST && (code == 0x25 || code == 0x24 || !code)))
printk("fd_mcs: REQUEST SENSE " "Key = %x, Code = %x, Qualifier = %x\n", key, code, qualifier);
}
}
#endif
#if EVERY_ACCESS
printk( "BEFORE MY_DONE. . ." );
printk("BEFORE MY_DONE. . .");
#endif
spin_lock_irqsave(shpnt->host_lock, flags);
my_done( shpnt,
(current_SC->SCp.Status & 0xff)
| ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) );
spin_unlock_irqrestore(shpnt->host_lock, flags);
spin_lock_irqsave(shpnt->host_lock, flags);
my_done(shpnt, (current_SC->SCp.Status & 0xff)
| ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16));
spin_unlock_irqrestore(shpnt->host_lock, flags);
#if EVERY_ACCESS
printk( "RETURNING.\n" );
printk("RETURNING.\n");
#endif
} else {
if (current_SC->SCp.phase & disconnect) {
outb( 0xd0 | FIFO_COUNT, Interrupt_Cntl_port );
outb( 0x00, SCSI_Cntl_port );
} else {
outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
}
}
} else {
if (current_SC->SCp.phase & disconnect) {
outb(0xd0 | FIFO_COUNT, Interrupt_Cntl_port);
outb(0x00, SCSI_Cntl_port);
} else {
outb(0x90 | FIFO_COUNT, Interrupt_Cntl_port);
}
}
#if DEBUG_RACE
in_interrupt_flag = 0;
in_interrupt_flag = 0;
#endif
return;
return;
}
int fd_mcs_release(struct Scsi_Host *shpnt)
static int fd_mcs_release(struct Scsi_Host *shpnt)
{
int i, this_host, irq_usage;
int i, this_host, irq_usage;
release_region(shpnt->io_port, shpnt->n_io_port);
release_region(shpnt->io_port, shpnt->n_io_port);
this_host = -1;
irq_usage = 0;
for (i = 0; i < found; i++) {
if (shpnt == hosts[i])
this_host = i;
if (shpnt->irq == hosts[i]->irq)
irq_usage++;
}
this_host = -1;
irq_usage = 0;
for (i = 0; i < found; i++) {
if (shpnt == hosts[i])
this_host = i;
if (shpnt->irq == hosts[i]->irq)
irq_usage++;
}
/* only for the last one */
if (1 == irq_usage)
free_irq(shpnt->irq, hosts);
/* only for the last one */
if (1 == irq_usage)
free_irq(shpnt->irq, hosts);
found--;
found--;
for (i = this_host; i < found; i++)
hosts[i] = hosts[i+1];
for (i = this_host; i < found; i++)
hosts[i] = hosts[i + 1];
hosts[found] = NULL;
hosts[found] = NULL;
return 0;
return 0;
}
int fd_mcs_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
static int fd_mcs_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
{
struct Scsi_Host *shpnt = SCpnt->host;
struct Scsi_Host *shpnt = SCpnt->host;
if (in_command) {
panic( "fd_mcs: fd_mcs_queue() NOT REENTRANT!\n" );
}
if (in_command) {
panic("fd_mcs: fd_mcs_queue() NOT REENTRANT!\n");
}
#if EVERY_ACCESS
printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
SCpnt->target,
*(unsigned char *)SCpnt->cmnd,
SCpnt->use_sg,
SCpnt->request_bufflen );
printk("queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n", SCpnt->target, *(unsigned char *) SCpnt->cmnd, SCpnt->use_sg, SCpnt->request_bufflen);
#endif
fd_mcs_make_bus_idle(shpnt);
SCpnt->scsi_done = done; /* Save this for the done function */
current_SC = SCpnt;
/* Initialize static data */
if (current_SC->use_sg) {
current_SC->SCp.buffer =
(struct scatterlist *)current_SC->request_buffer;
current_SC->SCp.ptr = current_SC->SCp.buffer->address;
current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
} else {
current_SC->SCp.ptr = (char *)current_SC->request_buffer;
current_SC->SCp.this_residual = current_SC->request_bufflen;
current_SC->SCp.buffer = NULL;
current_SC->SCp.buffers_residual = 0;
}
current_SC->SCp.Status = 0;
current_SC->SCp.Message = 0;
current_SC->SCp.have_data_in = 0;
current_SC->SCp.sent_command = 0;
current_SC->SCp.phase = in_arbitration;
/* Start arbitration */
outb( 0x00, Interrupt_Cntl_port );
outb( 0x00, SCSI_Cntl_port ); /* Disable data drivers */
outb( adapter_mask, SCSI_Data_NoACK_port ); /* Set our id bit */
in_command = 1;
outb( 0x20, Interrupt_Cntl_port );
outb( 0x14 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */
return 0;
fd_mcs_make_bus_idle(shpnt);
SCpnt->scsi_done = done; /* Save this for the done function */
current_SC = SCpnt;
/* Initialize static data */
if (current_SC->use_sg) {
current_SC->SCp.buffer = (struct scatterlist *) current_SC->request_buffer;
current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
} else {
current_SC->SCp.ptr = (char *) current_SC->request_buffer;
current_SC->SCp.this_residual = current_SC->request_bufflen;
current_SC->SCp.buffer = NULL;
current_SC->SCp.buffers_residual = 0;
}
current_SC->SCp.Status = 0;
current_SC->SCp.Message = 0;
current_SC->SCp.have_data_in = 0;
current_SC->SCp.sent_command = 0;
current_SC->SCp.phase = in_arbitration;
/* Start arbitration */
outb(0x00, Interrupt_Cntl_port);
outb(0x00, SCSI_Cntl_port); /* Disable data drivers */
outb(adapter_mask, SCSI_Data_NoACK_port); /* Set our id bit */
in_command = 1;
outb(0x20, Interrupt_Cntl_port);
outb(0x14 | PARITY_MASK, TMC_Cntl_port); /* Start arbitration */
return 0;
}
static void internal_done( Scsi_Cmnd *SCpnt )
static void internal_done(Scsi_Cmnd * SCpnt)
{
/* flag it done */
SCpnt->host_scribble = (unsigned char *)1;
/* flag it done */
SCpnt->host_scribble = (unsigned char *) 1;
}
int fd_mcs_command( Scsi_Cmnd *SCpnt )
int fd_mcs_command(Scsi_Cmnd * SCpnt)
{
fd_mcs_queue( SCpnt, internal_done );
/* host_scribble is used for status here */
SCpnt->host_scribble = NULL;
while (!SCpnt->host_scribble)
barrier();
return SCpnt->result;
fd_mcs_queue(SCpnt, internal_done);
/* host_scribble is used for status here */
SCpnt->host_scribble = NULL;
while (!SCpnt->host_scribble) {
cpu_relax();
barrier();
}
return SCpnt->result;
}
#if DEBUG_ABORT || DEBUG_RESET
static void fd_mcs_print_info( Scsi_Cmnd *SCpnt )
static void fd_mcs_print_info(Scsi_Cmnd * SCpnt)
{
unsigned int imr;
unsigned int irr;
unsigned int isr;
struct Scsi_Host *shpnt = SCpnt->host;
if (!SCpnt || !SCpnt->host) {
printk( "fd_mcs: cannot provide detailed information\n" );
}
printk( "%s\n", fd_mcs_info( SCpnt->host ) );
print_banner( SCpnt->host );
switch (SCpnt->SCp.phase) {
case in_arbitration: printk( "arbitration " ); break;
case in_selection: printk( "selection " ); break;
case in_other: printk( "other " ); break;
default: printk( "unknown " ); break;
}
printk( "(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
SCpnt->SCp.phase,
SCpnt->target,
*(unsigned char *)SCpnt->cmnd,
SCpnt->use_sg,
SCpnt->request_bufflen );
printk( "sent_command = %d, have_data_in = %d, timeout = %d\n",
SCpnt->SCp.sent_command,
SCpnt->SCp.have_data_in,
SCpnt->timeout );
unsigned int imr;
unsigned int irr;
unsigned int isr;
struct Scsi_Host *shpnt = SCpnt->host;
if (!SCpnt || !SCpnt->host) {
printk("fd_mcs: cannot provide detailed information\n");
}
printk("%s\n", fd_mcs_info(SCpnt->host));
print_banner(SCpnt->host);
switch (SCpnt->SCp.phase) {
case in_arbitration:
printk("arbitration ");
break;
case in_selection:
printk("selection ");
break;
case in_other:
printk("other ");
break;
default:
printk("unknown ");
break;
}
printk("(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n", SCpnt->SCp.phase, SCpnt->target, *(unsigned char *) SCpnt->cmnd, SCpnt->use_sg, SCpnt->request_bufflen);
printk("sent_command = %d, have_data_in = %d, timeout = %d\n", SCpnt->SCp.sent_command, SCpnt->SCp.have_data_in, SCpnt->timeout);
#if DEBUG_RACE
printk( "in_interrupt_flag = %d\n", in_interrupt_flag );
printk("in_interrupt_flag = %d\n", in_interrupt_flag);
#endif
imr = (inb( 0x0a1 ) << 8) + inb( 0x21 );
outb( 0x0a, 0xa0 );
irr = inb( 0xa0 ) << 8;
outb( 0x0a, 0x20 );
irr += inb( 0x20 );
outb( 0x0b, 0xa0 );
isr = inb( 0xa0 ) << 8;
outb( 0x0b, 0x20 );
isr += inb( 0x20 );
/* Print out interesting information */
printk( "IMR = 0x%04x", imr );
if (imr & (1 << shpnt->irq))
printk( " (masked)" );
printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr );
printk( "SCSI Status = 0x%02x\n", inb( SCSI_Status_port ) );
printk( "TMC Status = 0x%02x", inb( TMC_Status_port ) );
if (inb( TMC_Status_port ) & 1)
printk( " (interrupt)" );
printk( "\n" );
printk( "Interrupt Status = 0x%02x", inb( Interrupt_Status_port ) );
if (inb( Interrupt_Status_port ) & 0x08)
printk( " (enabled)" );
printk( "\n" );
if (chip == tmc18c50 || chip == tmc18c30) {
printk( "FIFO Status = 0x%02x\n", inb( shpnt->io_port + FIFO_Status ) );
printk( "Int. Condition = 0x%02x\n",
inb( shpnt->io_port + Interrupt_Cond ) );
}
printk( "Configuration 1 = 0x%02x\n", inb( shpnt->io_port + Configuration1 ) );
if (chip == tmc18c50 || chip == tmc18c30)
printk( "Configuration 2 = 0x%02x\n",
inb( shpnt->io_port + Configuration2 ) );
imr = (inb(0x0a1) << 8) + inb(0x21);
outb(0x0a, 0xa0);
irr = inb(0xa0) << 8;
outb(0x0a, 0x20);
irr += inb(0x20);
outb(0x0b, 0xa0);
isr = inb(0xa0) << 8;
outb(0x0b, 0x20);
isr += inb(0x20);
/* Print out interesting information */
printk("IMR = 0x%04x", imr);
if (imr & (1 << shpnt->irq))
printk(" (masked)");
printk(", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr);
printk("SCSI Status = 0x%02x\n", inb(SCSI_Status_port));
printk("TMC Status = 0x%02x", inb(TMC_Status_port));
if (inb(TMC_Status_port) & 1)
printk(" (interrupt)");
printk("\n");
printk("Interrupt Status = 0x%02x", inb(Interrupt_Status_port));
if (inb(Interrupt_Status_port) & 0x08)
printk(" (enabled)");
printk("\n");
if (chip == tmc18c50 || chip == tmc18c30) {
printk("FIFO Status = 0x%02x\n", inb(shpnt->io_port + FIFO_Status));
printk("Int. Condition = 0x%02x\n", inb(shpnt->io_port + Interrupt_Cond));
}
printk("Configuration 1 = 0x%02x\n", inb(shpnt->io_port + Configuration1));
if (chip == tmc18c50 || chip == tmc18c30)
printk("Configuration 2 = 0x%02x\n", inb(shpnt->io_port + Configuration2));
}
#endif
int fd_mcs_abort( Scsi_Cmnd *SCpnt)
static int fd_mcs_abort(Scsi_Cmnd * SCpnt)
{
struct Scsi_Host *shpnt = SCpnt->host;
struct Scsi_Host *shpnt = SCpnt->host;
unsigned long flags;
unsigned long flags;
#if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
printk( "fd_mcs: abort " );
printk("fd_mcs: abort ");
#endif
save_flags( flags );
cli();
if (!in_command) {
spin_lock_irqsave(shpnt->host_lock, flags);
if (!in_command) {
#if EVERY_ACCESS || ERRORS_ONLY
printk( " (not in command)\n" );
printk(" (not in command)\n");
#endif
restore_flags( flags );
return SCSI_ABORT_NOT_RUNNING;
} else printk( "\n" );
spin_unlock_irqrestore(shpnt->host_lock, flags);
return FAILED;
} else
printk("\n");
#if DEBUG_ABORT
fd_mcs_print_info( SCpnt );
fd_mcs_print_info(SCpnt);
#endif
fd_mcs_make_bus_idle(shpnt);
fd_mcs_make_bus_idle(shpnt);
current_SC->SCp.phase |= aborted;
current_SC->SCp.phase |= aborted;
current_SC->result = DID_ABORT << 16;
current_SC->result = DID_ABORT << 16;
restore_flags( flags );
/* Aborts are not done well. . . */
spin_lock_irqsave(shpnt->host_lock, flags);
my_done( shpnt, DID_ABORT << 16 );
spin_unlock_irqrestore(shpnt->host_lock, flags);
/* Aborts are not done well. . . */
my_done(shpnt, DID_ABORT << 16);
return SCSI_ABORT_SUCCESS;
spin_unlock_irqrestore(shpnt->host_lock, flags);
return SUCCESS;
}
int fd_mcs_reset( Scsi_Cmnd *SCpnt, unsigned int reset_flags )
static int fd_mcs_host_reset(Scsi_Cmnd * SCpnt)
{
struct Scsi_Host *shpnt = SCpnt->host;
return FAILED;
}
static int fd_mcs_device_reset(Scsi_Cmnd * SCpnt) {
return FAILED;
}
static int fd_mcs_bus_reset(Scsi_Cmnd * SCpnt) {
struct Scsi_Host *shpnt = SCpnt->host;
unsigned long flags;
#if DEBUG_RESET
static int called_once = 0;
static int called_once = 0;
#endif
#if ERRORS_ONLY
if (SCpnt) printk( "fd_mcs: SCSI Bus Reset\n" );
if (SCpnt)
printk("fd_mcs: SCSI Bus Reset\n");
#endif
#if DEBUG_RESET
if (called_once) fd_mcs_print_info( current_SC );
called_once = 1;
if (called_once)
fd_mcs_print_info(current_SC);
called_once = 1;
#endif
outb( 1, SCSI_Cntl_port );
do_pause( 2 );
outb( 0, SCSI_Cntl_port );
do_pause( 115 );
outb( 0, SCSI_Mode_Cntl_port );
outb( PARITY_MASK, TMC_Cntl_port );
/* Unless this is the very first call (i.e., SCPnt == NULL), everything
is probably hosed at this point. We will, however, try to keep
things going by informing the high-level code that we need help. */
return SCSI_RESET_WAKEUP;
}
spin_lock_irqsave(shpnt->host_lock, flags);
outb(1, SCSI_Cntl_port);
do_pause(2);
outb(0, SCSI_Cntl_port);
do_pause(115);
outb(0, SCSI_Mode_Cntl_port);
outb(PARITY_MASK, TMC_Cntl_port);
/* Unless this is the very first call (i.e., SCPnt == NULL), everything
is probably hosed at this point. We will, however, try to keep
things going by informing the high-level code that we need help. */
spin_unlock_irqrestore(shpnt->host_lock, flags);
return SUCCESS;
}
#include "sd.h"
#include <scsi/scsi_ioctl.h>
int fd_mcs_biosparam( Scsi_Disk *disk, struct block_device *bdev, int *info_array )
{
unsigned char buf[512 + sizeof( int ) * 2];
int size = disk->capacity;
int *sizes = (int *)buf;
unsigned char *data = (unsigned char *)(sizes + 2);
unsigned char do_read[] = { READ_6, 0, 0, 0, 1, 0 };
int retcode;
/* BIOS >= 3.4 for MCA cards */
/* This algorithm was provided by Future Domain (much thanks!). */
sizes[0] = 0; /* zero bytes out */
sizes[1] = 512; /* one sector in */
memcpy( data, do_read, sizeof( do_read ) );
retcode = kernel_scsi_ioctl( disk->device,
SCSI_IOCTL_SEND_COMMAND,
(void *)buf );
if (!retcode /* SCSI command ok */
&& data[511] == 0xaa && data[510] == 0x55 /* Partition table valid */
&& data[0x1c2]) { /* Partition type */
/* The partition table layout is as follows:
Start: 0x1b3h
Offset: 0 = partition status
1 = starting head
2 = starting sector and cylinder (word, encoded)
4 = partition type
5 = ending head
6 = ending sector and cylinder (word, encoded)
8 = starting absolute sector (double word)
c = number of sectors (double word)
Signature: 0x1fe = 0x55aa
So, this algorithm assumes:
1) the first partition table is in use,
2) the data in the first entry is correct, and
3) partitions never divide cylinders
Note that (1) may be FALSE for NetBSD (and other BSD flavors),
as well as for Linux. Note also, that Linux doesn't pay any
attention to the fields that are used by this algorithm -- it
only uses the absolute sector data. Recent versions of Linux's
fdisk(1) will fill this data in correctly, and forthcoming
versions will check for consistency.
Checking for a non-zero partition type is not part of the
Future Domain algorithm, but it seemed to be a reasonable thing
to do, especially in the Linux and BSD worlds. */
info_array[0] = data[0x1c3] + 1; /* heads */
info_array[1] = data[0x1c4] & 0x3f; /* sectors */
} else {
/* Note that this new method guarantees that there will always be
less than 1024 cylinders on a platter. This is good for drives
up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */
if ((unsigned int)size >= 0x7e0000U) {
info_array[0] = 0xff; /* heads = 255 */
info_array[1] = 0x3f; /* sectors = 63 */
} else if ((unsigned int)size >= 0x200000U) {
info_array[0] = 0x80; /* heads = 128 */
info_array[1] = 0x3f; /* sectors = 63 */
} else {
info_array[0] = 0x40; /* heads = 64 */
info_array[1] = 0x20; /* sectors = 32 */
}
}
/* For both methods, compute the cylinders */
info_array[2] = (unsigned int)size / (info_array[0] * info_array[1] );
return 0;
}
static int fd_mcs_biosparam(Scsi_Disk * disk, struct block_device *bdev, int *info_array) {
unsigned char buf[512 + sizeof(int) * 2];
int size = disk->capacity;
int *sizes = (int *) buf;
unsigned char *data = (unsigned char *) (sizes + 2);
unsigned char do_read[] = { READ_6, 0, 0, 0, 1, 0 };
int retcode;
/* BIOS >= 3.4 for MCA cards */
/* This algorithm was provided by Future Domain (much thanks!). */
sizes[0] = 0; /* zero bytes out */
sizes[1] = 512; /* one sector in */
memcpy(data, do_read, sizeof(do_read));
retcode = kernel_scsi_ioctl(disk->device, SCSI_IOCTL_SEND_COMMAND, (void *) buf);
if (!retcode /* SCSI command ok */
&& data[511] == 0xaa && data[510] == 0x55 /* Partition table valid */
&& data[0x1c2]) { /* Partition type */
/* The partition table layout is as follows:
Start: 0x1b3h
Offset: 0 = partition status
1 = starting head
2 = starting sector and cylinder (word, encoded)
4 = partition type
5 = ending head
6 = ending sector and cylinder (word, encoded)
8 = starting absolute sector (double word)
c = number of sectors (double word)
Signature: 0x1fe = 0x55aa
So, this algorithm assumes:
1) the first partition table is in use,
2) the data in the first entry is correct, and
3) partitions never divide cylinders
Note that (1) may be FALSE for NetBSD (and other BSD flavors),
as well as for Linux. Note also, that Linux doesn't pay any
attention to the fields that are used by this algorithm -- it
only uses the absolute sector data. Recent versions of Linux's
fdisk(1) will fill this data in correctly, and forthcoming
versions will check for consistency.
Checking for a non-zero partition type is not part of the
Future Domain algorithm, but it seemed to be a reasonable thing
to do, especially in the Linux and BSD worlds. */
info_array[0] = data[0x1c3] + 1; /* heads */
info_array[1] = data[0x1c4] & 0x3f; /* sectors */
} else {
/* Note that this new method guarantees that there will always be
less than 1024 cylinders on a platter. This is good for drives
up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */
if ((unsigned int) size >= 0x7e0000U) {
info_array[0] = 0xff; /* heads = 255 */
info_array[1] = 0x3f; /* sectors = 63 */
} else if ((unsigned int) size >= 0x200000U) {
info_array[0] = 0x80; /* heads = 128 */
info_array[1] = 0x3f; /* sectors = 63 */
} else {
info_array[0] = 0x40; /* heads = 64 */
info_array[1] = 0x20; /* sectors = 32 */
}
}
/* For both methods, compute the cylinders */
info_array[2] = (unsigned int) size / (info_array[0] * info_array[1]);
return 0;
}
/* Eventually this will go into an include file, but this will be later */
static Scsi_Host_Template driver_template = FD_MCS;
static Scsi_Host_Template driver_template = FD_MCS;
#include "scsi_module.c"
......@@ -22,31 +22,36 @@
#ifndef _FD_MCS_H
#define _FD_MCS_H
extern int fd_mcs_detect( Scsi_Host_Template * );
extern int fd_mcs_release( struct Scsi_Host * );
extern int fd_mcs_command( Scsi_Cmnd * );
extern int fd_mcs_abort( Scsi_Cmnd * );
extern int fd_mcs_reset( Scsi_Cmnd *, unsigned int );
extern int fd_mcs_queue( Scsi_Cmnd *, void (*done)(Scsi_Cmnd *) );
extern int fd_mcs_biosparam( Disk *, struct block_device *, int * );
extern int fd_mcs_proc_info( char *, char **, off_t, int, int, int );
extern const char *fd_mcs_info(struct Scsi_Host *);
static int fd_mcs_detect(Scsi_Host_Template *);
static int fd_mcs_release(struct Scsi_Host *);
static int fd_mcs_command(Scsi_Cmnd *);
static int fd_mcs_abort(Scsi_Cmnd *);
static int fd_mcs_bus_reset(Scsi_Cmnd *);
static int fd_mcs_device_reset(Scsi_Cmnd *);
static int fd_mcs_host_reset(Scsi_Cmnd *);
static int fd_mcs_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
static int fd_mcs_biosparam(Disk *, struct block_device *, int *);
static int fd_mcs_proc_info(char *, char **, off_t, int, int, int);
static const char *fd_mcs_info(struct Scsi_Host *);
#define FD_MCS {\
proc_name: "fd_mcs", \
proc_info: fd_mcs_proc_info, \
detect: fd_mcs_detect, \
release: fd_mcs_release, \
info: fd_mcs_info, \
command: fd_mcs_command, \
queuecommand: fd_mcs_queue, \
abort: fd_mcs_abort, \
reset: fd_mcs_reset, \
bios_param: fd_mcs_biosparam, \
can_queue: 1, \
this_id: 7, \
sg_tablesize: 64, \
cmd_per_lun: 1, \
use_clustering: DISABLE_CLUSTERING }
#endif /* _FD_MCS_H */
proc_name: "fd_mcs", \
proc_info: fd_mcs_proc_info, \
detect: fd_mcs_detect, \
release: fd_mcs_release, \
info: fd_mcs_info, \
command: fd_mcs_command, \
queuecommand: fd_mcs_queue, \
eh_abort_handler: fd_mcs_abort, \
eh_bus_reset_handler: fd_mcs_bus_reset, \
eh_host_reset_handler: fd_mcs_host_reset, \
eh_device_reset_handler: fd_mcs_device_reset, \
bios_param: fd_mcs_biosparam, \
can_queue: 1, \
this_id: 7, \
sg_tablesize: 64, \
cmd_per_lun: 1, \
use_clustering: DISABLE_CLUSTERING \
}
#endif /* _FD_MCS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment