115 #define NCR_700_VERSION "2.8"
117 #include <linux/kernel.h>
118 #include <linux/types.h>
119 #include <linux/string.h>
120 #include <linux/slab.h>
128 #include <linux/module.h>
130 #include <linux/device.h>
133 #include <asm/pgtable.h>
134 #include <asm/byteorder.h>
136 #include <scsi/scsi.h>
153 #define to32bit(x) ((__u32)((unsigned long)(x)))
158 #define STATIC static
166 #include "53c700_d.h"
185 static char *NCR_700_phase[] = {
188 "before command phase",
189 "after command phase",
190 "after status phase",
191 "after data in phase",
192 "after data out phase",
196 static char *NCR_700_condition[] = {
204 "REJECT_MSG RECEIVED",
205 "DISCONNECT_MSG RECEIVED",
211 static char *NCR_700_fatal_messages[] = {
212 "unexpected message after reselection",
213 "still MSG_OUT after message injection",
214 "not MSG_IN after selection",
215 "Illegal message length received",
218 static char *NCR_700_SBCL_bits[] = {
229 static char *NCR_700_SBCL_to_phase[] = {
259 if(period < hostdata->min_period) {
263 XFERP = (period*4 * hostdata->
sync_clock)/1000 - 4;
264 if(offset > max_offset) {
269 if(XFERP < min_xferp) {
272 return (offset & 0x0f) | (XFERP & 0x07)<<4;
281 return NCR_700_offset_period_to_sxfer(hostdata,
294 static int banner = 0;
303 printk(
KERN_ERR "53c700: Failed to allocate memory for driver, detatching\n");
307 script = (
__u32 *)memory;
332 tpnt->
name =
"53c700";
343 - (
unsigned long)&hostdata->
slots[0].SG[0]);
348 hostdata->
slots[j-1].ITL_forw = &hostdata->
slots[
j];
356 for (j = 0; j < PATCHES; j++)
357 script[LABELPATCHES[j]] =
bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]);
360 pScript + MSGOUT_OFFSET);
362 pScript + STATUS_OFFSET);
364 pScript + MSGIN_OFFSET);
366 hostdata->
script = script;
377 host->hostdata[0] = (
unsigned long)
hostdata;
391 (hostdata->
fast ?
"53c700-66" :
"53c700"),
393 "(Differential)" :
"");
397 if (scsi_add_host(host, dev)) {
398 dev_printk(
KERN_ERR, dev,
"53c700: scsi_add_host failed\n");
421 NCR_700_identify(
int can_disconnect,
__u8 lun)
424 ((can_disconnect) ? 0x40 : 0) |
442 int count, synchronous = 0;
446 count = ((NCR_700_readb(host,
DFIFO_REG) & 0x7f) -
447 (NCR_700_readl(host,
DBC_REG) & 0x7f)) & 0x7f;
449 count = ((NCR_700_readb(host,
DFIFO_REG) & 0x3f) -
450 (NCR_700_readl(host,
DBC_REG) & 0x3f)) & 0x3f;
454 synchronous = NCR_700_readb(host,
SXFER_REG) & 0x0f;
457 ddir = NCR_700_readb(host,
CTEST0_REG) & 0x01;
462 count += (NCR_700_readb(host,
SSTAT2_REG) & 0xf0) >> 4;
476 printk(
"RESIDUAL IS %d (ddir %d)\n", count, ddir);
484 sbcl_to_string(
__u8 sbcl)
487 static char ret[256];
492 strcat(ret, NCR_700_SBCL_bits[i]);
494 strcat(ret, NCR_700_SBCL_to_phase[sbcl & 0x07]);
503 for(i=0; i<8 && !(bitmap &(1<<
i)); i++)
601 char *
cmnd = NCR_700_get_sense_cmnd(SCp->
device);
603 printk(
" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n",
604 SCp, SCp->
cmnd[7], result);
621 if(NCR_700_get_depth(SCp->
device) == 0 ||
622 NCR_700_get_depth(SCp->
device) > SCp->
device->queue_depth)
624 NCR_700_get_depth(SCp->
device));
626 NCR_700_set_depth(SCp->
device, NCR_700_get_depth(SCp->
device) - 1);
656 __u8 burst_disable = 0;
679 NCR_700_writeb(burst_length | hostdata->
dmode_extra,
712 if(hostdata->
clock > 75) {
713 printk(
KERN_ERR "53c700: Clock speed %dMHz is too high: 75Mhz is the maximum this chip can be driven at\n", hostdata->
clock);
716 DEBUG((
"53c700: sync 2 async 3\n"));
720 }
else if(hostdata->
clock > 50 && hostdata->
clock <= 75) {
722 DEBUG((
"53c700: sync 1.5 async 3\n"));
728 }
else if(hostdata->
clock > 37 && hostdata->
clock <= 50) {
730 DEBUG((
"53c700: sync 1 async 2\n"));
734 }
else if(hostdata->
clock > 25 && hostdata->
clock <=37) {
736 DEBUG((
"53c700: sync 1 async 1.5\n"));
741 DEBUG((
"53c700: sync 1 async 1\n"));
751 min_period = 1000*(4+min_xferp)/(4*hostdata->
sync_clock);
798 switch(hostdata->
msgin[2]) {
805 if(offset == 0 || period == 0) {
821 NCR_700_writeb(NCR_700_get_SXFER(SCp->
device),
827 "Unexpected SDTR msg\n");
828 hostdata->
msgout[0] = A_REJECT_MSG;
834 resume_offset = hostdata->
pScript + Ent_SendMessageWithATN;
839 printk(
KERN_INFO "scsi%d: (%d:%d), Unsolicited WDTR after CMD, Rejecting\n",
841 hostdata->
msgout[0] = A_REJECT_MSG;
845 resume_offset = hostdata->
pScript + Ent_SendMessageWithATN;
852 NCR_700_phase[(dsps & 0xf00) >> 8]);
856 hostdata->
msgout[0] = A_REJECT_MSG;
862 resume_offset = hostdata->
pScript + Ent_SendMessageWithATN;
864 NCR_700_writel(temp, host,
TEMP_REG);
865 return resume_offset;
883 NCR_700_phase[(dsps & 0xf00) >> 8]);
888 switch(hostdata->
msgin[0]) {
905 "Rejected first tag queue attempt, turning off tag queueing\n");
909 SCp->
device->tagged_supported = 0;
913 "(%d:%d) Unexpected REJECT Message %s\n",
915 NCR_700_phase[(dsps & 0xf00) >> 8]);
920 case A_PARITY_ERROR_MSG:
925 case A_SIMPLE_TAG_MSG:
928 NCR_700_phase[(dsps & 0xf00) >> 8]);
934 NCR_700_phase[(dsps & 0xf00) >> 8]);
939 hostdata->
msgout[0] = A_REJECT_MSG;
945 resume_offset = hostdata->
pScript + Ent_SendMessageWithATN;
949 NCR_700_writel(temp, host,
TEMP_REG);
952 return resume_offset;
960 __u32 resume_offset = 0;
968 if(dsps == A_GOOD_STATUS_AFTER_STATUS) {
969 DEBUG((
" COMMAND COMPLETE, status=%02x\n",
973 NCR_700_set_tag_neg_state(SCp->
device,
985 "broken device is looping in contingent allegiance: ignoring\n");
989 NCR_700_get_sense_cmnd(SCp->
device);
992 printk(
" cmd %p has status %d, requesting sense\n",
993 SCp, hostdata->
status[0]);
1008 cmnd[1] = (SCp->
device->lun & 0x7) << 5;
1020 cmnd[7] = hostdata->
status[0];
1029 slot->
SG[1].pAddr = 0;
1064 }
else if((dsps & 0xfffff0f0) == A_UNEXPECTED_PHASE) {
1065 __u8 i = (dsps & 0xf00) >> 8;
1069 sbcl_to_string(NCR_700_readb(host,
SBCL_REG)));
1075 }
else if((dsps & 0xfffff000) == A_FATAL) {
1076 int i = (dsps & 0xfff);
1079 host->
host_no, pun,
lun, NCR_700_fatal_messages[i]);
1080 if(dsps == A_FATAL_ILLEGAL_MSG_LENGTH) {
1085 }
else if((dsps & 0xfffff0f0) == A_DISCONNECT) {
1086 #ifdef NCR_700_DEBUG
1087 __u8 i = (dsps & 0xf00) >> 8;
1089 printk(
"scsi%d: (%d:%d), DISCONNECTED (%d) %s\n",
1091 i, NCR_700_phase[i]);
1095 }
else if(dsps == A_RESELECTION_IDENTIFIED) {
1101 lun = hostdata->
msgin[0] & 0x1f;
1104 DEBUG((
"scsi%d: (%d:%d) RESELECTED!\n",
1105 host->
host_no, reselection_id, lun));
1110 host->
host_no, reselection_id, lun);
1113 if(hostdata->
msgin[1] == A_SIMPLE_TAG_MSG) {
1117 host->
host_no, reselection_id, lun, hostdata->
msgin[2]);
1123 "reselection is tag %d, slot %p(%d)\n",
1124 hostdata->
msgin[2], slot, slot->
tag);
1129 "no saved request for untagged cmd\n");
1136 printk(
KERN_ERR "scsi%d: (%d:%d) RESELECTED but no saved command (MSG = %02x %02x %02x)!!\n",
1137 host->
host_no, reselection_id, lun,
1139 hostdata->
msgin[2]);
1142 printk(
KERN_ERR "scsi%d: FATAL, host not busy during valid reselection!\n",
1149 CommandAddress, slot->
pCmd);
1151 CommandCount, slot->
cmnd->cmd_len);
1153 SGScriptStartAddress,
1161 NCR_700_writeb(NCR_700_get_SXFER(hostdata->
cmd->device),
1175 }
else if(dsps == A_RESELECTED_DURING_SELECTION) {
1188 reselection_id &= ~(1<<host->
this_id);
1192 printk(
KERN_INFO "scsi%d: (%d:%d) RESELECTION DURING SELECTION, dsp=%08x[%04x] state=%d, count=%d\n",
1205 printk(
KERN_INFO "IDENTIFIED SG segment as being %08x in slot %p, cmd %p, slot->resume_offset=%08x\n", SG, &hostdata->
slots[i], hostdata->
slots[i].cmnd, hostdata->
slots[i].resume_offset);
1206 SCp = hostdata->
slots[
i].cmnd;
1216 if(reselection_id == 0) {
1221 printk(
KERN_ERR "scsi%d: script reselected and we took a selection interrupt\n",
1228 reselection_id = bitmap_to_number(reselection_id);
1232 hostdata->
msgin[1] = 0;
1236 resume_offset = hostdata->
pScript + Ent_GetReselectionWithTag;
1238 resume_offset = hostdata->
pScript + Ent_GetReselectionData;
1240 }
else if(dsps == A_COMPLETED_SELECTION_AS_TARGET) {
1244 DEBUG((
" SELECTION COMPLETED\n"));
1245 }
else if((dsps & 0xfffff0f0) == A_MSG_IN) {
1248 }
else if((dsps & 0xfffff000) == 0) {
1249 __u8 i = (dsps & 0xf0) >> 4,
j = (dsps & 0xf00) >> 8;
1250 printk(
KERN_ERR "scsi%d: (%d:%d), unhandled script condition %s %s at %04x\n",
1251 host->
host_no, pun,
lun, NCR_700_condition[i],
1252 NCR_700_phase[
j], dsp - hostdata->
pScript);
1262 }
else if((dsps & 0xfffff000) == A_DEBUG_INTERRUPT) {
1263 printk(
KERN_NOTICE "scsi%d (%d:%d) DEBUG INTERRUPT %d AT %08x[%04x], continuing\n",
1265 resume_offset =
dsp;
1267 printk(
KERN_ERR "scsi%d: (%d:%d), unidentified script interrupt 0x%x at %04x\n",
1271 return resume_offset;
1286 __u32 resume_offset = 0;
1292 for(count = 0; count < 5; count++) {
1293 id = NCR_700_readb(host, hostdata->
chip710 ?
1302 sbcl = NCR_700_readb(host,
SBCL_REG);
1309 DEBUG((
"scsi%d: Reselected by %d\n",
1315 DEBUG((
" ID %d WARNING: RESELECTION OF BUSY HOST, saving cmd %p, slot %p, addr %x [%04x], resume %x!\n",
id, hostdata->
cmd, slot, dsp, dsp - hostdata->
pScript, resume_offset));
1317 switch(dsp - hostdata->
pScript) {
1318 case Ent_Disconnect1:
1319 case Ent_Disconnect2:
1322 case Ent_Disconnect3:
1323 case Ent_Disconnect4:
1326 case Ent_Disconnect5:
1327 case Ent_Disconnect6:
1330 case Ent_Disconnect7:
1331 case Ent_Disconnect8:
1347 hostdata->
msgin[1] = 0;
1353 resume_offset = hostdata->
pScript + Ent_SelectedAsTarget;
1355 resume_offset = hostdata->
pScript + Ent_GetReselectionWithTag;
1357 resume_offset = hostdata->
pScript + Ent_GetReselectionData;
1363 NCR_700_clear_fifo(
struct Scsi_Host *host) {
1374 NCR_700_flush_fifo(
struct Scsi_Host *host) {
1406 DEBUG((
"scsi%d: host busy, queueing command %p, slot %p\n",
1407 SCp->
device->host->host_no, slot->
cmnd, slot));
1411 hostdata->
cmd = SCp;
1434 count += scsi_populate_tag_msg(SCp, &hostdata->
msgout[count]);
1437 if(hostdata->
fast &&
1458 SGScriptStartAddress,
to32bit(&slot->
pSG[0].ins));
1459 NCR_700_clear_fifo(SCp->
device->host);
1471 NCR_700_writeb(NCR_700_get_SXFER(SCp->
device),
1486 __u32 resume_offset = 0;
1488 unsigned long flags;
1497 if((istat = NCR_700_readb(host,
ISTAT_REG))
1506 state = hostdata->
state;
1507 SCp = hostdata->
cmd;
1521 dsps = NCR_700_readl(host,
DSPS_REG);
1522 dsp = NCR_700_readl(host,
DSP_REG);
1524 DEBUG((
"scsi%d: istat %02x sstat0 %02x dstat %02x dsp %04x[%08x] dsps 0x%x\n",
1540 printk(
KERN_ERR "scsi%d: Bus Reset detected, executing command %p, slot %p, dsp %08x[%04x]\n",
1547 NCR_700_clear_flag(SDp, ~0);
1559 printk(
KERN_ERR " failing command because of reset, slot %p, cmnd %p\n",
1563 NCR_700_set_depth(SCp->
device, 0);
1583 DEBUG((
"scsi%d: (%d:%d) selection timeout\n",
1590 if(dsp == Ent_SendMessage + 8 + hostdata->
pScript) {
1593 #ifdef NCR_700_DEBUG
1595 int count = (hostdata->
script[Ent_SendMessage/4] & 0xffffff) - ((NCR_700_readl(host,
DBC_REG) & 0xffffff) + NCR_700_data_residual(host));
1596 printk(
"scsi%d (%d:%d) PHASE MISMATCH IN SEND MESSAGE %d remain, return %p[%04x], phase %s\n", host->
host_no, pun,
lun, count, (
void *)temp, temp - hostdata->
pScript, sbcl_to_string(NCR_700_readb(host,
SBCL_REG)));
1599 }
else if(dsp >=
to32bit(&slot->
pSG[0].ins) &&
1601 int data_transfer = NCR_700_readl(host,
DBC_REG) & 0xffffff;
1603 int residual = NCR_700_data_residual(host);
1605 #ifdef NCR_700_DEBUG
1608 printk(
"scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x\n",
1610 SGcount, data_transfer);
1613 printk(
"scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x, residual %d\n",
1615 SGcount, data_transfer, residual);
1620 if(data_transfer != 0) {
1626 count = (
bS_to_cpu(slot->
SG[SGcount].ins) & 0x00ffffff);
1627 DEBUG((
"DATA TRANSFER MISMATCH, count = %d, transferred %d\n", count, count-data_transfer));
1631 pAddr += (count - data_transfer);
1632 #ifdef NCR_700_DEBUG
1633 if(pAddr != naddr) {
1634 printk(
"scsi%d (%d:%d) transfer mismatch pAddr=%lx, naddr=%lx, data_transfer=%d, residual=%d\n", host->
host_no, pun,
lun, (
unsigned long)pAddr, (
unsigned long)naddr, data_transfer, residual);
1640 for(i=0; i<SGcount; i++) {
1642 slot->
SG[
i].pAddr = 0;
1649 NCR_700_flush_fifo(host);
1652 printk(
KERN_ERR "scsi%d: (%d:%d) phase mismatch at %04x, phase %s\n",
1666 DEBUG((
"scsi%d: (%d:%d) ====>SCRIPT INTERRUPT<====\n",
1670 printk(
KERN_ERR "scsi%d: (%d:%d) Illegal Instruction detected at 0x%08x[0x%x]!!!\n"
1673 dsp, dsp - hostdata->
pScript);
1676 printk(
KERN_ERR "scsi%d: (%d:%d) serious DMA problem, dstat=%02x\n",
1711 printk(
KERN_ERR "scsi%d: Driver error: resume at 0x%08x [0x%04x] with non busy host!\n",
1717 NCR_700_clear_fifo(host);
1732 % NCR_700_COMMAND_SLOTS_PER_HOST;
1737 DEBUG((
"scsi%d: Issuing saved command slot %p, cmd %p\t\n",
1739 hostdata->
slots[j].cmnd));
1772 if(NCR_700_get_depth(SCp->
device) != 0
1774 || !blk_rq_tagged(SCp->
request))) {
1776 NCR_700_get_depth(SCp->
device));
1779 if(NCR_700_get_depth(SCp->
device) >= SCp->
device->queue_depth) {
1781 NCR_700_get_depth(SCp->
device));
1784 NCR_700_set_depth(SCp->
device, NCR_700_get_depth(SCp->
device) + 1);
1798 #ifdef NCR_700_DEBUG
1799 printk(
"53c700: scsi%d, command ", SCp->
device->host->host_no);
1802 if(blk_rq_tagged(SCp->
request)
1816 if(!blk_rq_tagged(SCp->
request)
1823 && scsi_get_tag_type(SCp->
device)) {
1830 SCp->
device->current_cmnd = SCp;
1834 if(!scsi_sg_count(SCp) && !scsi_bufflen(SCp) &&
1836 #ifdef NCR_700_DEBUG
1837 printk(
"53c700: Command");
1844 switch (SCp->
cmnd[0]) {
1888 DEBUG((
" scatter block %d: move %d[%08x] from 0x%lx\n",
1889 i, count,
slot->SG[i].ins, (
unsigned long)vPtr));
1893 slot->SG[
i].pAddr = 0;
1895 DEBUG((
" SETTING %08lx to %x\n",
1896 (&
slot->pSG[i].ins),
1899 slot->resume_offset = 0;
1914 "New error handler wants to abort command\n\t");
1948 "New error handler wants BUS reset, cmd %p\n\t", SCp);
1954 spin_lock_irq(SCp->
device->host->host_lock);
1956 spin_unlock_irq(SCp->
device->host->host_lock);
1958 spin_lock_irq(SCp->
device->host->host_lock);
1964 spin_unlock_irq(SCp->
device->host->host_lock);
1966 spin_lock_irq(SCp->
device->host->host_lock);
1973 spin_unlock_irq(SCp->
device->host->host_lock);
1983 spin_lock_irq(SCp->
device->host->host_lock);
1988 spin_unlock_irq(SCp->
device->host->host_lock);
2003 if(period < hostdata->min_period)
2018 int max_offset = hostdata->
chip710
2024 if(offset > max_offset)
2025 offset = max_offset;
2065 if(hostdata->
fast) {
2098 int change_tag = ((tag_type ==0 && scsi_get_tag_type(SDp) != 0)
2099 || (tag_type != 0 && scsi_get_tag_type(SDp) == 0));
2103 scsi_set_tag_type(SDp, tag_type);
2115 scsi_deactivate_tcq(SDp, SDp->
host->cmd_per_lun);
2135 return snprintf(buf, 20,
"%d\n", NCR_700_get_depth(SDp));
2140 .name =
"active_tags",
2143 .show = NCR_700_show_active_tags,
2147 &NCR_700_active_tags_attr,
2162 static int __init NCR_700_init(
void)
2165 if(!NCR_700_transport_template)
2170 static void __exit NCR_700_exit(
void)