patch-1.3.99 linux/drivers/scsi/eata_dma.c
Next file: linux/drivers/scsi/eata_dma.h
Previous file: linux/drivers/scsi/aic7xxx.c
Back to the patch index
Back to the overall index
- Lines: 1229
- Date:
Mon May 6 07:34:20 1996
- Orig file:
v1.3.98/linux/drivers/scsi/eata_dma.c
- Orig date:
Sun May 5 08:52:00 1996
diff -u --recursive --new-file v1.3.98/linux/drivers/scsi/eata_dma.c linux/drivers/scsi/eata_dma.c
@@ -8,8 +8,15 @@
* *
* The driver currently: *
* -supports all ISA based EATA-DMA boards *
+ * like PM2011, PM2021, PM2041, PM3021 *
* -supports all EISA based EATA-DMA boards *
+ * like PM2012B, PM2022, PM2122, PM2322, PM2042, *
+ * PM3122, PM3222, PM3332 *
* -supports all PCI based EATA-DMA boards *
+ * like PM2024, PM2124, PM2044, PM2144, PM3224, *
+ * PM3334 *
+ * -supports the Wide, Ultra Wide and Differential *
+ * versions of the boards *
* -supports multiple HBAs with & without IRQ sharing *
* -supports all SCSI channels on multi channel boards *
* -needs identical IDs on all channels of a HBA *
@@ -19,8 +26,9 @@
* -provides rudimentary latency measurement *
* possibilities via /proc/scsi/eata_dma/<hostnum> *
* *
- * (c)1993,94,95 Michael Neuffer *
- * neuffer@goofy.zdv.uni-mainz.de *
+ * (c)1993-96 Michael Neuffer *
+ * mike@i-Connect.Net *
+ * neuffer@mail.uni-mainz.de *
* *
* This program is free software; you can redistribute it *
* and/or modify it under the terms of the GNU General *
@@ -45,10 +53,11 @@
* very helpful and tried to give me all the infos and *
* support I need. *
* *
- * Thanks also to Greg Hosler who did a lot of testing and *
- * found quite a number of bugs during the development. *
+ * Thanks also to Simon Shapiro, Greg Hosler and Mike *
+ * Jagdis who did a lot of testing and found quite a number *
+ * of bugs during the development. *
************************************************************
- * last change: 95/04/27 OS: Linux 1.3.95 *
+ * last change: 95/05/05 OS: Linux 1.3.98 *
************************************************************/
/* Look in eata_dma.h for configuration and revision information */
@@ -63,6 +72,7 @@
#include <linux/bios32.h>
#include <linux/pci.h>
#include <linux/proc_fs.h>
+#include <linux/delay.h>
#include <asm/byteorder.h>
#include <asm/types.h>
#include <asm/io.h>
@@ -132,7 +142,7 @@
else reg_IRQ[sh->irq]--;
scsi_init_free((void *)status, 512);
- scsi_init_free((void *)dma_scratch, 512);
+ scsi_init_free((void *)dma_scratch - 4, 1024);
for (i = 0; i < sh->can_queue; i++){ /* Free all SG arrays */
if(SD(sh)->ccb[i].sg_list != NULL)
scsi_init_free((void *) SD(sh)->ccb[i].sg_list,
@@ -149,12 +159,89 @@
#endif
+inline void eata_latency_in(struct eata_ccb *cp, hostdata *hd)
+{
+ uint time;
+ time = jiffies - cp->timestamp;
+ if(hd->all_lat[1] > time)
+ hd->all_lat[1] = time;
+ if(hd->all_lat[2] < time)
+ hd->all_lat[2] = time;
+ hd->all_lat[3] += time;
+ hd->all_lat[0]++;
+ if((cp->rw_latency) == WRITE) { /* was WRITE */
+ if(hd->writes_lat[cp->sizeindex][1] > time)
+ hd->writes_lat[cp->sizeindex][1] = time;
+ if(hd->writes_lat[cp->sizeindex][2] < time)
+ hd->writes_lat[cp->sizeindex][2] = time;
+ hd->writes_lat[cp->sizeindex][3] += time;
+ hd->writes_lat[cp->sizeindex][0]++;
+ } else if((cp->rw_latency) == READ) {
+ if(hd->reads_lat[cp->sizeindex][1] > time)
+ hd->reads_lat[cp->sizeindex][1] = time;
+ if(hd->reads_lat[cp->sizeindex][2] < time)
+ hd->reads_lat[cp->sizeindex][2] = time;
+ hd->reads_lat[cp->sizeindex][3] += time;
+ hd->reads_lat[cp->sizeindex][0]++;
+ }
+}
+
+inline void eata_latency_out(struct eata_ccb *cp, Scsi_Cmnd *cmd)
+{
+ int x, z;
+ short *sho;
+ long *lon;
+ x = 0; /* just to keep GCC quiet */
+ cp->timestamp = jiffies; /* For latency measurements */
+ switch(cmd->cmnd[0]) {
+ case WRITE_6:
+ x = cmd->cmnd[4]/2;
+ cp->rw_latency = WRITE;
+ break;
+ case READ_6:
+ x = cmd->cmnd[4]/2;
+ cp->rw_latency = READ;
+ break;
+ case WRITE_10:
+ sho = (short *) &cmd->cmnd[7];
+ x = ntohs(*sho)/2;
+ cp->rw_latency = WRITE;
+ break;
+ case READ_10:
+ sho = (short *) &cmd->cmnd[7];
+ x = ntohs(*sho)/2;
+ cp->rw_latency = READ;
+ break;
+ case WRITE_12:
+ lon = (long *) &cmd->cmnd[6];
+ x = ntohl(*lon)/2;
+ cp->rw_latency = WRITE;
+ break;
+ case READ_12:
+ lon = (long *) &cmd->cmnd[6];
+ x = ntohl(*lon)/2;
+ cp->rw_latency = READ;
+ break;
+ default:
+ cp->rw_latency = OTHER;
+ break;
+ }
+ if (cmd->cmnd[0] == WRITE_6 || cmd->cmnd[0] == WRITE_10 ||
+ cmd->cmnd[0] == WRITE_12 || cmd->cmnd[0] == READ_6 ||
+ cmd->cmnd[0] == READ_10 || cmd->cmnd[0] == READ_12) {
+ for(z = 0; (x > (1 << z)) && (z <= 11); z++)
+ /* nothing */;
+ cp->sizeindex = z;
+ }
+}
+
+
void eata_int_handler(int irq, void *dev_id, struct pt_regs * regs)
{
uint i, result = 0;
uint hba_stat, scsi_stat, eata_stat;
Scsi_Cmnd *cmd;
- struct eata_ccb *cp;
+ struct eata_ccb *ccb;
struct eata_sp *sp;
uint base;
ulong flags;
@@ -173,16 +260,16 @@
int_counter++;
sp = &SD(sh)->sp;
- cp = sp->ccb;
+ ccb = sp->ccb;
- if(cp == NULL) {
+ if(ccb == NULL) {
eata_stat = inb((uint)sh->base + HA_RSTATUS);
printk("eata_dma: int_handler, Spurious IRQ %d "
"received. CCB pointer not set.\n", irq);
break;
}
- cmd = cp->cmd;
+ cmd = ccb->cmd;
base = (uint) cmd->host->base;
hba_stat = sp->hba_stat;
@@ -190,23 +277,27 @@
if (sp->EOC == FALSE) {
eata_stat = inb(base + HA_RSTATUS);
- printk("eata_dma: int_handler, board: %x cmd %lx returned "
- "unfinished.\nEATA: %x HBA: %x SCSI: %x spadr %lx "
- "spadrirq %lx, irq%d\n", base, (long)cp, eata_stat,
- hba_stat, scsi_stat,(long)&status, (long)&status[irq],
- irq);
- DBG(DBG_DELAY, DEL2(800));
+ printk(KERN_WARNING "eata_dma: int_handler, board: %x cmd %lx "
+ "returned unfinished.\n"
+ "EATA: %x HBA: %x SCSI: %x spadr %lx spadrirq %lx, "
+ "irq%d\n", base, (long)ccb, eata_stat, hba_stat,
+ scsi_stat,(long)&status, (long)&status[irq], irq);
+ cmd->result = DID_ERROR << 16;
+ ccb->status = FREE;
+ cmd->scsi_done(cmd);
break;
}
- if (cp->status == LOCKED) {
- cp->status = FREE;
+ if (ccb->status == LOCKED) {
+ ccb->status = FREE;
eata_stat = inb(base + HA_RSTATUS);
printk("eata_dma: int_handler, freeing locked queueslot\n");
- DBG(DBG_INTR && DBG_DELAY, DEL2(800));
+ DBG(DBG_INTR && DBG_DELAY, DELAY(1));
break;
}
+ sp->EOC = FALSE; /* Clean out this flag */
+
eata_stat = inb(base + HA_RSTATUS);
DBG(DBG_INTR, printk("IRQ %d received, base %#.4x, pid %ld, "
"target: %x, lun: %x, ea_s: %#.2x, hba_s: "
@@ -215,52 +306,22 @@
switch (hba_stat) {
case HA_NO_ERROR: /* NO Error */
- if (scsi_stat == CONDITION_GOOD
- && cmd->device->type == TYPE_DISK
- && (HD(cmd)->t_state[cp->cp_channel][cp->cp_id] == RESET))
- result = DID_BUS_BUSY << 16;
- else if (scsi_stat == GOOD) {
- HD(cmd)->t_state[cp->cp_channel][cp->cp_id] = OK;
- if(HD(cmd)->do_latency == TRUE && cp->timestamp) {
- uint time;
- time = jiffies - cp->timestamp;
- if((cp->rw_latency) == TRUE) { /* was WRITE */
- if(HD(cmd)->writes_lat[cp->sizeindex][1] > time)
- HD(cmd)->writes_lat[cp->sizeindex][1] = time;
- if(HD(cmd)->writes_lat[cp->sizeindex][2] < time)
- HD(cmd)->writes_lat[cp->sizeindex][2] = time;
- HD(cmd)->writes_lat[cp->sizeindex][3] += time;
- HD(cmd)->writes_lat[cp->sizeindex][0]++;
- } else {
- if(HD(cmd)->reads_lat[cp->sizeindex][1] > time)
- HD(cmd)->reads_lat[cp->sizeindex][1] = time;
- if(HD(cmd)->reads_lat[cp->sizeindex][2] < time)
- HD(cmd)->reads_lat[cp->sizeindex][2] = time;
- HD(cmd)->reads_lat[cp->sizeindex][3] += time;
- HD(cmd)->reads_lat[cp->sizeindex][0]++;
- }
- }
- }
- else if (scsi_stat == CHECK_CONDITION
- && cmd->device->type == TYPE_DISK
- && (cmd->sense_buffer[2] & 0xf) == RECOVERED_ERROR)
- result = DID_BUS_BUSY << 16;
- else
- result = DID_OK << 16;
- HD(cmd)->t_timeout[cp->cp_channel][cp->cp_id] = OK;
+ HD(cmd)->t_state[ccb->cp_channel][ccb->cp_id] = OK;
+ if(HD(cmd)->do_latency == TRUE && ccb->timestamp)
+ eata_latency_in(ccb, HD(cmd));
+ result = DID_OK << 16;
+ HD(cmd)->t_timeout[ccb->cp_channel][ccb->cp_id] = OK;
break;
case HA_ERR_SEL_TO: /* Selection Timeout */
- result = DID_BAD_TARGET << 16;
- break;
case HA_ERR_CMD_TO: /* Command Timeout */
- if (HD(cmd)->t_timeout[cp->cp_channel][cp->cp_id] > 1)
- result = DID_ERROR << 16;
- else {
- result = DID_TIME_OUT << 16;
- HD(cmd)->t_timeout[cp->cp_channel][cp->cp_id]++;
- }
+ result = DID_TIME_OUT << 16;
+ break;
+ case HA_BUS_RESET: /* SCSI Bus Reset Received */
+ result = DID_RESET << 16;
+ DBG(DBG_STATUS, printk(KERN_WARNING "scsi%d: BUS RESET "
+ "received on cmd %ld\n",
+ HD(cmd)->HBA_number, cmd->pid));
break;
- case HA_ERR_RESET: /* SCSI Bus Reset Received */
case HA_INIT_POWERUP: /* Initial Controller Power-up */
if (cmd->device->type != TYPE_TAPE)
result = DID_BUS_BUSY << 16;
@@ -268,15 +329,39 @@
result = DID_ERROR << 16;
for (i = 0; i < MAXTARGET; i++)
- HD(cmd)->t_state[cp->cp_channel][i] = RESET;
+ HD(cmd)->t_state[ccb->cp_channel][i] = RESET;
+ DBG(DBG_STATUS, printk(KERN_DEBUG "scsi%d: cmd pid %ld "
+ "returned with INIT_POWERUP\n",
+ HD(cmd)->HBA_number, cmd->pid));
+ break;
+ case HA_CP_ABORT_NA:
+ case HA_CP_ABORTED:
+ result = DID_ABORT << 16;
+ DBG(DBG_STATUS, printk(KERN_WARNING "scsi%d: aborted cmd "
+ "returned\n", HD(cmd)->HBA_number));
+ break;
+ case HA_CP_RESET_NA:
+ case HA_CP_RESET:
+ HD(cmd)->t_state[cmd->channel][cmd->target] = OK;
+ HD(cmd)->resetlevel[cmd->channel] = 0;
+ result = DID_RESET << 16;
+ DBG(DBG_STATUS, printk(KERN_WARNING "scsi%d: reseted cmd "
+ "pid %ldreturned\n",
+ HD(cmd)->HBA_number, cmd->pid));
+ case HA_SCSI_HUNG: /* SCSI Hung */
+ printk(KERN_ERR "scsi%d: SCSI hung\n", HD(cmd)->HBA_number);
+ result = DID_ERROR << 16;
+ break;
+ case HA_RSENSE_FAIL: /* Auto Request-Sense Failed */
+ DBG(DBG_STATUS, printk(KERN_ERR "scsi%d: Auto Request Sense "
+ "Failed\n", HD(cmd)->HBA_number));
+ result = DID_ERROR << 16;
break;
case HA_UNX_BUSPHASE: /* Unexpected Bus Phase */
case HA_UNX_BUS_FREE: /* Unexpected Bus Free */
case HA_BUS_PARITY: /* Bus Parity Error */
- case HA_SCSI_HUNG: /* SCSI Hung */
case HA_UNX_MSGRJCT: /* Unexpected Message Reject */
case HA_RESET_STUCK: /* SCSI Bus Reset Stuck */
- case HA_RSENSE_FAIL: /* Auto Request-Sense Failed */
case HA_PARITY_ERR: /* Controller Ram Parity */
default:
result = DID_ERROR << 16;
@@ -293,10 +378,10 @@
cmd->device->channel, cmd->device->id, cmd->device->lun,
cmd->pid, eata_stat, hba_stat, scsi_stat,
cmd->sense_buffer[2] & 0xf, cmd->result);
- DBG(DBG_INTR&&DBG_DELAY,DEL2(800));
+ DBG(DBG_INTR&&DBG_DELAY,DELAY(1));
#endif
- cp->status = FREE; /* now we can release the slot */
+ ccb->status = FREE; /* now we can release the slot */
cmd->scsi_done(cmd);
}
}
@@ -314,41 +399,55 @@
return(FALSE);
/* And now the address in nice little byte chunks */
+#ifdef __LITTLE_ENDIAN
outb( addr & 0x000000ff, base + HA_WDMAADDR);
outb((addr & 0x0000ff00) >> 8, base + HA_WDMAADDR + 1);
outb((addr & 0x00ff0000) >> 16, base + HA_WDMAADDR + 2);
outb((addr & 0xff000000) >> 24, base + HA_WDMAADDR + 3);
+#else
+ outb((addr & 0xff000000) >> 24, base + HA_WDMAADDR);
+ outb((addr & 0x00ff0000) >> 16, base + HA_WDMAADDR + 1);
+ outb((addr & 0x0000ff00) >> 8, base + HA_WDMAADDR + 2);
+ outb((addr & 0x000000ff), base + HA_WDMAADDR + 3);
+#endif
outb(command, base + HA_WCOMMAND);
return(TRUE);
}
-#if 0
-inline int eata_send_immediate(u32 addr, u32 base, u8 cmnd, u8 cmnd2, u8 id,
- u8 lun)
+inline int eata_send_immediate(u32 base, u32 addr, u8 ifc, u8 code, u8 code2)
{
+ outb(0x0, base + HA_WDMAADDR - 1);
if(addr){
- outb( addr & 0x000000ff, base + HA_WDMAADDR);
- outb((addr & 0x0000ff00) >> 8, base + HA_WDMAADDR + 1);
+#ifdef __LITTLE_ENDIAN
+ outb( addr & 0x000000ff, base + HA_WDMAADDR);
+ outb((addr & 0x0000ff00) >> 8, base + HA_WDMAADDR + 1);
outb((addr & 0x00ff0000) >> 16, base + HA_WDMAADDR + 2);
outb((addr & 0xff000000) >> 24, base + HA_WDMAADDR + 3);
+#else
+ outb((addr & 0xff000000) >> 24, base + HA_WDMAADDR);
+ outb((addr & 0x00ff0000) >> 16, base + HA_WDMAADDR + 1);
+ outb((addr & 0x0000ff00) >> 8, base + HA_WDMAADDR + 2);
+ outb((addr & 0x000000ff), base + HA_WDMAADDR + 3);
+#endif
} else {
- outb(id, base + HA_WSUBCODE);
- outb(lun, base + HA_WSUBLUN);
+ outb(0x0, base + HA_WDMAADDR);
+ outb(0x0, base + HA_WDMAADDR + 1);
+ outb(code2, base + HA_WCODE2);
+ outb(code, base + HA_WCODE);
}
- outb(cmnd2, base + HA_WCOMMAND2);
- outb(cmnd, base + HA_WCOMMAND);
+ outb(ifc, base + HA_WIFC);
+ outb(EATA_CMD_IMMEDIATE, base + HA_WCOMMAND);
return(TRUE);
}
-#endif
int eata_queue(Scsi_Cmnd * cmd, void (* done) (Scsi_Cmnd *))
{
unsigned int i, x, y;
- u32 flags;
+ ulong flags;
hostdata *hd;
struct Scsi_Host *sh;
- struct eata_ccb *cp;
+ struct eata_ccb *ccb;
struct scatterlist *sl;
save_flags(flags);
@@ -359,6 +458,15 @@
hd = HD(cmd);
sh = cmd->host;
+#if 1
+ if (cmd->cmnd[0] == REQUEST_SENSE && cmd->sense_buffer[0] != 0) {
+ DBG(DBG_REQSENSE, printk(KERN_DEBUG "Tried to REQUEST SENSE\n"));
+ cmd->result = DID_OK << 16;
+ done(cmd);
+ return(0);
+ }
+#endif
+
/* check for free slot */
for (y = hd->last_ccb + 1, x = 0; x < sh->can_queue; x++, y++) {
if (y >= sh->can_queue)
@@ -378,52 +486,19 @@
restore_flags(flags);
return(0);
}
- cp = &hd->ccb[y];
+ ccb = &hd->ccb[y];
- memset(cp, 0, sizeof(struct eata_ccb) - sizeof(struct eata_sg_list *));
+ memset(ccb, 0, sizeof(struct eata_ccb) - sizeof(struct eata_sg_list *));
- cp->status = USED; /* claim free slot */
+ ccb->status = USED; /* claim free slot */
DBG(DBG_QUEUE, printk("eata_queue pid %ld, target: %x, lun: %x, y %d\n",
cmd->pid, cmd->target, cmd->lun, y));
- DBG(DBG_QUEUE && DBG_DELAY, DEL2(250));
+ DBG(DBG_QUEUE && DBG_DELAY, DELAY(1));
- if(hd->do_latency == TRUE) {
- int x, z;
- short *sho;
- long *lon;
- x = 0; /* just to keep GCC quiet */
- if (cmd->cmnd[0] == WRITE_6 || cmd->cmnd[0] == WRITE_10 ||
- cmd->cmnd[0] == WRITE_12 || cmd->cmnd[0] == READ_6 ||
- cmd->cmnd[0] == READ_10 || cmd->cmnd[0] == READ_12) {
-
- cp->timestamp = jiffies; /* For latency measurements */
- switch(cmd->cmnd[0]) {
- case WRITE_6:
- case READ_6:
- x = cmd->cmnd[4]/2;
- break;
- case WRITE_10:
- case READ_10:
- sho = (short *) &cmd->cmnd[7];
- x = ntohs(*sho)/2;
- break;
- case WRITE_12:
- case READ_12:
- lon = (long *) &cmd->cmnd[6];
- x = ntohl(*lon)/2;
- break;
- }
+ if(hd->do_latency == TRUE)
+ eata_latency_out(ccb, cmd);
- for(z = 0; (x > (1 << z)) && (z <= 11); z++)
- /* nothing */;
- cp->sizeindex = z;
- if (cmd->cmnd[0] == WRITE_6 || cmd->cmnd[0] == WRITE_10 ||
- cmd->cmnd[0] == WRITE_12){
- cp->rw_latency = TRUE;
- }
- }
- }
cmd->scsi_done = (void *)done;
switch (cmd->cmnd[0]) {
@@ -438,73 +513,73 @@
case WRITE_12: case WRITE_VERIFY_12: case SET_WINDOW:
case MEDIUM_SCAN: case SEND_VOLUME_TAG:
case 0xea: /* alternate number for WRITE LONG */
- cp->DataOut = TRUE; /* Output mode */
+ ccb->DataOut = TRUE; /* Output mode */
break;
case TEST_UNIT_READY:
default:
- cp->DataIn = TRUE; /* Input mode */
+ ccb->DataIn = TRUE; /* Input mode */
}
/* 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 */
+ ccb->Interpret = TRUE; /* Interpret command */
if (cmd->use_sg) {
- cp->scatter = TRUE; /* SG mode */
- if (cp->sg_list == NULL) {
- cp->sg_list = kmalloc(sh->sg_tablesize * sizeof(struct eata_sg_list),
+ ccb->scatter = TRUE; /* SG mode */
+ if (ccb->sg_list == NULL) {
+ ccb->sg_list = kmalloc(sh->sg_tablesize * sizeof(struct eata_sg_list),
GFP_ATOMIC | GFP_DMA);
}
- if (cp->sg_list == NULL)
+ if (ccb->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));
+ ccb->cp_dataDMA = htonl(virt_to_bus(ccb->sg_list));
- cp->cp_datalen = htonl(cmd->use_sg * sizeof(struct eata_sg_list));
+ ccb->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(virt_to_bus(sl->address));
- cp->sg_list[i].len = htonl((u32) sl->length);
+ ccb->sg_list[i].data = htonl(virt_to_bus(sl->address));
+ ccb->sg_list[i].len = htonl((u32) sl->length);
}
} else {
- cp->scatter = FALSE;
- cp->cp_datalen = htonl(cmd->request_bufflen);
- cp->cp_dataDMA = htonl(virt_to_bus(cmd->request_buffer));
+ ccb->scatter = FALSE;
+ ccb->cp_datalen = htonl(cmd->request_bufflen);
+ ccb->cp_dataDMA = htonl(virt_to_bus(cmd->request_buffer));
}
- cp->Auto_Req_Sen = TRUE;
- cp->cp_reqDMA = htonl(virt_to_bus(cmd->sense_buffer));
- cp->reqlen = sizeof(cmd->sense_buffer);
-
- cp->cp_id = cmd->target;
- cp->cp_channel = cmd->channel;
- cp->cp_lun = cmd->lun;
- cp->cp_dispri = TRUE;
- cp->cp_identify = TRUE;
- memcpy(cp->cp_cdb, cmd->cmnd, cmd->cmd_len);
+ ccb->Auto_Req_Sen = TRUE;
+ ccb->cp_reqDMA = htonl(virt_to_bus(cmd->sense_buffer));
+ ccb->reqlen = sizeof(cmd->sense_buffer);
+
+ ccb->cp_id = cmd->target;
+ ccb->cp_channel = cmd->channel;
+ ccb->cp_lun = cmd->lun;
+ ccb->cp_dispri = TRUE;
+ ccb->cp_identify = TRUE;
+ memcpy(ccb->cp_cdb, cmd->cmnd, cmd->cmd_len);
- cp->cp_statDMA = htonl(virt_to_bus(&(hd->sp)));
+ ccb->cp_statDMA = htonl(virt_to_bus(&(hd->sp)));
- cp->cp_viraddr = cp; /* This will be passed thru, so we don't need to
+ ccb->cp_viraddr = ccb; /* This will be passed thru, so we don't need to
* convert it */
- cp->cmd = cmd;
+ ccb->cmd = cmd;
cmd->host_scribble = (char *)&hd->ccb[y];
- if(eata_send_command((u32) cp, (u32) sh->base, EATA_CMD_DMA_SEND_CP) == FALSE) {
+ if(eata_send_command((u32) ccb, (u32) sh->base, EATA_CMD_DMA_SEND_CP) == FALSE) {
cmd->result = DID_BUS_BUSY << 16;
DBG(DBG_QUEUE && DBG_ABNORM,
printk("eata_queue target %d, pid %ld, HBA busy, "
"returning DID_BUS_BUSY\n",cmd->target, cmd->pid));
done(cmd);
- cp->status = FREE;
+ ccb->status = FREE;
restore_flags(flags);
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));
+ DBG(DBG_QUEUE && DBG_DELAY, DELAY(1));
restore_flags(flags);
return(0);
}
@@ -521,26 +596,26 @@
DBG(DBG_ABNORM, printk("eata_abort called pid: %ld target: %x lun: %x"
" reason %x\n", cmd->pid, cmd->target, cmd->lun,
cmd->abort_reason));
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
+ DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
while (inb((u32)(cmd->host->base) + HA_RAUXSTAT) & HA_ABUSY) {
if (--loop == 0) {
printk("eata_dma: abort, timeout error.\n");
+ DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
restore_flags(flags);
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
return (SCSI_ABORT_ERROR);
}
}
if (CD(cmd)->status == RESET) {
- restore_flags(flags);
printk("eata_dma: abort, command reset error.\n");
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
+ DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
+ restore_flags(flags);
return (SCSI_ABORT_ERROR);
}
if (CD(cmd)->status == LOCKED) {
- restore_flags(flags);
DBG(DBG_ABNORM, printk("eata_dma: abort, queue slot locked.\n"));
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
+ DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
+ restore_flags(flags);
return (SCSI_ABORT_NOT_RUNNING);
}
if (CD(cmd)->status == USED) {
@@ -557,11 +632,11 @@
panic("eata_dma: abort: invalid slot status\n");
}
-int eata_reset(Scsi_Cmnd * cmd, int resetflags)
+int eata_reset(Scsi_Cmnd * cmd, unsigned int resetflags)
{
ushort x, z;
- ulong time, limit = 0;
- ulong loop = R_LIMIT;
+ ulong limit = 0;
+ ulong loop = loops_per_sec / 3;
ulong flags;
unchar success = FALSE;
Scsi_Cmnd *sp;
@@ -576,7 +651,7 @@
if (HD(cmd)->state == RESET) {
printk("eata_reset: exit, already in reset.\n");
restore_flags(flags);
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
+ DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
return (SCSI_RESET_ERROR);
}
@@ -584,7 +659,7 @@
if (--loop == 0) {
printk("eata_reset: exit, timeout error.\n");
restore_flags(flags);
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
+ DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
return (SCSI_RESET_ERROR);
}
@@ -602,17 +677,17 @@
if (HD(cmd)->ccb[x].status == LOCKED) {
HD(cmd)->ccb[x].status = FREE;
printk("eata_reset: locked slot %d forced free.\n", x);
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
+ DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
continue;
}
sp = HD(cmd)->ccb[x].cmd;
HD(cmd)->ccb[x].status = RESET;
printk("eata_reset: slot %d in reset, pid %ld.\n", x, sp->pid);
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
+ DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
if (sp == NULL)
panic("eata_reset: slot %d, sp==NULL.\n", x);
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
+ DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
if (sp == cmd)
success = TRUE;
@@ -624,19 +699,12 @@
DBG(DBG_ABNORM, printk("eata_reset: board reset done, enabling interrupts.\n"));
HD(cmd)->state = RESET;
-
- restore_flags(flags);
-
- time = jiffies;
- while (jiffies < (time + (3 * HZ)) || limit++ < 10000000)
- /* As time goes by... */;
-
- save_flags(flags);
- cli();
+
+ DELAY(1);
DBG(DBG_ABNORM, printk("eata_reset: interrupts disabled, loops %ld.\n",
limit));
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
+ DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
for (x = 0; x < cmd->host->can_queue; x++) {
@@ -652,10 +720,9 @@
printk("eata_reset: slot %d locked, DID_RESET, pid %ld done.\n",
x, sp->pid);
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
- restore_flags(flags);
+ DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
+
sp->scsi_done(sp);
- cli();
}
HD(cmd)->state = FALSE;
@@ -663,11 +730,11 @@
if (success) {
DBG(DBG_ABNORM, printk("eata_reset: exit, success.\n"));
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
+ DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
return (SCSI_RESET_SUCCESS);
} else {
DBG(DBG_ABNORM, printk("eata_reset: exit, wakeup.\n"));
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
+ DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
return (SCSI_RESET_PUNT);
}
}
@@ -677,7 +744,8 @@
*
* At the moment the algorithm is rather simple
*/
-static void eata_select_queue_depths(struct Scsi_Host *host, Scsi_Device *devicelist)
+static void eata_select_queue_depths(struct Scsi_Host *host,
+ Scsi_Device *devicelist)
{
Scsi_Device *device;
int devcount = 0;
@@ -745,13 +813,34 @@
} else /* ISA forces us to limit the QS because of bounce buffers*/
device->queue_depth = 2; /* I know this is cruel */
- printk(KERN_INFO "scsi%d: queue depth for target %d on channel %d set "
- "to %d\n", host->host_no, device->id, device->channel,
+ printk(KERN_INFO "scsi%d: queue depth for target %d on channel %d "
+ "set to %d\n", host->host_no, device->id, device->channel,
device->queue_depth);
}
}
}
+int check_blink_state(long base)
+{
+ ushort loops = 10;
+ u32 blinkindicator;
+ u32 state = 0x12345678;
+ u32 oldstate = 0;
+
+ blinkindicator = htonl(0x54504442);
+ while ((loops--) && (state != oldstate)) {
+ oldstate = state;
+ state = inl((uint) base + 1);
+ }
+
+ DBG(DBG_BLINK, printk("Did Blink check. Status: %d\n",
+ (state == oldstate) && (state == blinkindicator)));
+
+ if ((state == oldstate) && (state == blinkindicator))
+ return(TRUE);
+ else
+ return (FALSE);
+}
char * get_board_data(u32 base, u32 irq, u32 id)
{
@@ -802,8 +891,8 @@
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",
+ DBG(DBG_INTR3, printk(KERN_DEBUG "fake_int_result: %#x hbastat %#x "
+ "scsistat %#x, buff %p sp %p\n",
fake_int_result, (u32) (sp->hba_stat /*& 0x7f*/),
(u32) sp->scsi_stat, buff, sp));
@@ -811,38 +900,17 @@
scsi_init_free((void *)sp, sizeof(struct eata_sp));
if ((fake_int_result & HA_SERROR) || jiffies > i){
+ printk(KERN_WARNING "eata_dma: trying to reset HBA at %x to clear "
+ "possible blink state\n", base);
/* hard reset the HBA */
inb((u32) (base) + HA_RSTATUS);
eata_send_command(0, base, EATA_CMD_RESET);
- i = jiffies;
- while (jiffies < (i + (3 * HZ)) && limit++ < 10000000)
- barrier();
+ DELAY(1);
return (NULL);
} else
return (buff);
}
-
-int check_blink_state(long base)
-{
- ushort loops = 10;
- u32 blinkindicator;
- u32 state = 0x12345678;
- u32 oldstate = 0;
-
- blinkindicator = htonl(0x54504442);
- while ((loops--) && (state != oldstate)) {
- oldstate = state;
- state = inl((uint) base + 1);
- }
-
- DBG(DBG_BLINK, printk("Did Blink check. Status: %d\n",
- (state == oldstate) && (state == blinkindicator)));
- if ((state == oldstate) && (state == blinkindicator))
- return(TRUE);
- else
- return (FALSE);
-}
int get_conf_PIO(u32 base, struct get_conf *buf)
{
@@ -857,6 +925,10 @@
while (inb(base + HA_RSTATUS) & HA_SBUSY)
if (--loop == 0)
return (FALSE);
+
+ fake_int_base = (struct eata_register *) base;
+ fake_int_result = FALSE;
+ fake_int_happened = FALSE;
DBG(DBG_PIO && DBG_PROBE,
printk("Issuing PIO READ CONFIG to HBA at %#x\n", base));
@@ -890,6 +962,7 @@
return (FALSE);
}
+
void print_config(struct get_conf *gc)
{
printk("LEN: %d ver:%d OCS:%d TAR:%d TRNXFR:%d MORES:%d DMAS:%d\n",
@@ -929,7 +1002,7 @@
}
if(gc->HAA_valid == FALSE || ntohl(gc->len) < 0x22)
gc->MAX_CHAN = 0;
-
+
if (reg_IRQ[gc->IRQ] == FALSE) { /* Interrupt already registered ? */
if (!request_irq(gc->IRQ, (void *) eata_fake_int_handler, SA_INTERRUPT,
"eata_dma", NULL)){
@@ -948,13 +1021,27 @@
} else
reg_IRQ[gc->IRQ]++;
}
-
+
+
+ /* If DMA is supported but DMA_valid isn't set to indicate that
+ * the channel number is given we must have pre 2.0 firmware (1.7?)
+ * which leaves us to guess since the "newer ones" also don't set the
+ * DMA_valid bit.
+ */
+ if (gc->DMA_support && !gc->DMA_valid && gc->DMA_channel) {
+ printk(KERN_WARNING "eata_dma: If you are using a pre 2.0 firmware "
+ "please update it !\n"
+ " You can get new firmware releases from ftp.dpt.com\n");
+ gc->DMA_channel = (base == 0x1f0 ? 3 /* DMA=5 */ : 2 /* DMA=6 */);
+ gc->DMA_valid = TRUE;
+ }
+
/* if gc->DMA_valid it must be an ISA HBA and we have to register it */
dma_channel = BUSMASTER;
if (gc->DMA_valid) {
if (request_dma(dma_channel = (8 - gc->DMA_channel) & 7, "eata_dma")) {
- printk("Unable to allocate DMA channel %d for ISA HBA at %#.4x.\n",
- dma_channel, base);
+ printk(KERN_WARNING "Unable to allocate DMA channel %d for ISA HBA"
+ " at %#.4x.\n", dma_channel, base);
reg_IRQ[gc->IRQ]--;
if (reg_IRQ[gc->IRQ] == 0)
free_irq(gc->IRQ, NULL);
@@ -963,23 +1050,27 @@
return (FALSE);
}
}
-
-#if !(NEWSTUFF)
+
+ if (dma_channel != BUSMASTER) {
+ disable_dma(dma_channel);
+ clear_dma_ff(dma_channel);
+ set_dma_mode(dma_channel, DMA_MODE_CASCADE);
+ enable_dma(dma_channel);
+ }
+
if (bustype != IS_EISA && bustype != IS_ISA)
-#endif
buff = get_board_data(base, gc->IRQ, gc->scsi_id[3]);
if (buff == NULL) {
-#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);
+ printk(KERN_WARNING "HBA at %#.4x doesn't support DMA. "
+ "Sorry\n", base);
else
- printk("HBA at %#.4x does not react on INQUIRY. Sorry.\n",
- base);
+ printk(KERN_WARNING "HBA at %#.4x does not react on INQUIRY. "
+ "Sorry.\n", base);
if (gc->DMA_valid)
free_dma(dma_channel);
reg_IRQ[gc->IRQ]--;
@@ -988,14 +1079,12 @@
if (gc->IRQ_TR == FALSE)
reg_IRQL[gc->IRQ] = FALSE;
return (FALSE);
-#if !(NEWSTUFF)
}
-#endif
}
-
+
if (gc->DMA_support == FALSE && buff != NULL)
- printk("HBA %.12sat %#.4x doesn't set the DMA_support flag correctly.\n",
- &buff[16], base);
+ printk(KERN_WARNING "HBA %.12sat %#.4x doesn't set the DMA_support "
+ "flag correctly.\n", &buff[16], base);
request_region(base, 9, "eata_dma"); /* We already checked the
* availability, so this
@@ -1004,8 +1093,10 @@
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");
+ printk(KERN_WARNING "Warning: Queue size has to be corrected. Assuming"
+ " 64 queueslots\n"
+ " This might be a PM2012B with a defective Firmware\n"
+ " Contact DPT support@dpt.com for an upgrade\n");
}
size = sizeof(hostdata) + ((sizeof(struct eata_ccb) + sizeof(long))
@@ -1015,7 +1106,45 @@
sh = scsi_register(tpnt, size);
- if(sh == NULL) {
+ if(sh != NULL) {
+
+ hd = SD(sh);
+
+ memset(hd->reads, 0, sizeof(u32) * 26);
+
+ sh->select_queue_depths = eata_select_queue_depths;
+
+ hd->bustype = bustype;
+
+ /*
+ * If we are using a ISA board, we can't use extended SG,
+ * because we would need exessive amounts of memory for
+ * bounce buffers.
+ */
+ if (gc->SG_64K==TRUE && ntohs(gc->SGsiz)==64 && hd->bustype!=IS_ISA){
+ sh->sg_tablesize = SG_SIZE_BIG;
+ } else {
+ sh->sg_tablesize = ntohs(gc->SGsiz);
+ if (sh->sg_tablesize > SG_SIZE || sh->sg_tablesize == 0) {
+ if (sh->sg_tablesize == 0)
+ printk(KERN_WARNING "Warning: SG size had to be fixed.\n"
+ "This might be a PM2012 with a defective Firmware"
+ "\nContact DPT support@dpt.com for an upgrade\n");
+ sh->sg_tablesize = SG_SIZE;
+ }
+ }
+ hd->sgsize = sh->sg_tablesize;
+ }
+
+ if(sh != NULL) {
+ sh->can_queue = hd->queuesize = ntohs(gc->queuesiz);
+ sh->cmd_per_lun = 0;
+ }
+
+ if(sh == NULL) {
+ DBG(DBG_REGISTER, printk(KERN_NOTICE "eata_dma: couldn't register HBA"
+ " at%x \n", base));
+ scsi_unregister(sh);
if (gc->DMA_valid)
free_dma(dma_channel);
@@ -1026,64 +1155,52 @@
reg_IRQL[gc->IRQ] = FALSE;
return (FALSE);
}
-
- hd = SD(sh);
-
- memset(hd->ccb, 0, sizeof(struct eata_ccb) * ntohs(gc->queuesiz));
- memset(hd->reads, 0, sizeof(u32) * 26);
+
hd->broken_INQUIRY = (bugs & BROKEN_INQUIRY);
if(hd->broken_INQUIRY == TRUE) {
- strcpy(SD(sh)->vendor, "DPT");
- strcpy(SD(sh)->name, "??????????");
- strcpy(SD(sh)->revision, "???.?");
+ strcpy(hd->vendor, "DPT");
+ strcpy(hd->name, "??????????");
+ strcpy(hd->revision, "???.?");
+ hd->firmware_revision = 0;
} else {
- strncpy(SD(sh)->vendor, &buff[8], 8);
- SD(sh)->vendor[8] = 0;
- strncpy(SD(sh)->name, &buff[16], 17);
- SD(sh)->name[17] = 0;
- SD(sh)->revision[0] = buff[32];
- SD(sh)->revision[1] = buff[33];
- SD(sh)->revision[2] = buff[34];
- SD(sh)->revision[3] = '.';
- SD(sh)->revision[4] = buff[35];
- SD(sh)->revision[5] = 0;
- }
+ strncpy(hd->vendor, &buff[8], 8);
+ hd->vendor[8] = 0;
+ strncpy(hd->name, &buff[16], 17);
+ hd->name[17] = 0;
+ hd->revision[0] = buff[32];
+ hd->revision[1] = buff[33];
+ hd->revision[2] = buff[34];
+ hd->revision[3] = '.';
+ hd->revision[4] = buff[35];
+ hd->revision[5] = 0;
+ hd->firmware_revision = (buff[32] << 24) + (buff[33] << 16)
+ + (buff[34] << 8) + buff[35];
+ }
+
+ if (hd->firmware_revision >= (('0'<<24) + ('7'<<16) + ('G'<< 8) + '0'))
+ hd->immediate_support = 1;
+ else
+ hd->immediate_support = 0;
switch (ntohl(gc->len)) {
case 0x1c:
- SD(sh)->EATA_revision = 'a';
+ hd->EATA_revision = 'a';
break;
case 0x1e:
- SD(sh)->EATA_revision = 'b';
+ hd->EATA_revision = 'b';
break;
case 0x22:
- SD(sh)->EATA_revision = 'c';
+ hd->EATA_revision = 'c';
break;
case 0x24:
- SD(sh)->EATA_revision = 'z';
+ hd->EATA_revision = 'z';
default:
- SD(sh)->EATA_revision = '?';
+ hd->EATA_revision = '?';
}
- if(ntohl(gc->len) >= 0x22) {
- if (gc->is_PCI == TRUE)
- hd->bustype = IS_PCI;
- else if (gc->is_EISA == TRUE)
- hd->bustype = IS_EISA;
- else
- hd->bustype = IS_ISA;
- } else if(hd->broken_INQUIRY == FALSE) {
- if (buff[21] == '4')
- hd->bustype = IS_PCI;
- else if (buff[21] == '2')
- hd->bustype = IS_EISA;
- else
- hd->bustype = IS_ISA;
- } else
- hd->bustype = bustype;
-
+
if(ntohl(gc->len) >= 0x22) {
sh->max_id = gc->MAX_ID + 1;
sh->max_lun = gc->MAX_LUN + 1;
@@ -1092,6 +1209,7 @@
sh->max_lun = 8;
}
+ hd->HBA_number = sh->host_no;
hd->channel = gc->MAX_CHAN;
sh->max_channel = gc->MAX_CHAN;
sh->unique_id = base;
@@ -1105,34 +1223,7 @@
* SCSI midlevel code should support different HBA ids on every channel
*/
sh->this_id = gc->scsi_id[3];
-
- hd->queuesize = ntohs(gc->queuesiz);
- sh->can_queue = ntohs(gc->queuesiz);
- sh->cmd_per_lun = 0;
- sh->select_queue_depths = eata_select_queue_depths;
- /* FIXME:
- * SG should be allocated more dynamically
- */
- /*
- * If we are using a ISA board, we can't use extended SG,
- * because we would need excessive amounts of memory for
- * bounce buffers.
- */
- if (gc->SG_64K == TRUE && ntohs(gc->SGsiz) == 64 && hd->bustype != IS_ISA){
- sh->sg_tablesize = SG_SIZE_BIG;
- sh->use_clustering = TRUE;
- } else {
- sh->sg_tablesize = ntohs(gc->SGsiz);
- sh->use_clustering = TRUE;
- if (sh->sg_tablesize > SG_SIZE || sh->sg_tablesize == 0) {
- sh->sg_tablesize = SG_SIZE;
- if (ntohs(gc->SGsiz) == 0)
- printk("Warning: SG size had to be corrected.\n"
- "This might be a PM2012 with a defective Firmware\n");
- }
- }
-
if (gc->SECOND)
hd->primary = FALSE;
else
@@ -1150,6 +1241,7 @@
hd->writes_lat[x][1] = 0xffffffff;
hd->reads_lat[x][1] = 0xffffffff;
}
+ hd->all_lat[1] = 0xffffffff;
hd->next = NULL; /* build a linked list of all HBAs */
hd->prev = last_HBA;
@@ -1164,6 +1256,7 @@
}
+
void find_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
{
u32 base;
@@ -1320,7 +1413,7 @@
continue; /* break; */
} else if (check_blink_state(base) == TRUE) {
printk("eata_dma: HBA is in BLINK state.\n"
- "Consult your HBAs Manual to correct this.\n");
+ "Consult your HBAs manual to correct this.\n");
}
}
}
@@ -1350,13 +1443,15 @@
tpnt->proc_dir = &proc_scsi_eata_dma;
status = scsi_init_malloc(512, GFP_ATOMIC | GFP_DMA);
- dma_scratch = scsi_init_malloc(512, GFP_ATOMIC | GFP_DMA);
+ dma_scratch = scsi_init_malloc(1024, 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);
}
+ dma_scratch += 4;
+
find_PCI(&gc, tpnt);
find_EISA(&gc, tpnt);
@@ -1364,41 +1459,45 @@
find_ISA(&gc, tpnt);
for (i = 0; i <= MAXIRQ; i++) { /* Now that we know what we have, we */
- if (reg_IRQ[i]){ /* exchange the interrupt handler which */
+ if (reg_IRQ[i] >= 1){ /* exchange the interrupt handler which */
free_irq(i, NULL); /* we used for probing with the real one */
- request_irq(i, (void *)(eata_int_handler), SA_INTERRUPT, "eata_dma", NULL);
+ request_irq(i, (void *)(eata_int_handler), SA_INTERRUPT,
+ "eata_dma", NULL);
}
}
+
HBA_ptr = first_HBA;
-
+
if (registered_HBAs != 0) {
- printk("EATA (Extended Attachment) driver version: %d.%d%s\n"
- "developed in co-operation with DPT\n"
- "(c) 1993-95 Michael Neuffer, neuffer@goofy.zdv.uni-mainz.de\n",
- VER_MAJOR, VER_MINOR, VER_SUB);
- printk("Registered HBAs:");
- 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("EATA (Extended Attachment) driver version: %d.%d%s"
+ "\ndeveloped in co-operation with DPT\n"
+ "(c) 1993-96 Michael Neuffer, mike@i-Connect.Net\n",
+ VER_MAJOR, VER_MINOR, VER_SUB);
+ printk("Registered HBAs:");
+ printk("\nHBA no. Boardtype Revis EATA Bus BaseIO IRQ"
+ " DMA Ch ID Pr QS S/G IS\n");
+ for (i = 1; i <= registered_HBAs; i++) {
+ printk("scsi%-2d: %.12s 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 ",
(u32) HBA_ptr->base, HBA_ptr->irq);
if(HBA_ptr->dma_channel != BUSMASTER)
- printk(" %2x ", HBA_ptr->dma_channel);
+ printk(" %2x ", HBA_ptr->dma_channel);
else
- printk(" %s", "BMST");
- 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);
+ printk(" %s", "BMST");
+ printk(" %d %d %c %3d %3d %c\n",
+ SD(HBA_ptr)->channel+1, HBA_ptr->this_id,
+ (SD(HBA_ptr)->primary == TRUE)?'Y':'N',
+ HBA_ptr->can_queue, HBA_ptr->sg_tablesize,
+ (SD(HBA_ptr)->immediate_support == TRUE)?'Y':'N');
HBA_ptr = SD(HBA_ptr)->next;
}
} else {
scsi_init_free((void *)status, 512);
}
- scsi_init_free((void *)dma_scratch, 512);
+ scsi_init_free((void *)dma_scratch - 4, 1024);
DBG(DPT_DEBUG, DELAY(12));
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