patch-1.3.13 linux/drivers/scsi/eata_dma.c
Next file: linux/drivers/scsi/eata_dma.h
Previous file: linux/drivers/scsi/ChangeLog
Back to the patch index
Back to the overall index
- Lines: 425
- Date:
Tue Jul 25 17:50:13 1995
- Orig file:
v1.3.12/linux/drivers/scsi/eata_dma.c
- Orig date:
Tue Jul 18 16:28:58 1995
diff -u --recursive --new-file v1.3.12/linux/drivers/scsi/eata_dma.c linux/drivers/scsi/eata_dma.c
@@ -48,7 +48,7 @@
* Thanks also to Greg Hosler who did a lot of testing and *
* found quite a number of bugs during the development. *
************************************************************
- * last change: 95/07/11 OS: Linux 1.3.9 *
+ * last change: 95/07/18 OS: Linux 1.3.10 *
************************************************************/
/* Look in eata_dma.h for configuration and revision information */
@@ -94,22 +94,27 @@
static struct eata_sp *status = 0; /* Statuspacket array */
static void *dma_scratch = 0;
-static uint internal_command_finished = TRUE;
-static unchar HBA_interpret = FALSE;
static u32 fake_int_base;
-static u32 fake_int_result;
+static int fake_int_result;
+static int fake_int_happened;
static ulong int_counter = 0;
static ulong queue_counter = 0;
-void eata_scsi_done (Scsi_Cmnd * SCpnt)
+void eata_scsi_done (Scsi_Cmnd * scmd)
{
+ scmd->request.dev = 0xfffe;
+
+ if (scmd->request.sem != NULL)
+ up(scmd->request.sem);
+
return;
}
void eata_fake_int_handler(s32 irq, struct pt_regs * regs)
{
fake_int_result = inb(fake_int_base + HA_RSTATUS);
+ fake_int_happened = TRUE;
DBG(DBG_INTR3, printk("eata_fake_int_handler called irq%d base %#x"
" res %#x\n", irq, fake_int_base, fake_int_result));
return;
@@ -141,11 +146,6 @@
}
#endif
-const char *eata_info(struct Scsi_Host *host)
-{
- static char *information = "EATA SCSI HBA Driver";
- return information;
-}
void eata_int_handler(int irq, struct pt_regs * regs)
{
@@ -172,7 +172,7 @@
sp=&SD(sh)->sp;
- cp = sp->ccb;
+ cp = sp->ccb; /* Has been passed thru, no conversion needed */
cmd = cp->cmd;
base = (uint) cmd->host->base;
@@ -290,15 +290,7 @@
#endif
cp->status = FREE; /* now we can release the slot */
-
- restore_flags(flags);
- if(cmd->scsi_done != eata_scsi_done) cmd->scsi_done(cmd);
- else {
- internal_command_finished = TRUE;
- HBA_interpret = FALSE;
- }
- save_flags(flags);
- cli();
+ cmd->scsi_done(cmd);
}
restore_flags(flags);
@@ -312,7 +304,8 @@
while (inb(base + HA_RAUXSTAT) & HA_ABUSY)
if (--loop == 0)
return(FALSE);
-
+
+ /* And now the address in nice little byte chunks */
outb( addr & 0x000000ff, base + HA_WDMAADDR);
outb((addr & 0x0000ff00) >> 8, base + HA_WDMAADDR + 1);
outb((addr & 0x00ff0000) >> 16, base + HA_WDMAADDR + 2);
@@ -321,7 +314,7 @@
return(TRUE);
}
-#if 0
+#if 0
inline int eata_send_immediate(u32 addr, u32 base, u8 cmnd, u8 cmnd2, u8 id,
u8 lun)
{
@@ -354,14 +347,7 @@
cli();
queue_counter++;
-
- if (done == (void *)eata_scsi_done) {
- if (internal_command_finished == TRUE)
- internal_command_finished = FALSE;
- else
- cmd->result = (DID_ERROR << 16) + QUEUE_FULL;
- }
-
+
hd = HD(cmd);
sh = cmd->host;
@@ -448,35 +434,37 @@
default:
cp->DataIn = TRUE; /* Input mode */
}
-
- if ((done == (void *) eata_scsi_done && HBA_interpret == TRUE)
- || cmd->target == sh->this_id)
+
+ /* FIXME: This will will have to be changed once the midlevel driver
+ * allows different HBA IDs on every channel.
+ */
+ if (cmd->target == sh->this_id)
cp->Interpret = TRUE; /* Interpret command */
-
+
if (cmd->use_sg) {
cp->scatter = TRUE; /* SG mode */
if (cp->sg_list == NULL) {
cp->sg_list = kmalloc(SG_SIZE_BIG*sizeof(struct eata_sg_list),
GFP_ATOMIC | GFP_DMA);
}
- cp->cp_dataDMA = htonl((ulong)cp->sg_list);
- if (cp->cp_dataDMA == 0)
+ if (cp->sg_list == NULL)
panic("eata_dma: Run out of DMA memory for SG lists !\n");
+ cp->cp_dataDMA = htonl(virt_to_bus(cp->sg_list));
cp->cp_datalen = htonl(cmd->use_sg * sizeof(struct eata_sg_list));
sl=(struct scatterlist *)cmd->request_buffer;
for(i = 0; i < cmd->use_sg; i++, sl++){
- cp->sg_list[i].data = htonl((u32) sl->address);
+ cp->sg_list[i].data = htonl(virt_to_bus(sl->address));
cp->sg_list[i].len = htonl((u32) sl->length);
}
} else {
cp->scatter = FALSE;
cp->cp_datalen = htonl(cmd->request_bufflen);
- cp->cp_dataDMA = htonl((u32)cmd->request_buffer);
+ cp->cp_dataDMA = htonl(virt_to_bus(cmd->request_buffer));
}
cp->Auto_Req_Sen = TRUE;
- cp->cp_reqDMA = htonl((u32) cmd->sense_buffer);
+ cp->cp_reqDMA = htonl(virt_to_bus(cmd->sense_buffer));
cp->reqlen = sizeof(cmd->sense_buffer);
cp->cp_id = cmd->target;
@@ -486,9 +474,9 @@
cp->cp_identify = TRUE;
memcpy(cp->cp_cdb, cmd->cmnd, cmd->cmd_len);
- cp->cp_statDMA = htonl((u32) &(hd->sp));
+ cp->cp_statDMA = htonl(virt_to_bus(&(hd->sp)));
- cp->cp_viraddr = cp;
+ cp->cp_viraddr = cp; /* This will be passed thru, so we don't need to convert it */
cp->cmd = cmd;
cmd->host_scribble = (char *)&hd->ccb[y];
@@ -496,16 +484,17 @@
cmd->result = DID_ERROR << 16;
printk("eata_queue target %d, pid %ld, HBA busy, returning DID_ERROR,"
" done.\n", cmd->target, cmd->pid);
+
restore_flags(flags);
- if(done != (void *)eata_scsi_done) done(cmd);
- return (0);
+ done(cmd);
+ return(0);
}
DBG(DBG_QUEUE,printk("Queued base %#.4x pid: %ld target: %x lun: %x "
"slot %d irq %d\n", (s32)sh->base, cmd->pid,
cmd->target, cmd->lun, y, sh->irq));
DBG(DBG_QUEUE && DBG_DELAY, DEL2(200));
restore_flags(flags);
- return (0);
+ return(0);
}
@@ -626,8 +615,8 @@
restore_flags(flags);
time = jiffies;
- while (jiffies < (time + (3 * HZ)) && limit++ < 10000000)
- /* nothing */;
+ while (jiffies < (time + (3 * HZ)) || limit++ < 10000000)
+ /* As time goes by... */;
save_flags(flags);
cli();
@@ -691,9 +680,12 @@
cp->DataIn = TRUE;
cp->Interpret = TRUE; /* Interpret command */
+ cp->cp_dispri = TRUE;
+ cp->cp_identify = TRUE;
- cp->cp_datalen = htonl(255);
- cp->cp_dataDMA = htonl((s32)buff);
+ cp->cp_datalen = htonl(56);
+ cp->cp_dataDMA = htonl(virt_to_bus(buff));
+ cp->cp_statDMA = htonl(virt_to_bus(sp));
cp->cp_viraddr = cp;
cp->cp_id = id;
@@ -703,23 +695,22 @@
cp->cp_cdb[1] = 0;
cp->cp_cdb[2] = 0;
cp->cp_cdb[3] = 0;
- cp->cp_cdb[4] = 255;
+ cp->cp_cdb[4] = 56;
cp->cp_cdb[5] = 0;
- cp->cp_statDMA = htonl((ulong) sp);
-
fake_int_base = base;
- fake_int_result = 0;
+ fake_int_result = FALSE;
+ fake_int_happened = FALSE;
eata_send_command((u32) cp, (u32) base, EATA_CMD_DMA_SEND_CP);
- i = jiffies + (3 * HZ) ;
- while (fake_int_result == FALSE && jiffies <= i)
+ i = jiffies + (3 * HZ);
+ while (fake_int_happened == FALSE && jiffies <= i)
barrier();
DBG(DBG_INTR3, printk("fake_int_result: %#x hbastat %#x scsistat %#x,"
" buff %p sp %p\n",
- fake_int_result, (u32) (sp->hba_stat & 0x7f),
+ fake_int_result, (u32) (sp->hba_stat /*& 0x7f*/),
(u32) sp->scsi_stat, buff, sp));
scsi_init_free((void *)cp, sizeof(struct eata_ccb));
@@ -730,7 +721,7 @@
inb((u32) (base) + HA_RSTATUS);
eata_send_command(0, base, EATA_CMD_RESET);
i = jiffies;
- while (jiffies < (i + (3 * HZ)) && limit++ < 10000000)
+ while (jiffies < (i + (3 * HZ)) && limit++ < 10000000)
barrier();
return (NULL);
} else
@@ -881,13 +872,17 @@
}
}
- if (bustype != IS_EISA)
+#if !(NEWSTUFF)
+ if (bustype != IS_EISA && bustype != IS_ISA)
+#endif
buff = get_board_data(base, gc->IRQ, gc->scsi_id[3]);
if (buff == NULL) {
- if (bustype == IS_EISA) {
+#if !(NEWSTUFF)
+ if (bustype == IS_EISA || bustype == IS_ISA) {
bugs = bugs || BROKEN_INQUIRY;
} else {
+#endif
if (gc->DMA_support == FALSE)
printk("HBA at %#.4x doesn't support DMA. Sorry\n", base);
else
@@ -901,7 +896,9 @@
if (gc->IRQ_TR == FALSE)
reg_IRQL[gc->IRQ] = FALSE;
return (FALSE);
+#if !(NEWSTUFF)
}
+#endif
}
if (gc->DMA_support == FALSE && buff != NULL)
@@ -916,7 +913,7 @@
if(ntohs(gc->queuesiz) == 0) {
gc->queuesiz = ntohs(64);
printk("Warning: Queue size has to be corrected. Assuming 64 queueslots\n"
- " This might be a PM2012B with a defective Firmware\n");
+ " This might be a PM2012B with a defective Firmware\n");
}
size = sizeof(hostdata) + ((sizeof(struct eata_ccb) + sizeof(long))
@@ -996,8 +993,8 @@
hd->bustype = bustype;
if(ntohl(gc->len) >= 0x22) {
- sh->max_id = gc->MAX_ID;
- sh->max_lun = gc->MAX_LUN;
+ sh->max_id = gc->MAX_ID + 1;
+ sh->max_lun = gc->MAX_LUN + 1;
} else {
sh->max_id = 8;
sh->max_lun = 8;
@@ -1015,14 +1012,15 @@
* SCSI midlevel code should support different HBA ids on every channel
*/
sh->this_id = gc->scsi_id[3];
- sh->can_queue = ntohs(gc->queuesiz) - 1; /* Keep one free for internals */
+ sh->can_queue = ntohs(gc->queuesiz);
- if (gc->OCS_enabled == TRUE)
+ if (gc->OCS_enabled == TRUE) {
if(hd->bustype != IS_ISA)
sh->cmd_per_lun = sh->can_queue/C_P_L_DIV;
else
- sh->cmd_per_lun = 8;
- else
+ sh->cmd_per_lun = 8; /* We artificially limit this to conserve memory,
+ * which would be needed for ISA bounce buffers */
+ } else
sh->cmd_per_lun = 1;
/* FIXME:
@@ -1175,14 +1173,15 @@
(u16 *) & com_adr))) {
if (!((com_adr & PCI_COMMAND_IO) &&
(com_adr & PCI_COMMAND_MASTER))) {
- printk("HBA has IO or BUSMASTER mode disabled\n");
+ printk("eata_dma: HBA has IO or BUSMASTER mode disabled\n");
continue;
}
} else
printk("eata_dma: error %x while reading "
"PCI_COMMAND\n", error);
} else
- printk("DEVICECLASSID %x didn't match\n", rev_device);
+ printk("eata_dma: DEVICECLASSID %x didn't match\n",
+ rev_device);
} else {
printk("eata_dma: error %x while reading PCI_CLASS_BASE\n",
error);
@@ -1219,10 +1218,8 @@
break;
}
}
- } else if ((base & 0x0fff) == 0x0c88) {
- x = (base >> 12) & 0x0f;
- EISAbases[x] = 0;
- }
+ } else if ((base & 0x0fff) == 0x0c88)
+ EISAbases[(base >> 12) & 0x0f] = 0;
continue; /* break; */
} else if (check_blink_state(base) == TRUE) {
printk("eata_dma: HBA is in BLINK state.\n"
@@ -1230,14 +1227,16 @@
}
}
}
- } else
+ } else {
printk("eata_dma: error %x while reading "
"PCI_BASE_ADDRESS_0\n", error);
+ }
}
- } else
+ } else {
printk("eata_dma: No BIOS32 extensions present. This driver release "
"still depends on it.\n"
" Skipping scan for PCI HBAs. \n");
+ }
#endif /* #ifndef CONFIG_PCI */
return;
}
@@ -1254,18 +1253,23 @@
status = scsi_init_malloc(512, GFP_ATOMIC | GFP_DMA);
dma_scratch = scsi_init_malloc(512, GFP_ATOMIC | GFP_DMA);
+ if(status == NULL || dma_scratch == NULL) {
+ printk("eata_dma: can't allocate enough memory to probe for hosts !\n");
+ return(0);
+ }
+
find_PCI(&gc, tpnt);
find_EISA(&gc, tpnt);
find_ISA(&gc, tpnt);
- for (i = 0; i <= MAXIRQ; i++)
- if (reg_IRQ[i]){
- free_irq(i);
+ for (i = 0; i <= MAXIRQ; i++) { /* Now that we know what we have, we */
+ if (reg_IRQ[i]){ /* exchange the interrupt handler which */
+ free_irq(i); /* we used for probing with the real one */
request_irq(i, (void *)(eata_int_handler), SA_INTERRUPT, "eata_dma");
}
-
+ }
HBA_ptr = first_HBA;
if (registered_HBAs != 0) {
@@ -1277,7 +1281,7 @@
printk("\nHBA no. Boardtype: Revis: EATA: Bus: BaseIO: IRQ: DMA: Ch: "
"ID: Pr: QS: SG: CPL:\n");
for (i = 1; i <= registered_HBAs; i++) {
- printk("scsi%-2d: %.10s v%s 2.0%c %s %#.4x %2d",
+ printk("scsi%-2d: %.10s v%s 2.0%c %s %#.4x %2d",
HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision,
SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P')?
"PCI ":(SD(HBA_ptr)->bustype == 'E')?"EISA":"ISA ",
@@ -1286,7 +1290,7 @@
printk(" %2x ", HBA_ptr->dma_channel);
else
printk(" %s", "BMST");
- printk(" %d %d %c %2d %2d %2d\n", SD(HBA_ptr)->channel,
+ printk(" %d %d %c %2d %2d %2d\n", SD(HBA_ptr)->channel,
HBA_ptr->this_id, (SD(HBA_ptr)->primary == TRUE)?'Y':'N',
HBA_ptr->can_queue, HBA_ptr->sg_tablesize, HBA_ptr->cmd_per_lun);
HBA_ptr = SD(HBA_ptr)->next;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this