96 #define NDEBUG_ABORT 0
99 #if (NDEBUG & NDEBUG_LISTS)
100 #define LIST(x,y) {printk("LINE:%d Adding %p to %p\n", __LINE__, (void*)(x), (void*)(y)); if ((x)==(y)) udelay(5); }
101 #define REMOVE(w,x,y,z) {printk("LINE:%d Removing: %p->%p %p->%p \n", __LINE__, (void*)(w), (void*)(x), (void*)(y), (void*)(z)); if ((x)==(y)) udelay(5); }
104 #define REMOVE(w,x,y,z)
114 #define READ_OVERRUNS
117 #ifdef BOARD_REQUIRES_NO_DELAY
118 #define io_recovery_delay(x)
120 #define io_recovery_delay(x) udelay(x)
298 if (scsi_bufflen(cmd)) {
299 cmd->
SCp.buffer = scsi_sglist(cmd);
300 cmd->
SCp.buffers_residual = scsi_sg_count(cmd) - 1;
301 cmd->
SCp.ptr = sg_virt(cmd->
SCp.buffer);
302 cmd->
SCp.this_residual = cmd->
SCp.buffer->length;
305 cmd->
SCp.buffers_residual = 0;
307 cmd->
SCp.this_residual = 0;
325 static int NCR5380_poll_politely(
struct Scsi_Host *instance,
int reg,
int bit,
int val,
int t)
418 static void NCR5380_print(
struct Scsi_Host *instance)
430 printk(
"STATUS_REG: %02x ", status);
434 printk(
"\nBASR: %02x ", basr);
435 for (i = 0; basrs[
i].mask; ++
i)
436 if (basr & basrs[i].mask)
438 printk(
"\nICR: %02x ", icr);
439 for (i = 0; icrs[
i].mask; ++
i)
440 if (icr & icrs[i].mask)
442 printk(
"\nMODE: %02x ", mr);
443 for (i = 0; mrs[
i].mask; ++
i)
444 if (mr & mrs[i].mask)
459 static void NCR5380_print_phase(
struct Scsi_Host *instance)
468 printk(
"scsi%d : REQ not asserted, phase unknown.\n", instance->
host_no);
488 #define USLEEP_SLEEP (20*HZ/1000)
492 #define USLEEP_POLL (200*HZ/1000)
494 #ifndef USLEEP_WAITLONG
496 #define USLEEP_WAITLONG USLEEP_SLEEP
521 static int should_disconnect(
unsigned char cmd)
577 static int __init __maybe_unused NCR5380_probe_irq(
struct Scsi_Host *instance,
582 unsigned long timeout;
583 int trying_irqs, i, mask;
586 for (trying_irqs = i = 0, mask = 1; i < 16; ++
i, mask <<= 1)
614 for (i = 0, mask = 1; i < 16; ++
i, mask <<= 1)
615 if (trying_irqs & mask)
632 static void __init __maybe_unused
633 NCR5380_print_options(
struct Scsi_Host *instance)
678 static void NCR5380_print_status(
struct Scsi_Host *instance)
699 #define SPRINTF(args...) do { if(pos < buffer + length-80) pos += sprintf(pos, ## args); } while(0)
703 char *lprint_command(
unsigned char *cmd,
char *
pos,
char *
buffer,
int len);
717 #ifdef DTC_PUBLIC_RELEASE
718 dtc_wmaxi = dtc_maxi = 0;
720 #ifdef PAS16_PUBLIC_RELEASE
721 pas_wmaxi = pas_maxi = 0;
728 #ifdef DTC_PUBLIC_RELEASE
731 #ifdef T128_PUBLIC_RELEASE
734 #ifdef GENERIC_NCR5380_PUBLIC_RELEASE
737 #ifdef PAS16_PUBLIC_RELEASE
741 SPRINTF(
"\nBase Addr: 0x%05lX ", (
long) instance->
base);
748 #ifdef DTC_PUBLIC_RELEASE
749 SPRINTF(
"Highwater I/O busy_spin_counts -- write: %d read: %d\n", dtc_wmaxi, dtc_maxi);
751 #ifdef PAS16_PUBLIC_RELEASE
752 SPRINTF(
"Highwater I/O busy_spin_counts -- write: %d read: %d\n", pas_wmaxi, pas_maxi);
756 SPRINTF(
"scsi%d: no currently connected command\n", instance->
host_no);
761 pos = lprint_Scsi_Cmnd(ptr, pos, buffer, length);
765 pos = lprint_Scsi_Cmnd(ptr, pos, buffer, length);
769 if (pos - buffer < offset)
771 else if (pos - buffer - offset < length)
772 return pos - buffer -
offset;
776 static char *lprint_Scsi_Cmnd(
Scsi_Cmnd * cmd,
char *pos,
char *buffer,
int length)
780 pos = lprint_command(cmd->
cmnd, pos, buffer, length);
784 static char *lprint_command(
unsigned char *
command,
char *pos,
char *buffer,
int length)
787 pos = lprint_opcode(command[0], pos, buffer, length);
794 static char *lprint_opcode(
int opcode,
char *pos,
char *buffer,
int length)
796 SPRINTF(
"%2d (0x%02x)", opcode, opcode);
840 for (i = hostdata->
id_mask; i <= 0x80; i <<= 1)
843 for (i = 0; i < 8; ++
i)
844 hostdata->
busy[i] = 0;
846 hostdata->dmalen = 0;
856 for (i = 0; i < 8; ++
i) {
857 hostdata->time_read[
i] = 0;
858 hostdata->time_write[
i] = 0;
859 hostdata->bytes_read[
i] = 0;
860 hostdata->bytes_write[
i] = 0;
862 hostdata->timebase = 0;
863 hostdata->pendingw = 0;
864 hostdata->pendingr = 0;
868 if (flags & FLAG_NCR53C400)
873 hostdata->
host = instance;
878 printk(
KERN_WARNING "scsi%d : WARNING : support for multiple outstanding commands enabled\n" " without AUTOSENSE option, contingent allegiance conditions may\n"
879 " be incorrectly cleared.\n", instance->
host_no);
888 if (hostdata->
flags & FLAG_NCR53C400) {
935 static void NCR5380_exit(
struct Scsi_Host *instance)
961 switch (cmd->
cmnd[0]) {
964 printk(
"scsi%d : WRITE attempted with NO_WRITE debugging flag set\n", instance->
host_no);
972 switch (cmd->
cmnd[0]) {
976 hostdata->time_write[cmd->
device->id] -= (
jiffies - hostdata->timebase);
977 hostdata->bytes_write[cmd->
device->id] += scsi_bufflen(cmd);
978 hostdata->pendingw++;
983 hostdata->time_read[cmd->
device->id] -= (
jiffies - hostdata->timebase);
984 hostdata->bytes_read[cmd->
device->id] += scsi_bufflen(cmd);
985 hostdata->pendingr++;
1013 tmp->host_scribble = (
unsigned char *) cmd;
1058 dprintk(
NDEBUG_LISTS, (
"MAIN tmp=%p target=%d busy=%d lun=%d\n", tmp, tmp->target, hostdata->
busy[tmp->target], tmp->lun));
1091 if (!NCR5380_select(instance, tmp,
1131 && !hostdata->dmalen
1136 NCR5380_information_transfer(instance);
1146 #ifndef DONT_USE_INTR
1167 unsigned long flags;
1184 NCR5380_reselect(instance);
1193 #if defined(REAL_DMA)
1204 panic(
"scsi%d : received end of DMA interrupt with no connected cmd\n", instance->hostno);
1209 hostdata->dmalen = 0;
1225 spin_unlock_irqrestore(instance->
host_lock, flags);
1244 #ifdef NCR5380_STATS
1245 switch (cmd->
cmnd[0]) {
1249 hostdata->time_write[
scmd_id(cmd)] += (
jiffies - hostdata->timebase);
1250 hostdata->pendingw--;
1255 hostdata->time_read[
scmd_id(cmd)] += (
jiffies - hostdata->timebase);
1256 hostdata->pendingr--;
1300 unsigned char tmp[3],
phase;
1301 unsigned char *data;
1303 unsigned long timeout;
1304 unsigned char value;
1459 NCR5380_set_timer(hostdata, 1);
1468 NCR5380_reselect(instance);
1469 printk(
"scsi%d : reselection after won arbitration?\n", instance->
host_no);
1494 collect_stats(hostdata, cmd);
1521 err = NCR5380_poll_politely(instance,
STATUS_REG, SR_REQ, SR_REQ,
HZ);
1539 NCR5380_transfer_pio(instance, &
phase, &len, &data);
1545 initialize_SCp(cmd);
1580 static int NCR5380_transfer_pio(
struct Scsi_Host *instance,
unsigned char *
phase,
int *
count,
unsigned char **data) {
1584 unsigned char *
d = *
data;
1588 int break_allowed = 0;
1624 if (!(tmp & SR_REQ)) {
1654 if (!((p &
SR_MSG) && c > 1)) {
1669 NCR5380_poll_politely(instance,
STATUS_REG, SR_REQ, 0, 5*
HZ);
1701 if (!c || (*phase == p))
1739 static int do_abort(
struct Scsi_Host *host) {
1760 rc = NCR5380_poll_politely(host,
STATUS_REG, SR_REQ, SR_REQ, 60 *
HZ);
1765 tmp = (
unsigned char)rc;
1771 rc = NCR5380_poll_politely(host,
STATUS_REG, SR_REQ, 0, 3*
HZ);
1780 NCR5380_transfer_pio(host, &phase, &len, &msgptr);
1787 return len ? -1 : 0;
1790 #if defined(REAL_DMA) || defined(PSEUDO_DMA) || defined (REAL_DMA_POLL)
1812 static int NCR5380_transfer_dma(
struct Scsi_Host *instance,
unsigned char *phase,
int *count,
unsigned char **data) {
1814 register int c = *
count;
1815 register unsigned char p = *
phase;
1816 register unsigned char *d = *
data;
1819 #if defined(REAL_DMA_POLL)
1821 unsigned char saved_data = 0,
overrun = 0, residue;
1832 #if defined(REAL_DMA) || defined(REAL_DMA_POLL)
1833 #ifdef READ_OVERRUNS
1838 dprintk(
NDEBUG_DMA, (
"scsi%d : initializing DMA channel %d for %s, %d bytes %s %0x\n", instance->
host_no, instance->
dma_channel, (p & SR_IO) ?
"reading" :
"writing", c, (p & SR_IO) ?
"to" :
"from", (
unsigned) d));
1846 #elif defined(REAL_DMA_POLL)
1855 #if defined(PSEUDO_DMA) && defined(UNSAFE)
1859 if (hostdata->
flags & FLAG_NCR53C400)
1885 #if defined(REAL_DMA_POLL)
1927 #ifdef READ_OVERRUNS
1937 if (!(tmp & BASR_PHASE_MATCH))
1955 #ifdef READ_OVERRUNS
1956 if (*phase == p && (p & SR_IO) && residue == 0) {
1959 **data = saved_data;
1964 printk(
"No overrun??\n");
1968 NCR5380_transfer_pio(instance, phase, &cnt, data);
1969 *count -= toPIO -
cnt;
1973 dprintk(
NDEBUG_DMA, (
"Return with data ptr = 0x%X, count %d, last 0x%X, next 0x%X\n", *data, *count, *(*data + *count - 1), *(*data + *count)));
1976 #elif defined(REAL_DMA)
1980 #ifdef DMA_WORKS_RIGHT
1984 if (hostdata->
flags & FLAG_NCR53C400) {
2010 if (!(hostdata->
flags & FLAG_NCR53C400)) {
2019 #ifdef DMA_WORKS_RIGHT
2040 dprintk(NDEBUG_LAST_WRITE_SENT, (
"scsi%d : last bit sent works\n", instance->
host_no));
2054 if ((!(p & SR_IO)) && (hostdata->
flags & FLAG_NCR53C400)) {
2060 printk(
"53C400w: IRQ NOT THERE!\n");
2066 #if defined(PSEUDO_DMA) && defined(UNSAFE)
2093 static void NCR5380_information_transfer(
struct Scsi_Host *instance) {
2099 #
if defined(
PSEUDO_DMA) || defined(REAL_DMA_POLL)
2102 unsigned char *
data;
2103 unsigned char phase,
tmp, extended_msg[10], old_phase = 0xff;
2115 if (phase != old_phase) {
2131 #if (NDEBUG & NDEBUG_NO_DATAOUT)
2132 printk(
"scsi%d : NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n", instance->
host_no);
2144 if (!cmd->
SCp.this_residual && cmd->
SCp.buffers_residual) {
2146 --cmd->
SCp.buffers_residual;
2147 cmd->
SCp.this_residual = cmd->
SCp.buffer->length;
2148 cmd->
SCp.ptr = sg_virt(cmd->
SCp.buffer);
2161 #if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
2169 #ifdef NCR5380_dma_xfer_len
2174 #ifdef LIMIT_TRANSFERSIZE
2175 if (transfersize > 512)
2182 if (transfersize > 32 * 1024)
2183 transfersize = 32 * 1024;
2186 if (NCR5380_transfer_dma(instance, &phase, &len, (
unsigned char **) &cmd->
SCp.ptr)) {
2192 "switching to slow handshake\n");
2201 cmd->
SCp.this_residual -= transfersize - len;
2204 NCR5380_transfer_pio(instance, &phase, (
int *) &cmd->
SCp.this_residual, (
unsigned char **)
2210 NCR5380_transfer_pio(instance, &phase, &len, &data);
2235 if (!cmd->next_link) {
2236 printk(
"scsi%d : target %d lun %d linked command complete, no next_link\n" instance->
host_no, cmd->
device->id, cmd->
device->lun);
2241 initialize_SCp(cmd->next_link);
2243 cmd->next_link->
tag = cmd->
tag;
2244 cmd->
result = cmd->
SCp.Status | (cmd->
SCp.Message << 8);
2246 collect_stats(hostdata, cmd);
2277 cmd->
result = cmd->
SCp.Status | (cmd->
SCp.Message << 8);
2283 hostdata->ses.cmd_len) {
2285 hostdata->ses.cmd_len = 0 ;
2301 collect_stats(hostdata, cmd);
2322 cmd->
device->simple_tags = 0;
2331 cmd->
device->disconnect = 1;
2386 data = extended_msg + 1;
2388 NCR5380_transfer_pio(instance, &phase, &len, &data);
2392 if (!len && extended_msg[1] <= (
sizeof(extended_msg) - 1)) {
2395 len = extended_msg[1] - 1;
2396 data = extended_msg + 3;
2399 NCR5380_transfer_pio(instance, &phase, &len, &data);
2402 switch (extended_msg[2]) {
2410 printk(
"scsi%d: error receiving extended message\n", instance->
host_no);
2413 printk(
"scsi%d: extended message code %02x length %d is too long\n", instance->
host_no, extended_msg[2], extended_msg[1]);
2429 "rejecting unknown message %02x\n",tmp);
2432 "rejecting unknown extended message code %02x, length %d\n", extended_msg[1], extended_msg[0]);
2443 NCR5380_transfer_pio(instance, &phase, &len, &data);
2448 collect_stats(hostdata, cmd);
2463 NCR5380_transfer_pio(instance, &phase, &len, &data);
2464 if (!cmd->
device->disconnect && should_disconnect(cmd->
cmnd[0])) {
2473 NCR5380_transfer_pio(instance, &phase, &len, &data);
2478 NCR5380_dprint(NDEBUG_ALL, instance);
2505 static void NCR5380_reselect(
struct Scsi_Host *instance) {
2509 unsigned char target_mask;
2510 unsigned char lun, phase;
2512 unsigned char msg[3];
2513 unsigned char *data;
2551 if(NCR5380_poll_politely(instance,
STATUS_REG, SR_REQ, SR_REQ, 2*
HZ))
2557 NCR5380_transfer_pio(instance, &phase, &len, &data);
2559 if (!(
msg[0] & 0x80)) {
2566 lun = (
msg[0] & 0x07);
2581 if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun)
2590 tmp->host_scribble =
NULL;
2594 printk(
KERN_ERR "scsi%d : warning : target bitmask %02x lun %d not in disconnect_queue.\n", instance->
host_no, target_mask, lun);
2624 static void NCR5380_dma_complete(NCR5380_instance * instance) {
2688 NCR5380_print_status(instance);
2742 #if (NDEBUG & NDEBUG_ABORT)
2744 else if (prev == tmp)
2792 if (NCR5380_select(instance, cmd, (
int) cmd->
tag))
2817 printk(
KERN_WARNING "scsi%d : warning : SCSI command probably completed successfully\n"
2818 " before abortion\n", instance->
host_no);
2839 NCR5380_print_status(instance);