79 #include <linux/module.h>
81 #include <linux/string.h>
87 #include <scsi/scsi.h>
96 #define optimum_sx_per(hostdata) (hostdata)->sx_table[1].period_ns
99 #define WD33C93_VERSION "1.26++"
100 #define WD33C93_DATE "10/Feb/2007"
167 static char *setup_args[] = {
"",
"",
"",
"",
"",
"",
"",
"",
"",
"" };
169 static char *setup_strings;
172 static void wd33c93_execute(
struct Scsi_Host *instance);
174 #ifdef CONFIG_WD33C93_PIO
185 static inline unsigned long
214 outb((value >> 16) & 0xff, regs.
SCMD);
215 outb((value >> 8) & 0xff, regs.
SCMD);
219 #define write_wd33c93_cmd(regs, cmd) \
220 write_wd33c93((regs), WD_COMMAND, (cmd))
228 for (i=0; i<len; i++)
236 *regs.
SASR = reg_num;
248 value = *regs.
SCMD << 16;
249 value |= *regs.
SCMD << 8;
264 *regs.
SASR = reg_num;
271 write_wd33c93_count(
const wd33c93_regs regs,
unsigned long value)
275 *regs.
SCMD = value >> 16;
276 *regs.
SCMD = value >> 8;
296 for (i = 0; i < len; i++)
297 *regs.
SCMD = cmnd[i];
310 asr = read_aux_stat(regs);
312 x = read_wd33c93(regs,
WD_DATA);
323 if ((period <= sx_table[x - 0].period_ns) &&
324 (period > sx_table[x - 1].period_ns)) {
335 calc_sync_xfer(
unsigned int period,
unsigned int offset,
unsigned int fast,
343 if (offset && fast) {
350 result = sx_table[round_period(period,sx_table)].
reg_value;
360 calc_sync_msg(
unsigned int period,
unsigned int offset,
unsigned int fast,
410 if (scsi_bufflen(cmd)) {
411 cmd->
SCp.buffer = scsi_sglist(cmd);
412 cmd->
SCp.buffers_residual = scsi_sg_count(cmd) - 1;
413 cmd->
SCp.ptr = sg_virt(cmd->
SCp.buffer);
414 cmd->
SCp.this_residual = cmd->
SCp.buffer->length;
417 cmd->
SCp.buffers_residual = 0;
419 cmd->
SCp.this_residual = 0;
447 spin_lock_irq(&hostdata->
lock);
463 wd33c93_execute(cmd->
device->host);
467 spin_unlock_irq(&hostdata->lock);
505 if (!(hostdata->
busy[cmd->device->id] & (1 << cmd->device->lun)))
508 cmd = (
struct scsi_cmnd *) cmd->host_scribble;
525 #ifdef PROC_STATISTICS
526 hostdata->
cmd_cnt[cmd->device->id]++;
566 if (cmd->device->type == 1)
574 if ((
prev->device->id != cmd->device->id) ||
575 (
prev->device->lun != cmd->device->lun)) {
588 #ifdef PROC_STATISTICS
599 hostdata->
busy[cmd->device->id] |= (1 << cmd->device->lun);
629 write_wd33c93_count(regs, 0);
648 write_wd33c93_cdb(regs, cmd->cmd_len, cmd->cmnd);
656 write_wd33c93(regs,
WD_OWN_ID, cmd->cmd_len);
663 if ((cmd->SCp.phase == 0) && (hostdata->
no_dma == 0)) {
667 write_wd33c93_count(regs, 0);
669 write_wd33c93_count(regs,
670 cmd->SCp.this_residual);
676 write_wd33c93_count(regs, 0);
690 printk(
"%s)EX-2 ", (cmd->SCp.phase) ?
"d:" :
""))
700 printk(
"(%p,%d,%s:", buf, cnt, data_in_dir ?
"in" :
"out"))
703 write_wd33c93_count(regs, cnt);
707 asr = read_aux_stat(regs);
709 *buf++ = read_wd33c93(regs,
WD_DATA);
713 asr = read_aux_stat(regs);
715 write_wd33c93(regs,
WD_DATA, *buf++);
745 if (!cmd->
SCp.this_residual && cmd->
SCp.buffers_residual) {
747 --cmd->
SCp.buffers_residual;
748 cmd->
SCp.this_residual = cmd->
SCp.buffer->length;
749 cmd->
SCp.ptr = sg_virt(cmd->
SCp.buffer);
751 if (!cmd->
SCp.this_residual)
762 #ifdef PROC_STATISTICS
765 transfer_pio(regs, (
uchar *) cmd->
SCp.ptr,
766 cmd->
SCp.this_residual, data_in_dir, hostdata);
767 length = cmd->
SCp.this_residual;
768 cmd->
SCp.this_residual = read_wd33c93_count(regs);
769 cmd->
SCp.ptr += (length - cmd->
SCp.this_residual);
782 #ifdef PROC_STATISTICS
786 write_wd33c93_count(regs, cmd->
SCp.this_residual);
794 write_wd33c93_cmd(regs, WD_CMD_TRANS_INFO);
808 unsigned long length,
flags;
810 asr = read_aux_stat(regs);
816 #ifdef PROC_STATISTICS
842 printk(
"[%p/%d:", cmd->
SCp.ptr, cmd->
SCp.this_residual))
845 length = cmd->
SCp.this_residual;
846 cmd->
SCp.this_residual = read_wd33c93_count(regs);
847 cmd->
SCp.ptr += (length - cmd->
SCp.this_residual);
879 spin_unlock_irqrestore(&hostdata->
lock,
flags);
885 wd33c93_execute(instance);
927 printk(
" sending SDTR %02x03%02x%02x%02x ",
928 ucp[0], ucp[2], ucp[3], ucp[4]);
934 spin_unlock_irqrestore(&hostdata->
lock,
flags);
941 printk(
"IN-%d.%d", cmd->
SCp.this_residual,
942 cmd->
SCp.buffers_residual))
946 spin_unlock_irqrestore(&hostdata->
lock,
flags);
953 printk(
"OUT-%d.%d", cmd->
SCp.this_residual,
954 cmd->
SCp.buffers_residual))
958 spin_unlock_irqrestore(&hostdata->
lock,
flags);
970 spin_unlock_irqrestore(&hostdata->
lock,
flags);
977 cmd->
SCp.Status = read_1_byte(regs);
988 spin_unlock_irqrestore(&hostdata->
lock,
flags);
996 msg = read_1_byte(regs);
1035 cmd->
device->disconnect = 1;
1072 id = calc_sync_xfer(hostdata->
1073 default_sx_per / 4, 0,
1093 calc_sync_msg(hostdata->
1099 id = calc_sync_xfer(ucp[3], ucp[4],
1103 id = calc_sync_xfer(ucp[3], ucp[4],
1108 printk(
" sync_xfer=%02x\n",
1113 write_wd33c93_cmd(regs,
1127 write_wd33c93_cmd(regs,
1134 (
"Rejecting Unknown Extended Message(%02x). ",
1139 write_wd33c93_cmd(regs,
1157 printk(
"Rejecting Unknown Message(%02x) ", msg);
1164 spin_unlock_irqrestore(&hostdata->
lock,
flags);
1193 cmd->
SCp.Status | (cmd->
SCp.Message << 8);
1199 spin_unlock_irqrestore(&hostdata->
lock,
flags);
1200 wd33c93_execute(instance);
1203 (
"%02x:%02x:%02x: Unknown SEL_XFER_DONE phase!!---",
1205 spin_unlock_irqrestore(&hostdata->
lock,
flags);
1216 spin_unlock_irqrestore(&hostdata->
lock,
flags);
1245 spin_unlock_irqrestore(&hostdata->
lock,
flags);
1264 printk(
" - Already disconnected! ");
1266 spin_unlock_irqrestore(&hostdata->
lock,
flags);
1277 cmd->
result = cmd->
SCp.Status | (cmd->
SCp.Message << 8);
1284 spin_unlock_irqrestore(&hostdata->
lock,
flags);
1285 wd33c93_execute(instance);
1297 printk(
" - Already disconnected! ");
1300 switch (hostdata->
state) {
1313 cmd->
SCp.Status | (cmd->
SCp.Message << 8);
1329 printk(
"*** Unexpected DISCONNECT interrupt! ***");
1336 spin_unlock_irqrestore(&hostdata->
lock,
flags);
1337 wd33c93_execute(instance);
1368 ~(1 << cmd->
device->lun);
1374 (
"---%02x:%02x:%02x-TROUBLE: Intrusive ReSelect!---",
1401 if ((asr = read_aux_stat(regs)) & ASR_INT)
1405 if (!(asr & ASR_INT)) {
1407 (
"wd33c93: Reselected without IDENTIFY\n");
1417 lun = read_1_byte(regs);
1419 asr = read_aux_stat(regs);
1420 if (!(asr & ASR_INT)) {
1422 asr = read_aux_stat(regs);
1423 if (!(asr & ASR_INT))
1425 (
"wd33c93: No int after LUN on RESEL (%02x)\n",
1432 (
"wd33c93: Not paused with ACK on RESEL (%02x)\n",
1435 write_wd33c93_cmd(regs,
1439 (
"wd33c93: Not MSG_IN on reselect (%02x)\n",
1461 (
"---TROUBLE: target %d.%d not in disconnect queue---",
1463 spin_unlock_irqrestore(&hostdata->
lock,
flags);
1487 write_wd33c93_count(regs, 0);
1494 spin_unlock_irqrestore(&hostdata->
lock,
flags);
1498 printk(
"--UNKNOWN INTERRUPT:%02x:%02x:%02x--", asr,
sr, phs);
1499 spin_unlock_irqrestore(&hostdata->
lock,
flags);
1507 reset_wd33c93(
struct Scsi_Host *instance)
1514 #ifdef CONFIG_SGI_IP22
1519 while ((read_aux_stat(regs) &
ASR_BSY) && busycount++ < 100)
1529 if (read_aux_stat(regs) &
ASR_BSY)
1543 #ifdef CONFIG_MVME147_SCSI
1547 while (!(read_aux_stat(regs) &
ASR_INT))
1554 else if (
sr == 0x01) {
1579 instance = SCpnt->
device->host;
1585 hostdata->
dma_stop(instance, NULL, 0);
1586 for (i = 0; i < 8; i++) {
1587 hostdata->
busy[
i] = 0;
1602 reset_wd33c93(instance);
1618 instance = cmd->
device->host;
1620 regs = hostdata->
regs;
1639 (
"scsi%d: Abort - removing command from input_Q. ",
1664 printk(
"scsi%d: Aborting connected command - ",
1667 printk(
"stopping DMA - ");
1669 hostdata->
dma_stop(instance, cmd, 0);
1673 printk(
"sending wd33c93 ABORT command - ");
1674 write_wd33c93(regs, WD_CONTROL,
1680 printk(
"flushing fifo - ");
1683 asr = read_aux_stat(regs);
1686 }
while (!(asr & ASR_INT) && timeout-- > 0);
1689 (
"asr=%02x, sr=%02x, %ld bytes un-transferred (timeout=%ld) - ",
1690 asr, sr, read_wd33c93_count(regs), timeout);
1698 printk(
"sending wd33c93 DISCONNECT command - ");
1702 asr = read_aux_stat(regs);
1703 while ((asr &
ASR_CIP) && timeout-- > 0)
1704 asr = read_aux_stat(regs);
1706 printk(
"asr=%02x, sr=%02x.", asr, sr);
1714 wd33c93_execute(instance);
1731 (
"scsi%d: Abort - command found on disconnected_Q - ",
1733 printk(
"Abort SNOOZE. ");
1751 wd33c93_execute(instance);
1754 printk(
"scsi%d: warning : SCSI command probably completed successfully"
1755 " before abortion. ", instance->
host_no);
1759 #define MAX_WD33C93_HOSTS 4
1760 #define MAX_SETUP_ARGS ARRAY_SIZE(setup_args)
1761 #define SETUP_BUFFER_SIZE 200
1764 static int done_setup = 0;
1767 wd33c93_setup(
char *
str)
1807 __setup(
"wd33c93=", wd33c93_setup);
1812 check_setup_args(
char *
key,
int *
flags,
int *
val,
char *buf)
1825 if (x == MAX_SETUP_ARGS)
1828 cp = setup_args[
x] +
strlen(key);
1833 if ((*cp >=
'0') && (*cp <=
'9')) {
1856 static inline unsigned int
1857 round_4(
unsigned int x)
1869 calc_sx_table(
unsigned int mhz,
struct sx_period sx_table[9])
1879 d = (100000 *
d) / 2 / mhz;
1883 for (i = 1; i < 8; i++) {
1884 sx_table[
i].
period_ns = round_4((i+1)*d / 100);
1896 set_clk_freq(
int freq,
int *mhz)
1905 else if (freq > 7 && freq < 11)
1907 else if (freq > 11 && freq < 16)
1909 else if (freq > 15 && freq < 21)
1926 for (i = 0; i < 8; i++)
1927 if (mask & (1 << i))
1941 if (!done_setup && setup_strings)
1942 wd33c93_setup(setup_strings);
1946 hostdata->
regs = regs;
1947 hostdata->
clock_freq = set_clk_freq(clock_freq, &i);
1948 calc_sx_table(i, hostdata->
sx_table);
1953 for (i = 0; i < 8; i++) {
1954 hostdata->
busy[
i] = 0;
1959 #ifdef PROC_STATISTICS
1979 #ifdef PROC_INTERFACE
1982 #ifdef PROC_STATISTICS
1989 if (check_setup_args(
"clock", &flags, &val, buf)) {
1990 hostdata->
clock_freq = set_clk_freq(val, &val);
1991 calc_sx_table(val, hostdata->
sx_table);
1994 if (check_setup_args(
"nosync", &flags, &val, buf))
1997 if (check_setup_args(
"nodma", &flags, &val, buf))
1998 hostdata->
no_dma = (val == -1) ? 1 : val;
2000 if (check_setup_args(
"period", &flags, &val, buf))
2002 hostdata->
sx_table[round_period((
unsigned int)
val,
2005 if (check_setup_args(
"disconnect", &flags, &val, buf)) {
2012 if (check_setup_args(
"level2", &flags, &val, buf))
2015 if (check_setup_args(
"debug", &flags, &val, buf))
2018 if (check_setup_args(
"burst", &flags, &val, buf))
2022 && check_setup_args(
"fast", &flags, &val, buf))
2023 hostdata->
fast = !!val;
2025 if ((i = check_setup_args(
"next", &flags, &val, buf))) {
2027 setup_used[--
i] = 1;
2029 #ifdef PROC_INTERFACE
2030 if (check_setup_args(
"proc", &flags, &val, buf))
2031 hostdata->
proc = val;
2034 spin_lock_irq(&hostdata->
lock);
2035 reset_wd33c93(instance);
2036 spin_unlock_irq(&hostdata->
lock);
2038 printk(
"wd33c93-%d: chip=%s/%d no_sync=0x%x no_dma=%d",
2042 "WD33c93A" : (hostdata->
chip ==
2046 printk(
" debug_flags=0x%02x\n", hostdata->
args);
2048 printk(
" debugging=OFF\n");
2052 printk(
"%s,", setup_args[i]);
2061 #ifdef PROC_INTERFACE
2068 static int stop = 0;
2088 for (bp = buf; *bp; ) {
2089 while (
',' == *bp ||
' ' == *bp)
2091 if (!
strncmp(bp,
"debug:", 6)) {
2093 }
else if (!
strncmp(bp,
"disconnect:", 11)) {
2098 }
else if (!
strncmp(bp,
"period:", 7)) {
2101 hd->
sx_table[round_period((
unsigned int) x,
2103 }
else if (!
strncmp(bp,
"resync:", 7)) {
2105 }
else if (!
strncmp(bp,
"proc:", 5)) {
2107 }
else if (!
strncmp(bp,
"nodma:", 6)) {
2109 }
else if (!
strncmp(bp,
"level2:", 7)) {
2111 }
else if (!
strncmp(bp,
"burst:", 6)) {
2114 }
else if (!
strncmp(bp,
"fast:", 5)) {
2117 set_resync(hd, 0xff);
2119 }
else if (!
strncmp(bp,
"nosync:", 7)) {
2121 set_resync(hd, x ^ hd->
no_sync);
2130 spin_lock_irq(&hd->
lock);
2134 sprintf(tbuf,
"\nVersion %s - %s.",
2139 sprintf(tbuf,
"\nclock_freq=%02x no_sync=%02x no_dma=%d"
2140 " dma_mode=%02x fast=%d",
2143 strcat(bp,
"\nsync_xfer[] = ");
2144 for (x = 0; x < 7; x++) {
2148 strcat(bp,
"\nsync_stat[] = ");
2149 for (x = 0; x < 7; x++) {
2154 #ifdef PROC_STATISTICS
2156 strcat(bp,
"\ncommands issued: ");
2157 for (x = 0; x < 7; x++) {
2161 strcat(bp,
"\ndisconnects allowed:");
2162 for (x = 0; x < 7; x++) {
2166 strcat(bp,
"\ndisconnects done: ");
2167 for (x = 0; x < 7; x++) {
2172 "\ninterrupts: %ld, DATA_PHASE ints: %ld DMA, %ld PIO",
2178 strcat(bp,
"\nconnected: ");
2187 strcat(bp,
"\ninput_Q: ");
2197 strcat(bp,
"\ndisconnected_Q:");
2207 spin_unlock_irq(&hd->
lock);