Commit 11fc38f1 authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] ressurect the aha1740 driver

parent 7053dfab
...@@ -64,6 +64,8 @@ struct aha1740_hostdata { ...@@ -64,6 +64,8 @@ struct aha1740_hostdata {
#define HOSTDATA(host) ((struct aha1740_hostdata *) &host->hostdata) #define HOSTDATA(host) ((struct aha1740_hostdata *) &host->hostdata)
static spinlock_t aha1740_lock = SPIN_LOCK_UNLOCKED;
/* One for each IRQ level (9-15) */ /* One for each IRQ level (9-15) */
static struct Scsi_Host * aha_host[8] = {NULL, }; static struct Scsi_Host * aha_host[8] = {NULL, };
...@@ -258,7 +260,7 @@ void aha1740_intr_handle(int irq, void *dev_id, struct pt_regs * regs) ...@@ -258,7 +260,7 @@ void aha1740_intr_handle(int irq, void *dev_id, struct pt_regs * regs)
continue; continue;
} }
if (SCtmp->host_scribble) if (SCtmp->host_scribble)
scsi_free(SCtmp->host_scribble, 512); kfree(SCtmp->host_scribble);
/* Fetch the sense data, and tuck it away, in the required slot. /* Fetch the sense data, and tuck it away, in the required slot.
The Adaptec automatically fetches it, and there is no The Adaptec automatically fetches it, and there is no
guarantee that we will still have it in the cdb when we come guarantee that we will still have it in the cdb when we come
...@@ -346,8 +348,8 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -346,8 +348,8 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
#endif #endif
/* locate an available ecb */ /* locate an available ecb */
save_flags(flags);
cli(); spin_lock_irqsave(&aha1740_lock, flags);
ecbno = host->last_ecb_used + 1; /* An optimization */ ecbno = host->last_ecb_used + 1; /* An optimization */
if (ecbno >= AHA1740_ECBS) if (ecbno >= AHA1740_ECBS)
ecbno = 0; ecbno = 0;
...@@ -366,7 +368,7 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -366,7 +368,7 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
doubles as reserved flag */ doubles as reserved flag */
host->last_ecb_used = ecbno; host->last_ecb_used = ecbno;
restore_flags(flags); spin_unlock_irqrestore(&aha1740_lock, flags);
#ifdef DEBUG #ifdef DEBUG
printk("Sending command (%d %x)...", ecbno, done); printk("Sending command (%d %x)...", ecbno, done);
...@@ -390,14 +392,18 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -390,14 +392,18 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
DEB(unsigned char * ptr); DEB(unsigned char * ptr);
host->ecb[ecbno].sg = 1; /* SCSI Initiator Command w/scatter-gather*/ host->ecb[ecbno].sg = 1; /* SCSI Initiator Command w/scatter-gather*/
SCpnt->host_scribble = (unsigned char *) scsi_malloc(512); SCpnt->host_scribble = (unsigned char *)kmalloc(512, GFP_KERNEL);
if(SCpnt->host_scribble == NULL)
{
printk(KERN_WARNING "aha1740: out of memory in queuecommand!\n");
return 1;
}
sgpnt = (struct scatterlist *) SCpnt->request_buffer; sgpnt = (struct scatterlist *) SCpnt->request_buffer;
cptr = (struct aha1740_chain *) SCpnt->host_scribble; cptr = (struct aha1740_chain *) SCpnt->host_scribble;
if (cptr == NULL) panic("aha1740.c: unable to allocate DMA memory\n");
for(i=0; i<SCpnt->use_sg; i++) for(i=0; i<SCpnt->use_sg; i++)
{ {
cptr[i].datalen = sgpnt[i].length; cptr[i].datalen = sgpnt[i].length;
cptr[i].dataptr = isa_virt_to_bus(sgpnt[i].address); cptr[i].dataptr = isa_virt_to_bus(page_address(sgpnt[i].page) + sgpnt[i].offset);
} }
host->ecb[ecbno].datalen = SCpnt->use_sg * sizeof(struct aha1740_chain); host->ecb[ecbno].datalen = SCpnt->use_sg * sizeof(struct aha1740_chain);
host->ecb[ecbno].dataptr = isa_virt_to_bus(cptr); host->ecb[ecbno].dataptr = isa_virt_to_bus(cptr);
...@@ -448,13 +454,12 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -448,13 +454,12 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
int loopcnt; int loopcnt;
unsigned int base = SCpnt->host->io_port; unsigned int base = SCpnt->host->io_port;
DEB(printk("aha1740[%d] critical section\n",ecbno)); DEB(printk("aha1740[%d] critical section\n",ecbno));
save_flags(flags);
cli(); spin_lock_irqsave(&aha1740_lock, flags);
for (loopcnt = 0; ; loopcnt++) { for (loopcnt = 0; ; loopcnt++) {
if (inb(G2STAT(base)) & G2STAT_MBXOUT) break; if (inb(G2STAT(base)) & G2STAT_MBXOUT) break;
if (loopcnt == LOOPCNT_WARN) { if (loopcnt == LOOPCNT_WARN) {
printk("aha1740[%d]_mbxout wait!\n",ecbno); printk("aha1740[%d]_mbxout wait!\n",ecbno);
cli(); /* printk may have done a sti()! */
} }
if (loopcnt == LOOPCNT_MAX) if (loopcnt == LOOPCNT_MAX)
panic("aha1740.c: mbxout busy!\n"); panic("aha1740.c: mbxout busy!\n");
...@@ -464,13 +469,12 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -464,13 +469,12 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
if (! (inb(G2STAT(base)) & G2STAT_BUSY)) break; if (! (inb(G2STAT(base)) & G2STAT_BUSY)) break;
if (loopcnt == LOOPCNT_WARN) { if (loopcnt == LOOPCNT_WARN) {
printk("aha1740[%d]_attn wait!\n",ecbno); printk("aha1740[%d]_attn wait!\n",ecbno);
cli();
} }
if (loopcnt == LOOPCNT_MAX) if (loopcnt == LOOPCNT_MAX)
panic("aha1740.c: attn wait failed!\n"); panic("aha1740.c: attn wait failed!\n");
} }
outb(ATTN_START | (target & 7), ATTN(base)); /* Start it up */ outb(ATTN_START | (target & 7), ATTN(base)); /* Start it up */
restore_flags(flags); spin_unlock_irqrestore(&aha1740_lock, flags);
DEB(printk("aha1740[%d] request queued.\n",ecbno)); DEB(printk("aha1740[%d] request queued.\n",ecbno));
} }
else else
...@@ -488,7 +492,10 @@ int aha1740_command(Scsi_Cmnd * SCpnt) ...@@ -488,7 +492,10 @@ int aha1740_command(Scsi_Cmnd * SCpnt)
aha1740_queuecommand(SCpnt, internal_done); aha1740_queuecommand(SCpnt, internal_done);
SCpnt->SCp.Status = 0; SCpnt->SCp.Status = 0;
while (!SCpnt->SCp.Status) while (!SCpnt->SCp.Status)
{
cpu_relax();
barrier(); barrier();
}
return SCpnt->result; return SCpnt->result;
} }
......
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