fas216.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:74k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/arch/arm/drivers/scsi/fas216.c
  3.  *
  4.  *  Copyright (C) 1997-2000 Russell King
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License version 2 as
  8.  * published by the Free Software Foundation.
  9.  *
  10.  * Based on information in qlogicfas.c by Tom Zerucha, Michael Griffith, and
  11.  * other sources, including:
  12.  *   the AMD Am53CF94 data sheet
  13.  *   the AMD Am53C94 data sheet 
  14.  *
  15.  * This is a generic driver.  To use it, have a look at cumana_2.c.  You
  16.  * should define your own structure that overlays FAS216_Info, eg:
  17.  * struct my_host_data {
  18.  *    FAS216_Info info;
  19.  *    ... my host specific data ...
  20.  * };
  21.  *
  22.  * Changelog:
  23.  *  30-08-1997 RMK Created
  24.  *  14-09-1997 RMK Started disconnect support
  25.  *  08-02-1998 RMK Corrected real DMA support
  26.  *  15-02-1998 RMK Started sync xfer support
  27.  *  06-04-1998 RMK Tightened conditions for printing incomplete
  28.  * transfers
  29.  *  02-05-1998 RMK Added extra checks in fas216_reset
  30.  *  24-05-1998 RMK Fixed synchronous transfers with period >= 200ns
  31.  *  27-06-1998 RMK Changed asm/delay.h to linux/delay.h
  32.  *  26-08-1998 RMK Improved message support wrt MESSAGE_REJECT
  33.  *  02-04-2000 RMK Converted to use the new error handling, and
  34.  * automatically request sense data upon check
  35.  * condition status from targets.
  36.  *
  37.  * Todo:
  38.  *  - allow individual devices to enable sync xfers.
  39.  */
  40. #include <linux/module.h>
  41. #include <linux/blk.h>
  42. #include <linux/kernel.h>
  43. #include <linux/string.h>
  44. #include <linux/ioport.h>
  45. #include <linux/sched.h>
  46. #include <linux/proc_fs.h>
  47. #include <linux/unistd.h>
  48. #include <linux/stat.h>
  49. #include <linux/delay.h>
  50. #include <linux/init.h>
  51. #include <asm/dma.h>
  52. #include <asm/io.h>
  53. #include <asm/irq.h>
  54. #include <asm/ecard.h>
  55. #define FAS216_C
  56. #include "../../scsi/scsi.h"
  57. #include "../../scsi/hosts.h"
  58. #include "fas216.h"
  59. #define VER_MAJOR 0
  60. #define VER_MINOR 0
  61. #define VER_PATCH 5
  62. /* NOTE: SCSI2 Synchronous transfers *require* DMA according to
  63.  *  the data sheet.  This restriction is crazy, especially when
  64.  *  you only want to send 16 bytes!  What were the guys who
  65.  *  designed this chip on at that time?  Did they read the SCSI2
  66.  *  spec at all?  The following sections are taken from the SCSI2
  67.  *  standard (s2r10) concerning this:
  68.  *
  69.  * > IMPLEMENTORS NOTES:
  70.  * >   (1)  Re-negotiation at every selection is not recommended, since a
  71.  * >   significant performance impact is likely.
  72.  *
  73.  * >  The implied synchronous agreement shall remain in effect until a BUS DEVICE
  74.  * >  RESET message is received, until a hard reset condition occurs, or until one
  75.  * >  of the two SCSI devices elects to modify the agreement.  The default data
  76.  * >  transfer mode is asynchronous data transfer mode.  The default data transfer
  77.  * >  mode is entered at power on, after a BUS DEVICE RESET message, or after a hard
  78.  * >  reset condition.
  79.  *
  80.  *  In total, this means that once you have elected to use synchronous
  81.  *  transfers, you must always use DMA.
  82.  *
  83.  *  I was thinking that this was a good chip until I found this restriction ;(
  84.  */
  85. #define SCSI2_SYNC
  86. #undef  SCSI2_WIDE
  87. #undef  SCSI2_TAG
  88. #undef DEBUG_CONNECT
  89. #undef DEBUG_BUSSERVICE
  90. #undef DEBUG_FUNCTIONDONE
  91. #undef DEBUG_MESSAGES
  92. #undef CHECK_STRUCTURE
  93. static struct { int stat, ssr, isr, ph; } list[8];
  94. static int ptr;
  95. static void fas216_dumpstate(FAS216_Info *info)
  96. {
  97. unsigned char is, stat, inst;
  98. is   = inb(REG_IS(info));
  99. stat = inb(REG_STAT(info));
  100. inst = inb(REG_INST(info));
  101. printk("FAS216: CTCL=%02X CTCM=%02X CMD=%02X STAT=%02X"
  102.        " INST=%02X IS=%02X CFIS=%02X",
  103. inb(REG_CTCL(info)), inb(REG_CTCM(info)),
  104. inb(REG_CMD(info)),  stat, inst, is,
  105. inb(REG_CFIS(info)));
  106. printk(" CNTL1=%02X CNTL2=%02X CNTL3=%02X CTCH=%02Xn",
  107. inb(REG_CNTL1(info)), inb(REG_CNTL2(info)),
  108. inb(REG_CNTL3(info)), inb(REG_CTCH(info)));
  109. }
  110. static void fas216_dumpinfo(FAS216_Info *info)
  111. {
  112. static int used = 0;
  113. int i;
  114. if (used++)
  115. return;
  116. printk("FAS216_Info=n");
  117. printk("  { magic_start=%lX host=%p SCpnt=%p origSCpnt=%pn",
  118. info->magic_start, info->host, info->SCpnt,
  119. info->origSCpnt);
  120. printk("    scsi={ io_port=%X io_shift=%X irq=%X cfg={ %X %X %X %X }n",
  121. info->scsi.io_port, info->scsi.io_shift, info->scsi.irq,
  122. info->scsi.cfg[0], info->scsi.cfg[1], info->scsi.cfg[2],
  123. info->scsi.cfg[3]);
  124. printk("           type=%p phase=%X reconnected={ target=%d lun=%d tag=%d }n",
  125. info->scsi.type, info->scsi.phase,
  126. info->scsi.reconnected.target,
  127. info->scsi.reconnected.lun, info->scsi.reconnected.tag);
  128. printk("           SCp={ ptr=%p this_residual=%X buffer=%p buffers_residual=%X }n",
  129. info->scsi.SCp.ptr, info->scsi.SCp.this_residual,
  130. info->scsi.SCp.buffer, info->scsi.SCp.buffers_residual);
  131. printk("      msgs async_stp=%X disconnectable=%d aborting=%d }n",
  132. info->scsi.async_stp,
  133. info->scsi.disconnectable, info->scsi.aborting);
  134. printk("    stats={ queues=%X removes=%X fins=%X reads=%X writes=%X miscs=%Xn"
  135.        "            disconnects=%X aborts=%X bus_resets=%X host_resets=%X}n",
  136. info->stats.queues, info->stats.removes, info->stats.fins,
  137. info->stats.reads, info->stats.writes, info->stats.miscs,
  138. info->stats.disconnects, info->stats.aborts, info->stats.bus_resets,
  139. info->stats.host_resets);
  140. printk("    ifcfg={ clockrate=%X select_timeout=%X asyncperiod=%X sync_max_depth=%X }n",
  141. info->ifcfg.clockrate, info->ifcfg.select_timeout,
  142. info->ifcfg.asyncperiod, info->ifcfg.sync_max_depth);
  143. for (i = 0; i < 8; i++) {
  144. printk("    busyluns[%d]=%X dev[%d]={ disconnect_ok=%d stp=%X sof=%X sync_state=%X }n",
  145. i, info->busyluns[i], i,
  146. info->device[i].disconnect_ok, info->device[i].stp,
  147. info->device[i].sof, info->device[i].sync_state);
  148. }
  149. printk("    dma={ transfer_type=%X setup=%p pseudo=%p stop=%p }n",
  150. info->dma.transfer_type, info->dma.setup,
  151. info->dma.pseudo, info->dma.stop);
  152. printk("    internal_done=%X magic_end=%lX }n",
  153. info->internal_done, info->magic_end);
  154. }
  155. #ifdef CHECK_STRUCTURE
  156. static void __fas216_checkmagic(FAS216_Info *info, const char *func)
  157. {
  158. int corruption = 0;
  159. if (info->magic_start != MAGIC) {
  160. printk(KERN_CRIT "FAS216 Error: magic at start corruptedn");
  161. corruption++;
  162. }
  163. if (info->magic_end != MAGIC) {
  164. printk(KERN_CRIT "FAS216 Error: magic at end corruptedn");
  165. corruption++;
  166. }
  167. if (corruption) {
  168. fas216_dumpinfo(info);
  169. panic("scsi memory space corrupted in %s", func);
  170. }
  171. }
  172. #define fas216_checkmagic(info) __fas216_checkmagic((info), __FUNCTION__)
  173. #else
  174. #define fas216_checkmagic(info)
  175. #endif
  176. static const char *fas216_bus_phase(int stat)
  177. {
  178. static const char *phases[] = {
  179. "DATA OUT", "DATA IN",
  180. "COMMAND", "STATUS",
  181. "MISC OUT", "MISC IN",
  182. "MESG OUT", "MESG IN"
  183. };
  184. return phases[stat & STAT_BUSMASK];
  185. }
  186. static const char *fas216_drv_phase(FAS216_Info *info)
  187. {
  188. switch (info->scsi.phase) {
  189. case PHASE_IDLE: return "idle";
  190. case PHASE_SELECTION: return "selection";
  191. case PHASE_COMMAND: return "command";
  192. case PHASE_RECONNECTED: return "reconnected";
  193. case PHASE_DATAOUT: return "data out";
  194. case PHASE_DATAIN: return "data in";
  195. case PHASE_MSGIN: return "message in";
  196. case PHASE_MSGIN_DISCONNECT: return "disconnect";
  197. case PHASE_MSGOUT_EXPECT: return "expect message out";
  198. case PHASE_MSGOUT: return "message out";
  199. case PHASE_STATUS: return "status";
  200. case PHASE_DONE: return "done";
  201. default: return "???";
  202. }
  203. }
  204. static char fas216_target(FAS216_Info *info)
  205. {
  206. if (info->SCpnt)
  207. return '0' + info->SCpnt->target;
  208. else
  209. return 'H';
  210. }
  211. static void add_debug_list(int stat, int ssr, int isr, int ph)
  212. {
  213. list[ptr].stat = stat;
  214. list[ptr].ssr = ssr;
  215. list[ptr].isr = isr;
  216. list[ptr].ph = ph;
  217. ptr = (ptr + 1) & 7;
  218. }
  219. static void print_debug_list(void)
  220. {
  221. int i;
  222. i = ptr;
  223. printk(KERN_ERR "SCSI IRQ trail: ");
  224. do {
  225. printk("%02X:%02X:%02X:%1X ",
  226. list[i].stat, list[i].ssr,
  227. list[i].isr, list[i].ph);
  228. i = (i + 1) & 7;
  229. } while (i != ptr);
  230. printk("n");
  231. }
  232. static void fas216_done(FAS216_Info *info, unsigned int result);
  233. /* Function: int fas216_clockrate(unsigned int clock)
  234.  * Purpose : calculate correct value to be written into clock conversion
  235.  *      factor register.
  236.  * Params  : clock - clock speed in MHz
  237.  * Returns : CLKF_ value
  238.  */
  239. static int fas216_clockrate(int clock)
  240. {
  241. if (clock <= 10 || clock > 40) {
  242. printk(KERN_CRIT
  243.        "fas216: invalid clock rate: check your driver!n");
  244. clock = -1;
  245. } else
  246. clock = ((clock - 1) / 5 + 1) & 7;
  247. return clock;
  248. }
  249. /* Function: unsigned short fas216_get_last_msg(FAS216_Info *info, int pos)
  250.  * Purpose : retrieve a last message from the list, using position in fifo
  251.  * Params  : info - interface to search
  252.  *         : pos  - current fifo position
  253.  */
  254. static inline unsigned short
  255. fas216_get_last_msg(FAS216_Info *info, int pos)
  256. {
  257. unsigned short packed_msg = NOP;
  258. struct message *msg;
  259. int msgnr = 0;
  260. while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
  261. if (pos >= msg->fifo)
  262. break;
  263. }
  264. if (msg) {
  265. if (msg->msg[0] == EXTENDED_MESSAGE)
  266. packed_msg = EXTENDED_MESSAGE | msg->msg[2] << 8;
  267. else
  268. packed_msg = msg->msg[0];
  269. }
  270. #ifdef DEBUG_MESSAGES
  271. printk("Message: %04X found at position %02Xn",
  272. packed_msg, pos);
  273. #endif
  274. return packed_msg;
  275. }
  276. /* Function: int fas216_syncperiod(FAS216_Info *info, int ns)
  277.  * Purpose : Calculate value to be loaded into the STP register
  278.  *           for a given period in ns
  279.  * Params  : info - state structure for interface connected to device
  280.  *         : ns   - period in ns (between subsequent bytes)
  281.  * Returns : Value suitable for REG_STP
  282.  */
  283. static int
  284. fas216_syncperiod(FAS216_Info *info, int ns)
  285. {
  286. int value = (info->ifcfg.clockrate * ns) / 1000;
  287. fas216_checkmagic(info);
  288. if (value < 4)
  289. value = 4;
  290. else if (value > 35)
  291. value = 35;
  292. return value & 31;
  293. }
  294. /* Function: void fas216_set_sync(FAS216_Info *info, int target)
  295.  * Purpose : Correctly setup FAS216 chip for specified transfer period.
  296.  * Params  : info   - state structure for interface
  297.  *         : target - target
  298.  * Notes   : we need to switch the chip out of FASTSCSI mode if we have
  299.  *           a transfer period >= 200ns - otherwise the chip will violate
  300.  *           the SCSI timings.
  301.  */
  302. static void
  303. fas216_set_sync(FAS216_Info *info, int target)
  304. {
  305. outb(info->device[target].sof, REG_SOF(info));
  306. outb(info->device[target].stp, REG_STP(info));
  307. if (info->device[target].period >= (200 / 4))
  308. outb(info->scsi.cfg[2] & ~CNTL3_FASTSCSI, REG_CNTL3(info));
  309. else
  310. outb(info->scsi.cfg[2], REG_CNTL3(info));
  311. }
  312. /* Synchronous transfer support
  313.  *
  314.  * Note: The SCSI II r10 spec says (5.6.12):
  315.  *
  316.  *  (2)  Due to historical problems with early host adapters that could
  317.  *  not accept an SDTR message, some targets may not initiate synchronous
  318.  *  negotiation after a power cycle as required by this standard.  Host
  319.  *  adapters that support synchronous mode may avoid the ensuing failure
  320.  *  modes when the target is independently power cycled by initiating a
  321.  *  synchronous negotiation on each REQUEST SENSE and INQUIRY command.
  322.  *  This approach increases the SCSI bus overhead and is not recommended
  323.  *  for new implementations.  The correct method is to respond to an
  324.  *  SDTR message with a MESSAGE REJECT message if the either the
  325.  *  initiator or target devices does not support synchronous transfers
  326.  *  or does not want to negotiate for synchronous transfers at the time.
  327.  *  Using the correct method assures compatibility with wide data
  328.  *  transfers and future enhancements.
  329.  *
  330.  * We will always initiate a synchronous transfer negociation request on
  331.  * every INQUIRY or REQUEST SENSE message, unless the target itself has
  332.  * at some point performed a synchronous transfer negociation request, or
  333.  * we have synchronous transfers disabled for this device.
  334.  */
  335. /* Function: void fas216_handlesync(FAS216_Info *info, char *msg)
  336.  * Purpose : Handle a synchronous transfer message from the target
  337.  * Params  : info - state structure for interface
  338.  *         : msg  - message from target
  339.  */
  340. static void
  341. fas216_handlesync(FAS216_Info *info, char *msg)
  342. {
  343. struct fas216_device *dev = &info->device[info->SCpnt->target];
  344. enum { sync, async, none, reject } res = none;
  345. #ifdef SCSI2_SYNC
  346. switch (msg[0]) {
  347. case MESSAGE_REJECT:
  348. /* Synchronous transfer request failed.
  349.  * Note: SCSI II r10:
  350.  *
  351.  *  SCSI devices that are capable of synchronous
  352.  *  data transfers shall not respond to an SDTR
  353.  *  message with a MESSAGE REJECT message.
  354.  *
  355.  * Hence, if we get this condition, we disable
  356.  * negociation for this device.
  357.  */
  358. if (dev->sync_state == neg_inprogress) {
  359. dev->sync_state = neg_invalid;
  360. res = async;
  361. }
  362. break;
  363. case EXTENDED_MESSAGE:
  364. switch (dev->sync_state) {
  365. /* We don't accept synchronous transfer requests.
  366.  * Respond with a MESSAGE_REJECT to prevent a
  367.  * synchronous transfer agreement from being reached.
  368.  */
  369. case neg_invalid:
  370. res = reject;
  371. break;
  372. /* We were not negociating a synchronous transfer,
  373.  * but the device sent us a negociation request.
  374.  * Honour the request by sending back a SDTR
  375.  * message containing our capability, limited by
  376.  * the targets capability.
  377.  */
  378. default:
  379. outb(CMD_SETATN, REG_CMD(info));
  380. if (msg[4] > info->ifcfg.sync_max_depth)
  381. msg[4] = info->ifcfg.sync_max_depth;
  382. if (msg[3] < 1000 / info->ifcfg.clockrate)
  383. msg[3] = 1000 / info->ifcfg.clockrate;
  384. msgqueue_flush(&info->scsi.msgs);
  385. msgqueue_addmsg(&info->scsi.msgs, 5,
  386. EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
  387. msg[3], msg[4]);
  388. info->scsi.phase = PHASE_MSGOUT_EXPECT;
  389. /* This is wrong.  The agreement is not in effect
  390.  * until this message is accepted by the device
  391.  */
  392. dev->sync_state = neg_targcomplete;
  393. res = sync;
  394. break;
  395. /* We initiated the synchronous transfer negociation,
  396.  * and have successfully received a response from the
  397.  * target.  The synchronous transfer agreement has been
  398.  * reached.  Note: if the values returned are out of our
  399.  * bounds, we must reject the message.
  400.  */
  401. case neg_inprogress:
  402. res = reject;
  403. if (msg[4] <= info->ifcfg.sync_max_depth &&
  404.     msg[3] >= 1000 / info->ifcfg.clockrate) {
  405. dev->sync_state = neg_complete;
  406. res = sync;
  407. }
  408. break;
  409. }
  410. }
  411. #else
  412. res = reject;
  413. #endif
  414. switch (res) {
  415. case sync:
  416. dev->period = msg[3];
  417. dev->sof    = msg[4];
  418. dev->stp    = fas216_syncperiod(info, msg[3] * 4);
  419. fas216_set_sync(info, info->SCpnt->target);
  420. break;
  421. case reject:
  422. outb(CMD_SETATN, REG_CMD(info));
  423. msgqueue_flush(&info->scsi.msgs);
  424. msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
  425. info->scsi.phase = PHASE_MSGOUT_EXPECT;
  426. case async:
  427. dev->period = info->ifcfg.asyncperiod / 4;
  428. dev->sof    = 0;
  429. dev->stp    = info->scsi.async_stp;
  430. fas216_set_sync(info, info->SCpnt->target);
  431. break;
  432. case none:
  433. break;
  434. }
  435. }
  436. /* Function: void fas216_handlewide(FAS216_Info *info, char *msg)
  437.  * Purpose : Handle a wide transfer message from the target
  438.  * Params  : info - state structure for interface
  439.  *         : msg  - message from target
  440.  */
  441. static void
  442. fas216_handlewide(FAS216_Info *info, char *msg)
  443. {
  444. struct fas216_device *dev = &info->device[info->SCpnt->target];
  445. enum { wide, bit8, none, reject } res = none;
  446. #ifdef SCSI2_WIDE
  447. switch (msg[0]) {
  448. case MESSAGE_REJECT:
  449. /* Wide transfer request failed.
  450.  * Note: SCSI II r10:
  451.  *
  452.  *  SCSI devices that are capable of wide
  453.  *  data transfers shall not respond to a
  454.  *  WDTR message with a MESSAGE REJECT message.
  455.  *
  456.  * Hence, if we get this condition, we never
  457.  * reattempt negociation for this device.
  458.  */
  459. if (dev->wide_state == neg_inprogress) {
  460. dev->wide_state = neg_invalid;
  461. res = bit8;
  462. }
  463. break;
  464. case EXTENDED_MESSAGE:
  465. switch (dev->wide_state) {
  466. /* We don't accept wide data transfer requests.
  467.  * Respond with a MESSAGE REJECT to prevent a
  468.  * wide data transfer agreement from being reached.
  469.  */
  470. case neg_invalid:
  471. res = reject;
  472. break;
  473. /* We were not negociating a wide data transfer,
  474.  * but the device sent is a negociation request.
  475.  * Honour the request by sending back a WDTR
  476.  * message containing our capability, limited by
  477.  * the targets capability.
  478.  */
  479. default:
  480. outb(CMD_SETATN, REG_CMD(info));
  481. if (msg[3] > info->ifcfg.wide_max_size)
  482. msg[3] = info->ifcfg.wide_max_size;
  483. msgqueue_flush(&info->scsi.msgs);
  484. msgqueue_addmsg(&info->scsi.msgs, 4,
  485. EXTENDED_MESSAGE, 2, EXTENDED_WDTR,
  486. msg[3]);
  487. info->scsi.phase = PHASE_MSGOUT_EXPECT;
  488. res = wide;
  489. break;
  490. /* We initiated the wide data transfer negociation,
  491.  * and have successfully received a response from the
  492.  * target.  The synchronous transfer agreement has been
  493.  * reached.  Note: if the values returned are out of our
  494.  * bounds, we must reject the message.
  495.  */
  496. case neg_inprogress:
  497. res = reject;
  498. if (msg[3] <= info->ifcfg.wide_max_size) {
  499. dev->wide_state = neg_complete;
  500. res = wide;
  501. }
  502. break;
  503. }
  504. }
  505. #else
  506. res = reject;
  507. #endif
  508. switch (res) {
  509. case wide:
  510. dev->wide_xfer = msg[3];
  511. break;
  512. case reject:
  513. outb(CMD_SETATN, REG_CMD(info));
  514. msgqueue_flush(&info->scsi.msgs);
  515. msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
  516. info->scsi.phase = PHASE_MSGOUT_EXPECT;
  517. case bit8:
  518. dev->wide_xfer = 0;
  519. break;
  520. case none:
  521. break;
  522. }
  523. }
  524. /* Function: void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
  525.  * Purpose : update data pointers after transfer suspended/paused
  526.  * Params  : info              - interface's local pointer to update
  527.  *           bytes_transferred - number of bytes transferred
  528.  */
  529. static void
  530. fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
  531. {
  532. unsigned char *ptr;
  533. unsigned int residual;
  534. fas216_checkmagic(info);
  535. ptr = info->scsi.SCp.ptr;
  536. residual = info->scsi.SCp.this_residual;
  537. info->SCpnt->request_bufflen -= bytes_transferred;
  538. while (residual <= bytes_transferred && bytes_transferred) {
  539. /* We have used up this buffer */
  540. bytes_transferred -= residual;
  541. if (info->scsi.SCp.buffers_residual) {
  542. info->scsi.SCp.buffer++;
  543. info->scsi.SCp.buffers_residual--;
  544. ptr = (unsigned char *)info->scsi.SCp.buffer->address;
  545. residual = info->scsi.SCp.buffer->length;
  546. } else {
  547. ptr = NULL;
  548. residual = 0;
  549. }
  550. }
  551. residual -= bytes_transferred;
  552. ptr += bytes_transferred;
  553. if (residual == 0)
  554. ptr = NULL;
  555. info->scsi.SCp.ptr = ptr;
  556. info->scsi.SCp.this_residual = residual;
  557. }
  558. /* Function: void fas216_pio(FAS216_Info *info, fasdmadir_t direction)
  559.  * Purpose : transfer data off of/on to card using programmed IO
  560.  * Params  : info      - interface to transfer data to/from
  561.  *           direction - direction to transfer data (DMA_OUT/DMA_IN)
  562.  * Notes   : this is incredibly slow
  563.  */
  564. static void
  565. fas216_pio(FAS216_Info *info, fasdmadir_t direction)
  566. {
  567. unsigned int residual;
  568. char *ptr;
  569. fas216_checkmagic(info);
  570. residual = info->scsi.SCp.this_residual;
  571. ptr = info->scsi.SCp.ptr;
  572. if (direction == DMA_OUT)
  573. outb(*ptr++, REG_FF(info));
  574. else
  575. *ptr++ = inb(REG_FF(info));
  576. residual -= 1;
  577. if (residual == 0) {
  578. if (info->scsi.SCp.buffers_residual) {
  579. info->scsi.SCp.buffer++;
  580. info->scsi.SCp.buffers_residual--;
  581. ptr = (unsigned char *)info->scsi.SCp.buffer->address;
  582. residual = info->scsi.SCp.buffer->length;
  583. } else {
  584. ptr = NULL;
  585. residual = 0;
  586. }
  587. }
  588. info->scsi.SCp.ptr = ptr;
  589. info->scsi.SCp.this_residual = residual;
  590. }
  591. /* Function: void fas216_starttransfer(FAS216_Info *info,
  592.  *        fasdmadir_t direction)
  593.  * Purpose : Start a DMA/PIO transfer off of/on to card
  594.  * Params  : info      - interface from which device disconnected from
  595.  *           direction - transfer direction (DMA_OUT/DMA_IN)
  596.  */
  597. static void
  598. fas216_starttransfer(FAS216_Info *info, fasdmadir_t direction, int flush_fifo)
  599. {
  600. fasdmatype_t dmatype;
  601. fas216_checkmagic(info);
  602. info->scsi.phase = (direction == DMA_OUT) ?
  603. PHASE_DATAOUT : PHASE_DATAIN;
  604. if (info->dma.transfer_type != fasdma_none &&
  605.     info->dma.transfer_type != fasdma_pio) {
  606. unsigned long total, residual;
  607. if (info->dma.transfer_type == fasdma_real_all)
  608. total = info->SCpnt->request_bufflen;
  609. else
  610. total = info->scsi.SCp.this_residual;
  611. residual = (inb(REG_CFIS(info)) & CFIS_CF) +
  612.     inb(REG_CTCL(info)) +
  613.     (inb(REG_CTCM(info)) << 8) +
  614.     (inb(REG_CTCH(info)) << 16);
  615. fas216_updateptrs(info, total - residual);
  616. }
  617. info->dma.transfer_type = fasdma_none;
  618. if (!info->scsi.SCp.ptr) {
  619. printk("scsi%d.%c: null buffer passed to "
  620. "fas216_starttransfern", info->host->host_no,
  621. fas216_target(info));
  622. return;
  623. }
  624. /* flush FIFO */
  625. if (flush_fifo)
  626. outb(CMD_FLUSHFIFO, REG_CMD(info));
  627. /*
  628.  * Default to PIO mode or DMA mode if we have a synchronous
  629.  * transfer agreement.
  630.  */
  631. if (info->device[info->SCpnt->target].sof && info->dma.setup)
  632. dmatype = fasdma_real_all;
  633. else
  634. dmatype = fasdma_pio;
  635. if (info->dma.setup)
  636. dmatype = info->dma.setup(info->host, &info->scsi.SCp,
  637.   direction, dmatype);
  638. info->dma.transfer_type = dmatype;
  639. switch (dmatype) {
  640. case fasdma_pio:
  641. outb(0, REG_SOF(info));
  642. outb(info->scsi.async_stp, REG_STP(info));
  643. outb(info->scsi.SCp.this_residual, REG_STCL(info));
  644. outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info));
  645. outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info));
  646. outb(CMD_TRANSFERINFO, REG_CMD(info));
  647. fas216_pio(info, direction);
  648. break;
  649. case fasdma_pseudo:
  650. outb(info->scsi.SCp.this_residual, REG_STCL(info));
  651. outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info));
  652. outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info));
  653. outb(CMD_TRANSFERINFO | CMD_WITHDMA, REG_CMD(info));
  654. info->dma.pseudo(info->host, &info->scsi.SCp,
  655.  direction, info->SCpnt->transfersize);
  656. break;
  657. case fasdma_real_block:
  658. outb(info->scsi.SCp.this_residual, REG_STCL(info));
  659. outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info));
  660. outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info));
  661. outb(CMD_TRANSFERINFO | CMD_WITHDMA, REG_CMD(info));
  662. break;
  663. case fasdma_real_all:
  664. outb(info->SCpnt->request_bufflen, REG_STCL(info));
  665. outb(info->SCpnt->request_bufflen >> 8, REG_STCM(info));
  666. outb(info->SCpnt->request_bufflen >> 16, REG_STCH(info));
  667. outb(CMD_TRANSFERINFO | CMD_WITHDMA, REG_CMD(info));
  668. break;
  669. default:
  670. printk(KERN_ERR "scsi%d.%d: invalid FAS216 DMA typen",
  671.        info->host->host_no, fas216_target(info));
  672. break;
  673. }
  674. }
  675. /* Function: void fas216_stoptransfer(FAS216_Info *info)
  676.  * Purpose : Stop a DMA transfer onto / off of the card
  677.  * Params  : info      - interface from which device disconnected from
  678.  */
  679. static void
  680. fas216_stoptransfer(FAS216_Info *info)
  681. {
  682. fas216_checkmagic(info);
  683. if (info->dma.transfer_type != fasdma_none &&
  684.     info->dma.transfer_type != fasdma_pio) {
  685. unsigned long total, residual;
  686. if ((info->dma.transfer_type == fasdma_real_all ||
  687.      info->dma.transfer_type == fasdma_real_block) &&
  688.     info->dma.stop)
  689. info->dma.stop(info->host, &info->scsi.SCp);
  690. if (info->dma.transfer_type == fasdma_real_all)
  691. total = info->SCpnt->request_bufflen;
  692. else
  693. total = info->scsi.SCp.this_residual;
  694. residual = (inb(REG_CFIS(info)) & CFIS_CF) +
  695.     inb(REG_CTCL(info)) +
  696.     (inb(REG_CTCM(info)) << 8) +
  697.     (inb(REG_CTCH(info)) << 16);
  698. fas216_updateptrs(info, total - residual);
  699. info->dma.transfer_type = fasdma_none;
  700. }
  701. if (info->scsi.phase == PHASE_DATAOUT)
  702. outb(CMD_FLUSHFIFO, REG_CMD(info));
  703. }
  704. /* Function: void fas216_disconnected_intr(FAS216_Info *info)
  705.  * Purpose : handle device disconnection
  706.  * Params  : info - interface from which device disconnected from
  707.  */
  708. static void
  709. fas216_disconnect_intr(FAS216_Info *info)
  710. {
  711. fas216_checkmagic(info);
  712. #ifdef DEBUG_CONNECT
  713. printk("scsi%d.%c: disconnect phase=%02Xn", info->host->host_no,
  714. fas216_target(info), info->scsi.phase);
  715. #endif
  716. msgqueue_flush(&info->scsi.msgs);
  717. switch (info->scsi.phase) {
  718. case PHASE_SELECTION: /* while selecting - no target */
  719. case PHASE_SELSTEPS:
  720. fas216_done(info, DID_NO_CONNECT);
  721. break;
  722. case PHASE_MSGIN_DISCONNECT: /* message in - disconnecting */
  723. outb(CMD_ENABLESEL, REG_CMD(info));
  724. info->scsi.disconnectable = 1;
  725. info->scsi.reconnected.tag = 0;
  726. info->scsi.phase = PHASE_IDLE;
  727. info->stats.disconnects += 1;
  728. break;
  729. case PHASE_DONE: /* at end of command - complete */
  730. fas216_done(info, DID_OK);
  731. break;
  732. case PHASE_MSGOUT: /* message out - possible ABORT message */
  733. if (fas216_get_last_msg(info, info->scsi.msgin_fifo) == ABORT) {
  734. info->scsi.aborting = 0;
  735. fas216_done(info, DID_ABORT);
  736. break;
  737. }
  738. default: /* huh? */
  739. printk(KERN_ERR "scsi%d.%c: unexpected disconnect in phase %sn",
  740. info->host->host_no, fas216_target(info), fas216_drv_phase(info));
  741. print_debug_list();
  742. fas216_stoptransfer(info);
  743. fas216_done(info, DID_ERROR);
  744. break;
  745. }
  746. }
  747. /* Function: void fas216_reselected_intr(FAS216_Info *info)
  748.  * Purpose : Start reconnection of a device
  749.  * Params  : info - interface which was reselected
  750.  */
  751. static void
  752. fas216_reselected_intr(FAS216_Info *info)
  753. {
  754. unsigned char target, identify_msg, ok;
  755. fas216_checkmagic(info);
  756. if ((info->scsi.phase == PHASE_SELECTION ||
  757.      info->scsi.phase == PHASE_SELSTEPS) && info->SCpnt) {
  758. Scsi_Cmnd *SCpnt = info->SCpnt;
  759. info->origSCpnt = SCpnt;
  760. info->SCpnt = NULL;
  761. if (info->device[SCpnt->target].wide_state == neg_inprogress)
  762. info->device[SCpnt->target].wide_state = neg_wait;
  763. if (info->device[SCpnt->target].sync_state == neg_inprogress)
  764. info->device[SCpnt->target].sync_state = neg_wait;
  765. }
  766. #ifdef DEBUG_CONNECT
  767. printk("scsi%d.%c: reconnect phase=%02Xn", info->host->host_no,
  768. fas216_target(info), info->scsi.phase);
  769. #endif
  770. if ((inb(REG_CFIS(info)) & CFIS_CF) != 2) {
  771. printk(KERN_ERR "scsi%d.H: incorrect number of bytes after reselectn",
  772. info->host->host_no);
  773. outb(CMD_SETATN, REG_CMD(info));
  774. outb(CMD_MSGACCEPTED, REG_CMD(info));
  775. msgqueue_flush(&info->scsi.msgs);
  776. msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
  777. info->scsi.phase = PHASE_MSGOUT_EXPECT;
  778. return;
  779. }
  780. target = inb(REG_FF(info));
  781. identify_msg = inb(REG_FF(info));
  782. ok = 1;
  783. if (!(target & (1 << info->host->this_id))) {
  784. printk(KERN_ERR "scsi%d.H: invalid host id on reselectn", info->host->host_no);
  785. ok = 0;
  786. }
  787. if (!(identify_msg & 0x80)) {
  788. printk(KERN_ERR "scsi%d.H: no IDENTIFY message on reselect, got msg %02Xn",
  789. info->host->host_no, identify_msg);
  790. ok = 0;
  791. }
  792. if (!ok) {
  793. /*
  794.  * Something went wrong - send an initiator error to
  795.  * the target.
  796.  */
  797. outb(CMD_SETATN, REG_CMD(info));
  798. outb(CMD_MSGACCEPTED, REG_CMD(info));
  799. msgqueue_flush(&info->scsi.msgs);
  800. msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
  801. info->scsi.phase = PHASE_MSGOUT_EXPECT;
  802. return;
  803. }
  804. target &= ~(1 << info->host->this_id);
  805. switch (target) {
  806. case   1:  target = 0; break;
  807. case   2:  target = 1; break;
  808. case   4:  target = 2; break;
  809. case   8:  target = 3; break;
  810. case  16:  target = 4; break;
  811. case  32:  target = 5; break;
  812. case  64:  target = 6; break;
  813. case 128:  target = 7; break;
  814. default:   target = info->host->this_id; break;
  815. }
  816. identify_msg &= 7;
  817. info->scsi.reconnected.target = target;
  818. info->scsi.reconnected.lun    = identify_msg;
  819. info->scsi.reconnected.tag    = 0;
  820. ok = 0;
  821. if (info->scsi.disconnectable && info->SCpnt &&
  822.     info->SCpnt->target == target && info->SCpnt->lun == identify_msg)
  823. ok = 1;
  824. if (!ok && queue_probetgtlun(&info->queues.disconnected, target, identify_msg))
  825. ok = 1;
  826. msgqueue_flush(&info->scsi.msgs);
  827. if (ok) {
  828. info->scsi.phase = PHASE_RECONNECTED;
  829. outb(target, REG_SDID(info));
  830. } else {
  831. /*
  832.  * Our command structure not found - abort the
  833.  * command on the target.  Since we have no
  834.  * record of this command, we can't send
  835.  * an INITIATOR DETECTED ERROR message.
  836.  */
  837. outb(CMD_SETATN, REG_CMD(info));
  838. msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
  839. info->scsi.phase = PHASE_MSGOUT_EXPECT;
  840. }
  841. outb(CMD_MSGACCEPTED, REG_CMD(info));
  842. }
  843. /* Function: void fas216_finish_reconnect(FAS216_Info *info)
  844.  * Purpose : finish reconnection sequence for device
  845.  * Params  : info - interface which caused function done interrupt
  846.  */
  847. static void
  848. fas216_finish_reconnect(FAS216_Info *info)
  849. {
  850. fas216_checkmagic(info);
  851. #ifdef DEBUG_CONNECT
  852. printk("Connected: %1X %1X %02X, reconnected: %1X %1X %02Xn",
  853. info->SCpnt->target, info->SCpnt->lun, info->SCpnt->tag,
  854. info->scsi.reconnected.target, info->scsi.reconnected.lun,
  855. info->scsi.reconnected.tag);
  856. #endif
  857. if (info->scsi.disconnectable && info->SCpnt) {
  858. info->scsi.disconnectable = 0;
  859. if (info->SCpnt->target == info->scsi.reconnected.target &&
  860.     info->SCpnt->lun    == info->scsi.reconnected.lun &&
  861.     info->SCpnt->tag    == info->scsi.reconnected.tag) {
  862. #ifdef DEBUG_CONNECT
  863. printk("scsi%d.%c: reconnected",
  864. info->host->host_no, fas216_target(info));
  865. #endif
  866. } else {
  867. queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
  868. #ifdef DEBUG_CONNECT
  869. printk("scsi%d.%c: had to move command to disconnected queuen",
  870. info->host->host_no, fas216_target(info));
  871. #endif
  872. info->SCpnt = NULL;
  873. }
  874. }
  875. if (!info->SCpnt) {
  876. info->SCpnt = queue_remove_tgtluntag(&info->queues.disconnected,
  877. info->scsi.reconnected.target,
  878. info->scsi.reconnected.lun,
  879. info->scsi.reconnected.tag);
  880. #ifdef DEBUG_CONNECT
  881. printk("scsi%d.%c: had to get command",
  882. info->host->host_no, fas216_target(info));
  883. #endif
  884. }
  885. if (!info->SCpnt) {
  886. outb(CMD_SETATN, REG_CMD(info));
  887. msgqueue_flush(&info->scsi.msgs);
  888. #if 0
  889. if (info->scsi.reconnected.tag)
  890. msgqueue_addmsg(&info->scsi.msgs, 2, ABORT_TAG, info->scsi.reconnected.tag);
  891. else
  892. #endif
  893. msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
  894. info->scsi.phase = PHASE_MSGOUT_EXPECT;
  895. info->scsi.aborting = 1;
  896. } else {
  897. /*
  898.  * Restore data pointer from SAVED data pointer
  899.  */
  900. info->scsi.SCp = info->SCpnt->SCp;
  901. #ifdef DEBUG_CONNECT
  902. printk(", data pointers: [%p, %X]",
  903. info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
  904. #endif
  905. }
  906. #ifdef DEBUG_CONNECT
  907. printk("n");
  908. #endif
  909. }
  910. static int fas216_wait_cmd(FAS216_Info *info, int cmd)
  911. {
  912. int tout;
  913. int stat;
  914. outb(cmd, REG_CMD(info));
  915. for (tout = 1000; tout; tout -= 1) {
  916. stat = inb(REG_STAT(info));
  917. if (stat & STAT_INT)
  918. break;
  919. udelay(1);
  920. }
  921. return stat;
  922. }
  923. static int fas216_get_msg_byte(FAS216_Info *info)
  924. {
  925. int stat;
  926. stat = fas216_wait_cmd(info, CMD_MSGACCEPTED);
  927. if ((stat & STAT_INT) == 0)
  928. goto timedout;
  929. if ((stat & STAT_BUSMASK) != STAT_MESGIN)
  930. goto unexpected_phase_change;
  931. inb(REG_INST(info));
  932. stat = fas216_wait_cmd(info, CMD_TRANSFERINFO);
  933. if ((stat & STAT_INT) == 0)
  934. goto timedout;
  935. if ((stat & STAT_BUSMASK) != STAT_MESGIN)
  936. goto unexpected_phase_change;
  937. inb(REG_INST(info));
  938. return inb(REG_FF(info));
  939. timedout:
  940. printk("scsi%d.%c: timed out waiting for message byten",
  941. info->host->host_no, fas216_target(info));
  942. return -1;
  943. unexpected_phase_change:
  944. printk("scsi%d.%c: unexpected phase change: status = %02Xn",
  945. info->host->host_no, fas216_target(info), stat);
  946. return -2;
  947. }
  948. /* Function: void fas216_message(FAS216_Info *info)
  949.  * Purpose : handle a function done interrupt from FAS216 chip
  950.  * Params  : info - interface which caused function done interrupt
  951.  */
  952. static void fas216_message(FAS216_Info *info)
  953. {
  954. unsigned char *message = info->scsi.message;
  955. unsigned int msglen = 1, i;
  956. int msgbyte = 0;
  957. fas216_checkmagic(info);
  958. message[0] = inb(REG_FF(info));
  959. if (message[0] == EXTENDED_MESSAGE) {
  960. msgbyte = fas216_get_msg_byte(info);
  961. if (msgbyte >= 0) {
  962. message[1] = msgbyte;
  963. for (msglen = 2; msglen < message[1] + 2; msglen++) {
  964. msgbyte = fas216_get_msg_byte(info);
  965. if (msgbyte >= 0)
  966. message[msglen] = msgbyte;
  967. else
  968. break;
  969. }
  970. }
  971. }
  972. info->scsi.msglen = msglen;
  973. #ifdef DEBUG_MESSAGES
  974. {
  975. int i;
  976. printk("scsi%d.%c: message in: ",
  977. info->host->host_no, fas216_target(info));
  978. for (i = 0; i < msglen; i++)
  979. printk("%02X ", message[i]);
  980. printk("n");
  981. }
  982. #endif
  983. if (info->scsi.phase == PHASE_RECONNECTED) {
  984. if (message[0] == SIMPLE_QUEUE_TAG)
  985. info->scsi.reconnected.tag = message[1];
  986. fas216_finish_reconnect(info);
  987. info->scsi.phase = PHASE_MSGIN;
  988. }
  989. switch (message[0]) {
  990. case COMMAND_COMPLETE:
  991. if (msglen != 1)
  992. goto unrecognised;
  993. printk(KERN_ERR "scsi%d.%c: command complete with no "
  994. "status in MESSAGE_IN?n",
  995. info->host->host_no, fas216_target(info));
  996. break;
  997. case SAVE_POINTERS:
  998. if (msglen != 1)
  999. goto unrecognised;
  1000. /*
  1001.  * Save current data pointer to SAVED data pointer
  1002.  * SCSI II standard says that we must not acknowledge
  1003.  * this until we have really saved pointers.
  1004.  * NOTE: we DO NOT save the command nor status pointers
  1005.  * as required by the SCSI II standard.  These always
  1006.  * point to the start of their respective areas.
  1007.  */
  1008. info->SCpnt->SCp = info->scsi.SCp;
  1009. info->SCpnt->SCp.sent_command = 0;
  1010. #if defined (DEBUG_MESSAGES) || defined (DEBUG_CONNECT)
  1011. printk("scsi%d.%c: save data pointers: [%p, %X]n",
  1012. info->host->host_no, fas216_target(info),
  1013. info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
  1014. #endif
  1015. break;
  1016. case RESTORE_POINTERS:
  1017. if (msglen != 1)
  1018. goto unrecognised;
  1019. /*
  1020.  * Restore current data pointer from SAVED data pointer
  1021.  */
  1022. info->scsi.SCp = info->SCpnt->SCp;
  1023. #if defined (DEBUG_MESSAGES) || defined (DEBUG_CONNECT)
  1024. printk("scsi%d.%c: restore data pointers: [%p, %X]n",
  1025. info->host->host_no, fas216_target(info),
  1026. info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
  1027. #endif
  1028. break;
  1029. case DISCONNECT:
  1030. if (msglen != 1)
  1031. goto unrecognised;
  1032. info->scsi.phase = PHASE_MSGIN_DISCONNECT;
  1033. break;
  1034. case MESSAGE_REJECT:
  1035. if (msglen != 1)
  1036. goto unrecognised;
  1037. switch (fas216_get_last_msg(info, info->scsi.msgin_fifo)) {
  1038. case EXTENDED_MESSAGE | EXTENDED_SDTR << 8:
  1039. fas216_handlesync(info, message);
  1040. break;
  1041. case EXTENDED_MESSAGE | EXTENDED_WDTR << 8:
  1042. fas216_handlewide(info, message);
  1043. break;
  1044. default:
  1045. printk("scsi%d.%c: reject, last message %04Xn",
  1046. info->host->host_no, fas216_target(info),
  1047. fas216_get_last_msg(info, info->scsi.msgin_fifo));
  1048. }
  1049. break;
  1050. case NOP:
  1051. break;
  1052. case SIMPLE_QUEUE_TAG:
  1053. if (msglen < 2)
  1054. goto unrecognised;
  1055. /* handled above - print a warning since this is untested */
  1056. printk("scsi%d.%c: reconnect queue tag %02Xn",
  1057. info->host->host_no, fas216_target(info),
  1058. message[1]);
  1059. break;
  1060. case EXTENDED_MESSAGE:
  1061. if (msglen < 3)
  1062. goto unrecognised;
  1063. switch (message[2]) {
  1064. case EXTENDED_SDTR: /* Sync transfer negociation request/reply */
  1065. fas216_handlesync(info, message);
  1066. break;
  1067. case EXTENDED_WDTR: /* Wide transfer negociation request/reply */
  1068. fas216_handlewide(info, message);
  1069. break;
  1070. default:
  1071. goto unrecognised;
  1072. }
  1073. break;
  1074. default:
  1075. goto unrecognised;
  1076. }
  1077. outb(CMD_MSGACCEPTED, REG_CMD(info));
  1078. return;
  1079. unrecognised:
  1080. printk("scsi%d.%c: unrecognised message, rejectingn",
  1081. info->host->host_no, fas216_target(info));
  1082. printk("scsi%d.%c: message was", info->host->host_no, fas216_target(info));
  1083. for (i = 0; i < msglen; i++)
  1084. printk("%s%02X", i & 31 ? " " : "n  ", message[i]);
  1085. printk("n");
  1086. /*
  1087.  * Something strange seems to be happening here -
  1088.  * I can't use SETATN since the chip gives me an
  1089.  * invalid command interrupt when I do.  Weird.
  1090.  */
  1091. outb(CMD_NOP, REG_CMD(info));
  1092. fas216_dumpstate(info);
  1093. outb(CMD_SETATN, REG_CMD(info));
  1094. msgqueue_flush(&info->scsi.msgs);
  1095. msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
  1096. info->scsi.phase = PHASE_MSGOUT_EXPECT;
  1097. fas216_dumpstate(info);
  1098. outb(CMD_MSGACCEPTED, REG_CMD(info));
  1099. }
  1100. /* Function: void fas216_send_command(FAS216_Info *info)
  1101.  * Purpose : send a command to a target after all message bytes have been sent
  1102.  * Params  : info - interface which caused bus service
  1103.  */
  1104. static void fas216_send_command(FAS216_Info *info)
  1105. {
  1106. int i;
  1107. fas216_checkmagic(info);
  1108. outb(CMD_NOP|CMD_WITHDMA, REG_CMD(info));
  1109. outb(CMD_FLUSHFIFO, REG_CMD(info));
  1110. /* load command */
  1111. for (i = info->scsi.SCp.sent_command; i < info->SCpnt->cmd_len; i++)
  1112. outb(info->SCpnt->cmnd[i], REG_FF(info));
  1113. outb(CMD_TRANSFERINFO, REG_CMD(info));
  1114. info->scsi.phase = PHASE_COMMAND;
  1115. }
  1116. /* Function: void fas216_send_messageout(FAS216_Info *info, int start)
  1117.  * Purpose : handle bus service to send a message
  1118.  * Params  : info - interface which caused bus service
  1119.  * Note    : We do not allow the device to change the data direction!
  1120.  */
  1121. static void fas216_send_messageout(FAS216_Info *info, int start)
  1122. {
  1123. unsigned int tot_msglen = msgqueue_msglength(&info->scsi.msgs);
  1124. fas216_checkmagic(info);
  1125. outb(CMD_FLUSHFIFO, REG_CMD(info));
  1126. if (tot_msglen) {
  1127. struct message *msg;
  1128. int msgnr = 0;
  1129. while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
  1130. int i;
  1131. for (i = start; i < msg->length; i++)
  1132. outb(msg->msg[i], REG_FF(info));
  1133. msg->fifo = tot_msglen - (inb(REG_CFIS(info)) & CFIS_CF);
  1134. start = 0;
  1135. }
  1136. } else
  1137. outb(NOP, REG_FF(info));
  1138. outb(CMD_TRANSFERINFO, REG_CMD(info));
  1139. info->scsi.phase = PHASE_MSGOUT;
  1140. }
  1141. /* Function: void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
  1142.  * Purpose : handle a bus service interrupt from FAS216 chip
  1143.  * Params  : info - interface which caused bus service interrupt
  1144.  *           stat - Status register contents
  1145.  *           ssr  - SCSI Status register contents
  1146.  */
  1147. static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
  1148. {
  1149. fas216_checkmagic(info);
  1150. #ifdef DEBUG_BUSSERVICE
  1151. printk("scsi%d.%c: bus service: stat=%02X ssr=%02X phase=%02Xn",
  1152. info->host->host_no, fas216_target(info), stat, ssr, info->scsi.phase);
  1153. #endif
  1154. switch (info->scsi.phase) {
  1155. case PHASE_SELECTION:
  1156. if ((ssr & IS_BITS) != 1)
  1157. goto bad_is;
  1158. break;
  1159. case PHASE_SELSTEPS:
  1160. switch (ssr & IS_BITS) {
  1161. case IS_SELARB:
  1162. case IS_MSGBYTESENT:
  1163. goto bad_is;
  1164. case IS_NOTCOMMAND:
  1165. case IS_EARLYPHASE:
  1166. if ((stat & STAT_BUSMASK) == STAT_MESGIN)
  1167. break;
  1168. goto bad_is;
  1169. case IS_COMPLETE:
  1170. break;
  1171. }
  1172. default:
  1173. break;
  1174. }
  1175. outb(CMD_NOP, REG_CMD(info));
  1176. #define STATE(st,ph) ((ph) << 3 | (st))
  1177. /* This table describes the legal SCSI state transitions,
  1178.  * as described by the SCSI II spec.
  1179.  */
  1180. switch (STATE(stat & STAT_BUSMASK, info->scsi.phase)) {
  1181. /* Reselmsgin   -> Data In */
  1182. case STATE(STAT_DATAIN, PHASE_RECONNECTED):
  1183. fas216_finish_reconnect(info);
  1184. case STATE(STAT_DATAIN, PHASE_SELSTEPS):/* Sel w/ steps -> Data In      */
  1185. case STATE(STAT_DATAIN, PHASE_DATAIN):  /* Data In      -> Data In      */
  1186. case STATE(STAT_DATAIN, PHASE_MSGOUT):  /* Message Out  -> Data In      */
  1187. case STATE(STAT_DATAIN, PHASE_COMMAND): /* Command      -> Data In      */
  1188. case STATE(STAT_DATAIN, PHASE_MSGIN):   /* Message In   -> Data In      */
  1189. fas216_starttransfer(info, DMA_IN, 0);
  1190. return;
  1191. case STATE(STAT_DATAOUT, PHASE_DATAOUT):/* Data Out     -> Data Out     */
  1192. fas216_starttransfer(info, DMA_OUT, 0);
  1193. return;
  1194. /* Reselmsgin   -> Data Out     */
  1195. case STATE(STAT_DATAOUT, PHASE_RECONNECTED):
  1196. fas216_finish_reconnect(info);
  1197. case STATE(STAT_DATAOUT, PHASE_SELSTEPS):/* Sel w/ steps-> Data Out     */
  1198. case STATE(STAT_DATAOUT, PHASE_MSGOUT): /* Message Out  -> Data Out     */
  1199. case STATE(STAT_DATAOUT, PHASE_COMMAND):/* Command      -> Data Out     */
  1200. case STATE(STAT_DATAOUT, PHASE_MSGIN):  /* Message In   -> Data Out     */
  1201. fas216_starttransfer(info, DMA_OUT, 1);
  1202. return;
  1203. /* Reselmsgin   -> Status       */
  1204. case STATE(STAT_STATUS, PHASE_RECONNECTED):
  1205. fas216_finish_reconnect(info);
  1206. goto status;
  1207. case STATE(STAT_STATUS, PHASE_DATAOUT): /* Data Out     -> Status       */
  1208. case STATE(STAT_STATUS, PHASE_DATAIN):  /* Data In      -> Status       */
  1209. fas216_stoptransfer(info);
  1210. case STATE(STAT_STATUS, PHASE_SELSTEPS):/* Sel w/ steps -> Status       */
  1211. case STATE(STAT_STATUS, PHASE_MSGOUT):  /* Message Out  -> Status       */
  1212. case STATE(STAT_STATUS, PHASE_COMMAND): /* Command      -> Status       */
  1213. case STATE(STAT_STATUS, PHASE_MSGIN):   /* Message In   -> Status       */
  1214. status:
  1215. outb(CMD_INITCMDCOMPLETE, REG_CMD(info));
  1216. info->scsi.phase = PHASE_STATUS;
  1217. return;
  1218. case STATE(STAT_MESGIN, PHASE_DATAOUT): /* Data Out     -> Message In   */
  1219. case STATE(STAT_MESGIN, PHASE_DATAIN):  /* Data In      -> Message In   */
  1220. fas216_stoptransfer(info);
  1221. case STATE(STAT_MESGIN, PHASE_COMMAND): /* Command -> Message In */
  1222. case STATE(STAT_MESGIN, PHASE_SELSTEPS):/* Sel w/ steps -> Message In   */
  1223. case STATE(STAT_MESGIN, PHASE_MSGOUT):  /* Message Out  -> Message In   */
  1224. info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
  1225. outb(CMD_FLUSHFIFO, REG_CMD(info));
  1226. outb(CMD_TRANSFERINFO, REG_CMD(info));
  1227. info->scsi.phase = PHASE_MSGIN;
  1228. return;
  1229. /* Reselmsgin   -> Message In   */
  1230. case STATE(STAT_MESGIN, PHASE_RECONNECTED):
  1231. case STATE(STAT_MESGIN, PHASE_MSGIN):
  1232. info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
  1233. outb(CMD_TRANSFERINFO, REG_CMD(info));
  1234. return;
  1235. /* Reselmsgin   -> Command      */
  1236. case STATE(STAT_COMMAND, PHASE_RECONNECTED):
  1237. fas216_finish_reconnect(info);
  1238. case STATE(STAT_COMMAND, PHASE_MSGOUT): /* Message Out  -> Command      */
  1239. case STATE(STAT_COMMAND, PHASE_MSGIN):  /* Message In   -> Command      */
  1240. fas216_send_command(info);
  1241. info->scsi.phase = PHASE_COMMAND;
  1242. return;
  1243. /* Selection    -> Message Out  */
  1244. case STATE(STAT_MESGOUT, PHASE_SELECTION):
  1245. fas216_send_messageout(info, 1);
  1246. return;
  1247. /* Any          -> Message Out  */
  1248. case STATE(STAT_MESGOUT, PHASE_MSGOUT_EXPECT):
  1249. fas216_send_messageout(info, 0);
  1250. return;
  1251. /* Error recovery rules.
  1252.  *   These either attempt to abort or retry the operation.
  1253.  * TODO: we need more of these
  1254.  */
  1255. case STATE(STAT_COMMAND, PHASE_COMMAND):/* Command      -> Command      */
  1256. /* error - we've sent out all the command bytes
  1257.  * we have.
  1258.  * NOTE: we need SAVE DATA POINTERS/RESTORE DATA POINTERS
  1259.  * to include the command bytes sent for this to work
  1260.  * correctly.
  1261.  */
  1262. printk(KERN_ERR "scsi%d.%c: "
  1263. "target trying to receive more command bytesn",
  1264. info->host->host_no, fas216_target(info));
  1265. outb(CMD_SETATN, REG_CMD(info));
  1266. outb(15, REG_STCL(info));
  1267. outb(0, REG_STCM(info));
  1268. outb(0, REG_STCH(info));
  1269. outb(CMD_PADBYTES | CMD_WITHDMA, REG_CMD(info));
  1270. msgqueue_flush(&info->scsi.msgs);
  1271. msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
  1272. info->scsi.phase = PHASE_MSGOUT_EXPECT;
  1273. return;
  1274. /* Selection    -> Message Out  */
  1275. case STATE(STAT_MESGOUT, PHASE_SELSTEPS):
  1276. case STATE(STAT_MESGOUT, PHASE_MSGOUT): /* Message Out  -> Message Out  */
  1277. /* If we get another message out phase, this
  1278.  * usually means some parity error occurred.
  1279.  * Resend complete set of messages.  If we have
  1280.  * more than 1 byte to send, we need to assert
  1281.  * ATN again.
  1282.  */
  1283. if (msgqueue_msglength(&info->scsi.msgs) > 1)
  1284. outb(CMD_SETATN, REG_CMD(info));
  1285. fas216_send_messageout(info, 0);
  1286. return;
  1287. }
  1288. if (info->scsi.phase == PHASE_MSGIN_DISCONNECT) {
  1289. printk(KERN_ERR "scsi%d.%c: disconnect message received, but bus service %s?n",
  1290. info->host->host_no, fas216_target(info),
  1291. fas216_bus_phase(stat));
  1292. msgqueue_flush(&info->scsi.msgs);
  1293. outb(CMD_SETATN, REG_CMD(info));
  1294. msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
  1295. info->scsi.phase = PHASE_MSGOUT_EXPECT;
  1296. info->scsi.aborting = 1;
  1297. outb(CMD_TRANSFERINFO, REG_CMD(info));
  1298. return;
  1299. }
  1300. printk(KERN_ERR "scsi%d.%c: bus phase %s after %s?n",
  1301. info->host->host_no, fas216_target(info),
  1302. fas216_bus_phase(stat),
  1303. fas216_drv_phase(info));
  1304. print_debug_list();
  1305. return;
  1306. bad_is:
  1307. printk("scsi%d.%c: bus service at step %d?n",
  1308. info->host->host_no, fas216_target(info),
  1309. ssr & IS_BITS);
  1310. print_debug_list();
  1311. fas216_done(info, DID_ERROR);
  1312. }
  1313. /* Function: void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
  1314.  * Purpose : handle a function done interrupt from FAS216 chip
  1315.  * Params  : info - interface which caused function done interrupt
  1316.  *           stat - Status register contents
  1317.  *           ssr  - SCSI Status register contents
  1318.  */
  1319. static void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
  1320. {
  1321. int status, message;
  1322. fas216_checkmagic(info);
  1323. #ifdef DEBUG_FUNCTIONDONE
  1324. printk("scsi%d.%c: function done: stat=%X ssr=%X phase=%02Xn",
  1325. info->host->host_no, fas216_target(info), stat, ssr, info->scsi.phase);
  1326. #endif
  1327. switch (info->scsi.phase) {
  1328. case PHASE_STATUS: /* status phase - read status and msg */
  1329. status = inb(REG_FF(info));
  1330. message = inb(REG_FF(info));
  1331. info->scsi.SCp.Message = message;
  1332. info->scsi.SCp.Status = status;
  1333. info->scsi.phase = PHASE_DONE;
  1334. outb(CMD_MSGACCEPTED, REG_CMD(info));
  1335. break;
  1336. case PHASE_IDLE: /* reselected? */
  1337. case PHASE_MSGIN: /* message in phase */
  1338. case PHASE_RECONNECTED: /* reconnected command */
  1339. if ((stat & STAT_BUSMASK) == STAT_MESGIN) {
  1340. info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
  1341. fas216_message(info);
  1342. break;
  1343. }
  1344. default:
  1345. printk("scsi%d.%c: internal phase %s for function done?"
  1346. "  What do I do with this?n",
  1347. info->host->host_no, fas216_target(info),
  1348. fas216_drv_phase(info));
  1349. }
  1350. }
  1351. /* Function: void fas216_intr(struct Scsi_Host *instance)
  1352.  * Purpose : handle interrupts from the interface to progress a command
  1353.  * Params  : instance - interface to service
  1354.  */
  1355. void fas216_intr(struct Scsi_Host *instance)
  1356. {
  1357. FAS216_Info *info = (FAS216_Info *)instance->hostdata;
  1358. unsigned char isr, ssr, stat;
  1359. fas216_checkmagic(info);
  1360. stat = inb(REG_STAT(info));
  1361. ssr = inb(REG_IS(info));
  1362. isr = inb(REG_INST(info));
  1363. add_debug_list(stat, ssr, isr, info->scsi.phase);
  1364. if (stat & STAT_INT) {
  1365. if (isr & INST_BUSRESET) {
  1366. printk(KERN_DEBUG "scsi%d.H: bus reset detectedn", instance->host_no);
  1367. scsi_report_bus_reset(instance, 0);
  1368. } else if (isr & INST_ILLEGALCMD) {
  1369. printk(KERN_CRIT "scsi%d.H: illegal command givenn", instance->host_no);
  1370. fas216_dumpstate(info);
  1371. } else if (isr & INST_DISCONNECT)
  1372. fas216_disconnect_intr(info);
  1373. else if (isr & INST_RESELECTED) /* reselected */
  1374. fas216_reselected_intr(info);
  1375. else if (isr & INST_BUSSERVICE) /* bus service request */
  1376. fas216_busservice_intr(info, stat, ssr);
  1377. else if (isr & INST_FUNCDONE) /* function done */
  1378. fas216_funcdone_intr(info, stat, ssr);
  1379. else
  1380.      printk("scsi%d.%c: unknown interrupt received:"
  1381. " phase %s isr %02X ssr %02X stat %02Xn",
  1382. instance->host_no, fas216_target(info),
  1383. fas216_drv_phase(info), isr, ssr, stat);
  1384. }
  1385. }
  1386. /* Function: void fas216_kick(FAS216_Info *info)
  1387.  * Purpose : kick a command to the interface - interface should be idle
  1388.  * Params  : info - our host interface to kick
  1389.  * Notes   : Interrupts are always disabled!
  1390.  */
  1391. static void fas216_kick(FAS216_Info *info)
  1392. {
  1393. Scsi_Cmnd *SCpnt = NULL;
  1394. int tot_msglen, from_queue = 0, disconnect_ok;
  1395. fas216_checkmagic(info);
  1396. /*
  1397.  * Obtain the next command to process.
  1398.  */
  1399. do {
  1400. if (info->reqSCpnt) {
  1401. SCpnt = info->reqSCpnt;
  1402. info->reqSCpnt = NULL;
  1403. break;
  1404. }
  1405. if (info->origSCpnt) {
  1406. SCpnt = info->origSCpnt;
  1407. info->origSCpnt = NULL;
  1408. break;
  1409. }
  1410. /* retrieve next command */
  1411. if (!SCpnt) {
  1412. SCpnt = queue_remove_exclude(&info->queues.issue,
  1413.      info->busyluns);
  1414. from_queue = 1;
  1415. break;
  1416. }
  1417. } while (0);
  1418. if (!SCpnt) /* no command pending - just exit */
  1419. return;
  1420. if (info->scsi.disconnectable && info->SCpnt) {
  1421. queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
  1422. info->scsi.disconnectable = 0;
  1423. info->SCpnt = NULL;
  1424. printk("scsi%d.%c: moved command to disconnected queuen",
  1425. info->host->host_no, fas216_target(info));
  1426. }
  1427. /*
  1428.  * claim host busy
  1429.  */
  1430. info->scsi.phase = PHASE_SELECTION;
  1431. info->SCpnt = SCpnt;
  1432. info->scsi.SCp = SCpnt->SCp;
  1433. info->dma.transfer_type = fasdma_none;
  1434. #ifdef DEBUG_CONNECT
  1435. printk("scsi%d.%c: starting cmd %02X",
  1436. info->host->host_no, '0' + SCpnt->target,
  1437. SCpnt->cmnd[0]);
  1438. #endif
  1439. if (from_queue) {
  1440. #ifdef SCSI2_TAG
  1441. /*
  1442.  * tagged queuing - allocate a new tag to this command
  1443.  */
  1444. if (SCpnt->device->tagged_queue && SCpnt->cmnd[0] != REQUEST_SENSE &&
  1445.     SCpnt->cmnd[0] != INQUIRY) {
  1446.     SCpnt->device->current_tag += 1;
  1447. if (SCpnt->device->current_tag == 0)
  1448.     SCpnt->device->current_tag = 1;
  1449. SCpnt->tag = SCpnt->device->current_tag;
  1450. } else
  1451. #endif
  1452. set_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
  1453. info->stats.removes += 1;
  1454. switch (SCpnt->cmnd[0]) {
  1455. case WRITE_6:
  1456. case WRITE_10:
  1457. case WRITE_12:
  1458. info->stats.writes += 1;
  1459. break;
  1460. case READ_6:
  1461. case READ_10:
  1462. case READ_12:
  1463. info->stats.reads += 1;
  1464. break;
  1465. default:
  1466. info->stats.miscs += 1;
  1467. break;
  1468. }
  1469. }
  1470. /*
  1471.  * Don't allow request sense commands to disconnect.
  1472.  */
  1473. disconnect_ok = SCpnt->cmnd[0] != REQUEST_SENSE &&
  1474. info->device[SCpnt->target].disconnect_ok;
  1475. /*
  1476.  * build outgoing message bytes
  1477.  */
  1478. msgqueue_flush(&info->scsi.msgs);
  1479. msgqueue_addmsg(&info->scsi.msgs, 1, IDENTIFY(disconnect_ok, SCpnt->lun));
  1480. /*
  1481.  * add tag message if required
  1482.  */
  1483. if (SCpnt->tag)
  1484. msgqueue_addmsg(&info->scsi.msgs, 2, SIMPLE_QUEUE_TAG, SCpnt->tag);
  1485. do {
  1486. #ifdef SCSI2_WIDE
  1487. if (info->device[SCpnt->target].wide_state == neg_wait) {
  1488. info->device[SCpnt->target].wide_state = neg_inprogress;
  1489. msgqueue_addmsg(&info->scsi.msgs, 4,
  1490. EXTENDED_MESSAGE, 2, EXTENDED_WDTR,
  1491. info->ifcfg.wide_max_size);
  1492. break;
  1493. }
  1494. #endif
  1495. #ifdef SCSI2_SYNC
  1496. if ((info->device[SCpnt->target].sync_state == neg_wait ||
  1497.      info->device[SCpnt->target].sync_state == neg_complete) &&
  1498.     (SCpnt->cmnd[0] == REQUEST_SENSE ||
  1499.      SCpnt->cmnd[0] == INQUIRY)) {
  1500. info->device[SCpnt->target].sync_state = neg_inprogress;
  1501. msgqueue_addmsg(&info->scsi.msgs, 5,
  1502. EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
  1503. 1000 / info->ifcfg.clockrate,
  1504. info->ifcfg.sync_max_depth);
  1505. break;
  1506. }
  1507. #endif
  1508. } while (0);
  1509. /* following what the ESP driver says */
  1510. outb(0, REG_STCL(info));
  1511. outb(0, REG_STCM(info));
  1512. outb(0, REG_STCH(info));
  1513. outb(CMD_NOP | CMD_WITHDMA, REG_CMD(info));
  1514. /* flush FIFO */
  1515. outb(CMD_FLUSHFIFO, REG_CMD(info));
  1516. /* load bus-id and timeout */
  1517. outb(BUSID(SCpnt->target), REG_SDID(info));
  1518. outb(info->ifcfg.select_timeout, REG_STIM(info));
  1519. /* synchronous transfers */
  1520. fas216_set_sync(info, SCpnt->target);
  1521. tot_msglen = msgqueue_msglength(&info->scsi.msgs);
  1522. #ifdef DEBUG_MESSAGES
  1523. {
  1524. struct message *msg;
  1525. int msgnr = 0, i;
  1526. printk("scsi%d.%c: message out: ",
  1527. info->host->host_no, '0' + SCpnt->target);
  1528. while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
  1529. printk("{ ");
  1530. for (i = 0; i < msg->length; i++)
  1531. printk("%02x ", msg->msg[i]);
  1532. printk("} ");
  1533. }
  1534. printk("n");
  1535. }
  1536. #endif
  1537. if (tot_msglen == 1 || tot_msglen == 3) {
  1538. /*
  1539.  * We have an easy message length to send...
  1540.  */
  1541. struct message *msg;
  1542. int msgnr = 0, i;
  1543. info->scsi.phase = PHASE_SELSTEPS;
  1544. /* load message bytes */
  1545. while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
  1546. for (i = 0; i < msg->length; i++)
  1547. outb(msg->msg[i], REG_FF(info));
  1548. msg->fifo = tot_msglen - (inb(REG_CFIS(info)) & CFIS_CF);
  1549. }
  1550. /* load command */
  1551. for (i = 0; i < SCpnt->cmd_len; i++)
  1552. outb(SCpnt->cmnd[i], REG_FF(info));
  1553. if (tot_msglen == 1)
  1554. outb(CMD_SELECTATN, REG_CMD(info));
  1555. else
  1556. outb(CMD_SELECTATN3, REG_CMD(info));
  1557. } else {
  1558. /*
  1559.  * We have an unusual number of message bytes to send.
  1560.  *  Load first byte into fifo, and issue SELECT with ATN and
  1561.  *  stop steps.
  1562.  */
  1563. struct message *msg = msgqueue_getmsg(&info->scsi.msgs, 0);
  1564. outb(msg->msg[0], REG_FF(info));
  1565. msg->fifo = 1;
  1566. outb(CMD_SELECTATNSTOP, REG_CMD(info));
  1567. }
  1568. #ifdef DEBUG_CONNECT
  1569. printk(", data pointers [%p, %X]n",
  1570. info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
  1571. #endif
  1572. /* should now get either DISCONNECT or (FUNCTION DONE with BUS SERVICE) intr */
  1573. }
  1574. /* Function: void fas216_rq_sns_done(info, SCpnt, result)
  1575.  * Purpose : Finish processing automatic request sense command
  1576.  * Params  : info   - interface that completed
  1577.  *      SCpnt  - command that completed
  1578.  *      result - driver byte of result
  1579.  */
  1580. static void
  1581. fas216_rq_sns_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
  1582. {
  1583. #ifdef DEBUG_CONNECT
  1584. printk("scsi%d.%c: request sense complete, result=%04X%02X%02Xn",
  1585. info->host->host_no, '0' + SCpnt->target, result,
  1586. SCpnt->SCp.Message, SCpnt->SCp.Status);
  1587. #endif
  1588. if (result != DID_OK || SCpnt->SCp.Status != GOOD)
  1589. /*
  1590.  * Something went wrong.  Make sure that we don't
  1591.  * have valid data in the sense buffer that could
  1592.  * confuse the higher levels.
  1593.  */
  1594. memset(SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
  1595. /*
  1596.  * Note that we don't set SCpnt->result, since that should
  1597.  * reflect the status of the command that we were asked by
  1598.  * the upper layers to process.  This would have been set
  1599.  * correctly by fas216_std_done.
  1600.  */
  1601. SCpnt->scsi_done(SCpnt);
  1602. }
  1603. /* Function: void fas216_std_done(info, SCpnt, result)
  1604.  * Purpose : Finish processing of standard command
  1605.  * Params  : info   - interface that completed
  1606.  *      SCpnt  - command that completed
  1607.  *      result - driver byte of result
  1608.  */
  1609. static void
  1610. fas216_std_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
  1611. {
  1612. info->stats.fins += 1;
  1613. SCpnt->result = result << 16 | info->scsi.SCp.Message << 8 |
  1614. info->scsi.SCp.Status;
  1615. #ifdef DEBUG_CONNECT
  1616. printk("scsi%d.%c: command complete, result=%08X, command=",
  1617. info->host->host_no, '0' + SCpnt->target, SCpnt->result);
  1618. print_command(SCpnt->cmnd);
  1619. #endif
  1620. /*
  1621.  * If the driver detected an error, or the command
  1622.  * was request sense, then we're all done.
  1623.  */
  1624. if (result != DID_OK || SCpnt->cmnd[0] == REQUEST_SENSE)
  1625. goto done;
  1626. /*
  1627.  * If the command returned CHECK_CONDITION status,
  1628.  * request the sense information.
  1629.  */
  1630. if (info->scsi.SCp.Status == CHECK_CONDITION)
  1631. goto request_sense;
  1632. /*
  1633.  * If the command did not complete with GOOD status,
  1634.  * we are all done here.
  1635.  */
  1636. if (info->scsi.SCp.Status != GOOD)
  1637. goto done;
  1638. /*
  1639.  * We have successfully completed a command.  Make sure that
  1640.  * we do not have any buffers left to transfer.  The world
  1641.  * is not perfect, and we seem to occasionally hit this.
  1642.  * It can be indicative of a buggy driver, target or the upper
  1643.  * levels of the SCSI code.
  1644.  */
  1645. if (info->scsi.SCp.ptr) {
  1646. switch (SCpnt->cmnd[0]) {
  1647. case INQUIRY:
  1648. case START_STOP:
  1649. // case READ_CAPACITY:
  1650. case MODE_SENSE:
  1651. break;
  1652. default:
  1653. printk(KERN_ERR "scsi%d.%c: incomplete data transfer "
  1654. "detected: res=%08X ptr=%p len=%X command=",
  1655. info->host->host_no, '0' + SCpnt->target,
  1656. SCpnt->result, info->scsi.SCp.ptr,
  1657. info->scsi.SCp.this_residual);
  1658. print_command(SCpnt->cmnd);
  1659. }
  1660. }
  1661. done: SCpnt->scsi_done(SCpnt);
  1662. return;
  1663. request_sense:
  1664. memset(SCpnt->cmnd, 0, sizeof (SCpnt->cmnd));
  1665. SCpnt->cmnd[0] = REQUEST_SENSE;
  1666. SCpnt->cmnd[1] = SCpnt->lun << 5;
  1667. SCpnt->cmnd[4] = sizeof(SCpnt->sense_buffer);
  1668. SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]);
  1669. SCpnt->SCp.buffer = NULL;
  1670. SCpnt->SCp.buffers_residual = 0;
  1671. SCpnt->SCp.ptr = (char *)SCpnt->sense_buffer;
  1672. SCpnt->SCp.this_residual = sizeof(SCpnt->sense_buffer);
  1673. SCpnt->SCp.Message = 0;
  1674. SCpnt->SCp.Status = 0;
  1675. SCpnt->sc_data_direction = SCSI_DATA_READ;
  1676. SCpnt->use_sg = 0;
  1677. SCpnt->tag = 0;
  1678. SCpnt->host_scribble = (void *)fas216_rq_sns_done;
  1679. /*
  1680.  * Place this command into the high priority "request
  1681.  * sense" slot.  This will be the very next command
  1682.  * executed, unless a target connects to us.
  1683.  */
  1684. if (info->reqSCpnt)
  1685. printk(KERN_WARNING "scsi%d.%c: loosing request commandn",
  1686. info->host->host_no, '0' + SCpnt->target);
  1687. info->reqSCpnt = SCpnt;
  1688. }
  1689. /* Function: void fas216_done(FAS216_Info *info, unsigned int result)
  1690.  * Purpose : complete processing for current command
  1691.  * Params  : info   - interface that completed
  1692.  *      result - driver byte of result
  1693.  */
  1694. static void fas216_done(FAS216_Info *info, unsigned int result)
  1695. {
  1696. void (*fn)(FAS216_Info *, Scsi_Cmnd *, unsigned int);
  1697. Scsi_Cmnd *SCpnt;
  1698. fas216_checkmagic(info);
  1699. if (!info->SCpnt)
  1700. goto no_command;
  1701. SCpnt = info->SCpnt;
  1702. info->SCpnt = NULL;
  1703.      info->scsi.phase = PHASE_IDLE;
  1704. if (!SCpnt->scsi_done)
  1705. goto no_done;
  1706. if (info->scsi.aborting) {
  1707. printk("scsi%d.%c: uncaught abort - returning DID_ABORTn",
  1708. info->host->host_no, fas216_target(info));
  1709. result = DID_ABORT;
  1710. info->scsi.aborting = 0;
  1711. }
  1712. /*
  1713.  * Sanity check the completion - if we have zero bytes left
  1714.  * to transfer, we should not have a valid pointer.
  1715.  */
  1716. if (info->scsi.SCp.ptr && info->scsi.SCp.this_residual == 0) {
  1717. printk("scsi%d.%c: zero bytes left to transfer, but "
  1718.        "buffer pointer still valid: ptr=%p len=%08x command=",
  1719.        info->host->host_no, '0' + SCpnt->target,
  1720.        info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
  1721. info->scsi.SCp.ptr = NULL;
  1722. print_command(SCpnt->cmnd);
  1723. }
  1724. /*
  1725.  * Clear down this command as completed.  If we need to request
  1726.  * the sense information, fas216_kick will re-assert the busy
  1727.  * status.
  1728.  */
  1729. clear_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
  1730. fn = (void (*)(FAS216_Info *, Scsi_Cmnd *, unsigned int))SCpnt->host_scribble;
  1731. fn(info, SCpnt, result);
  1732. if (info->scsi.irq != NO_IRQ)
  1733. fas216_kick(info);
  1734. return;
  1735. no_command:
  1736. panic("scsi%d.H: null command in fas216_done",
  1737. info->host->host_no);
  1738. no_done:
  1739. panic("scsi%d.H: null scsi_done function in fas216_done",
  1740. info->host->host_no);
  1741. }
  1742. /* Function: int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
  1743.  * Purpose : queue a command for adapter to process.
  1744.  * Params  : SCpnt - Command to queue
  1745.  *      done  - done function to call once command is complete
  1746.  * Returns : 0 - success, else error
  1747.  * Notes   : io_request_lock is held, interrupts are disabled.
  1748.  */
  1749. int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
  1750. {
  1751. FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
  1752. int result;
  1753. fas216_checkmagic(info);
  1754. #ifdef DEBUG_CONNECT
  1755. printk("scsi%d.%c: received queuable command (%p) %02Xn",
  1756. SCpnt->host->host_no, '0' + SCpnt->target,
  1757. SCpnt, SCpnt->cmnd[0]);
  1758. #endif
  1759. SCpnt->scsi_done = done;
  1760. SCpnt->host_scribble = (void *)fas216_std_done;
  1761. SCpnt->result = 0;
  1762. SCpnt->SCp.Message = 0;
  1763. SCpnt->SCp.Status = 0;
  1764. if (SCpnt->use_sg) {
  1765. unsigned long len = 0;
  1766. int buf;
  1767. SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->buffer;
  1768. SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
  1769. SCpnt->SCp.ptr = (char *) SCpnt->SCp.buffer->address;
  1770. SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
  1771. /*
  1772.  * Calculate correct buffer length.  Some commands
  1773.  * come in with the wrong request_bufflen.
  1774.  */
  1775. for (buf = 0; buf <= SCpnt->SCp.buffers_residual; buf++)
  1776. len += SCpnt->SCp.buffer[buf].length;
  1777. if (SCpnt->request_bufflen != len)
  1778. printk(KERN_WARNING "scsi%d.%c: bad request buffer "
  1779.        "length %d, should be %ldn", info->host->host_no,
  1780.        '0' + SCpnt->target, SCpnt->request_bufflen, len);
  1781. SCpnt->request_bufflen = len;
  1782. } else {
  1783. SCpnt->SCp.buffer = NULL;
  1784. SCpnt->SCp.buffers_residual = 0;
  1785. SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer;
  1786. SCpnt->SCp.this_residual = SCpnt->request_bufflen;
  1787. }
  1788. /*
  1789.  * If the upper SCSI layers pass a buffer, but zero length,
  1790.  * we aren't interested in the buffer pointer.
  1791.  */
  1792. if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.ptr) {
  1793. #if 0
  1794. printk(KERN_WARNING "scsi%d.%c: zero length buffer passed for "
  1795.        "command ", info->host->host_no, '0' + SCpnt->target);
  1796. print_command(SCpnt->cmnd);
  1797. #endif
  1798. SCpnt->SCp.ptr = NULL;
  1799. }
  1800. info->stats.queues += 1;
  1801. SCpnt->tag = 0;
  1802. /*
  1803.  * Add command into execute queue and let it complete under
  1804.  * whatever scheme we're using.
  1805.  */
  1806. result = !queue_add_cmd_ordered(&info->queues.issue, SCpnt);
  1807. /*
  1808.  * If we successfully added the command,
  1809.  * kick the interface to get it moving.
  1810.  */
  1811. if (result == 0 && (!info->SCpnt || info->scsi.disconnectable))
  1812. fas216_kick(info);
  1813. return result;
  1814. }
  1815. /* Function: void fas216_internal_done(Scsi_Cmnd *SCpnt)
  1816.  * Purpose : trigger restart of a waiting thread in fas216_command
  1817.  * Params  : SCpnt - Command to wake
  1818.  */
  1819. static void fas216_internal_done(Scsi_Cmnd *SCpnt)
  1820. {
  1821. FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
  1822. fas216_checkmagic(info);
  1823. info->internal_done = 1;
  1824. }
  1825. /* Function: int fas216_command(Scsi_Cmnd *SCpnt)
  1826.  * Purpose : queue a command for adapter to process.
  1827.  * Params  : SCpnt - Command to queue
  1828.  * Returns : scsi result code
  1829.  * Notes   : io_request_lock is held, interrupts are disabled.
  1830.  */
  1831. int fas216_command(Scsi_Cmnd *SCpnt)
  1832. {
  1833. FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
  1834. fas216_checkmagic(info);
  1835. /*
  1836.  * We should only be using this if we don't have an interrupt.
  1837.  * Provide some "incentive" to use the queueing code.
  1838.  */
  1839. if (info->scsi.irq != NO_IRQ)
  1840. BUG();
  1841. info->internal_done = 0;
  1842. fas216_queue_command(SCpnt, fas216_internal_done);
  1843. /*
  1844.  * This wastes time, since we can't return until the command is
  1845.  * complete. We can't sleep either since we may get re-entered!
  1846.  * However, we must re-enable interrupts, or else we'll be
  1847.  * waiting forever.
  1848.  */
  1849. spin_unlock_irq(&io_request_lock);
  1850. while (!info->internal_done) {
  1851. /*
  1852.  * If we don't have an IRQ, then we must poll the card for
  1853.  * it's interrupt, and use that to call this driver's
  1854.  * interrupt routine.  That way, we keep the command
  1855.  * progressing.  Maybe we can add some inteligence here
  1856.  * and go to sleep if we know that the device is going
  1857.  * to be some time (eg, disconnected).
  1858.  */
  1859. if (inb(REG_STAT(info)) & STAT_INT) {
  1860. spin_lock_irq(&io_request_lock);
  1861. fas216_intr(info->host);
  1862. spin_unlock_irq(&io_request_lock);
  1863. }
  1864. }
  1865. spin_lock_irq(&io_request_lock);
  1866. return SCpnt->result;
  1867. }
  1868. enum res_abort {
  1869. res_failed, /* unable to abort */
  1870. res_success, /* command on issue queue */
  1871. res_success_clear, /* command marked tgt/lun busy */
  1872. res_hw_abort /* command on disconnected dev */
  1873. };
  1874. /*
  1875.  * Prototype: enum res_abort fas216_do_abort(FAS216_Info *info, Scsi_Cmnd *SCpnt)
  1876.  * Purpose  : decide how to abort a command
  1877.  * Params   : SCpnt - command to abort
  1878.  * Returns  : abort status
  1879.  */
  1880. static enum res_abort
  1881. fas216_do_abort(FAS216_Info *info, Scsi_Cmnd *SCpnt)
  1882. {
  1883. enum res_abort res = res_failed;
  1884. if (queue_remove_cmd(&info->queues.issue, SCpnt)) {
  1885. /*
  1886.  * The command was on the issue queue, and has not been
  1887.  * issued yet.  We can remove the command from the queue,
  1888.  * and acknowledge the abort.  Neither the device nor the
  1889.  * interface know about the command.
  1890.  */
  1891. printk("on issue queue ");
  1892. res = res_success;
  1893. } else if (queue_remove_cmd(&info->queues.disconnected, SCpnt)) {
  1894. /*
  1895.  * The command was on the disconnected queue.  We must
  1896.  * reconnect with the device if possible, and send it
  1897.  * an abort message.
  1898.  */
  1899. printk("on disconnected queue ");
  1900. res = res_hw_abort;
  1901. } else if (info->SCpnt == SCpnt) {
  1902. printk("executing ");
  1903. switch (info->scsi.phase) {
  1904. /*
  1905.  * If the interface is idle, and the command is 'disconnectable',
  1906.  * then it is the same as on the disconnected queue.
  1907.  */
  1908. case PHASE_IDLE:
  1909. if (info->scsi.disconnectable) {
  1910. info->scsi.disconnectable = 0;
  1911. info->SCpnt = NULL;
  1912. res = res_hw_abort;
  1913. }
  1914. break;
  1915. default:
  1916. break;
  1917. }
  1918. } else if (info->origSCpnt == SCpnt) {
  1919. /*
  1920.  * The command will be executed next, but a command
  1921.  * is currently using the interface.  This is similar to
  1922.  * being on the issue queue, except the busylun bit has
  1923.  * been set.
  1924.  */
  1925. info->origSCpnt = NULL;
  1926. printk("waiting for execution ");
  1927. res = res_success_clear;
  1928. } else
  1929. printk("unknown ");
  1930. return res;
  1931. }
  1932. /* Function: int fas216_eh_abort(Scsi_Cmnd *SCpnt)
  1933.  * Purpose : abort this command
  1934.  * Params  : SCpnt - command to abort
  1935.  * Returns : FAILED if unable to abort
  1936.  * Notes   : io_request_lock is taken, and irqs are disabled
  1937.  */
  1938. int fas216_eh_abort(Scsi_Cmnd *SCpnt)
  1939. {
  1940. FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
  1941. int result = FAILED;
  1942. fas216_checkmagic(info);
  1943. info->stats.aborts += 1;
  1944. print_debug_list();
  1945. fas216_dumpstate(info);
  1946. fas216_dumpinfo(info);
  1947. printk(KERN_WARNING "scsi%d: abort ", info->host->host_no);
  1948. switch (fas216_do_abort(info, SCpnt)) {
  1949. /*
  1950.  * We managed to find the command and cleared it out.
  1951.  * We do not expect the command to be executing on the
  1952.  * target, but we have set the busylun bit.
  1953.  */
  1954. case res_success_clear:
  1955. printk("clear ");
  1956. clear_bit(SCpnt->target * 8 + SCpnt->lun, info->busyluns);
  1957. /*
  1958.  * We found the command, and cleared it out.  Either
  1959.  * the command is still known to be executing on the
  1960.  * target, or the busylun bit is not set.
  1961.  */
  1962. case res_success:
  1963. printk("successn");
  1964. result = SUCCESS;
  1965. break;
  1966. /*
  1967.  * We need to reconnect to the target and send it an
  1968.  * ABORT or ABORT_TAG message.  We can only do this
  1969.  * if the bus is free.
  1970.  */
  1971. case res_hw_abort:
  1972. /*
  1973.  * We are unable to abort the command for some reason.
  1974.  */
  1975. default:
  1976. case res_failed:
  1977. printk("failedn");
  1978. break;
  1979. }
  1980. return result;
  1981. }
  1982. /* Function: void fas216_reset_state(FAS216_Info *info)
  1983.  * Purpose : Initialise driver internal state
  1984.  * Params  : info - state to initialise
  1985.  */
  1986. static void fas216_reset_state(FAS216_Info *info)
  1987. {
  1988. neg_t sync_state, wide_state;
  1989. int i;
  1990. fas216_checkmagic(info);
  1991. /*
  1992.  * Clear out all stale info in our state structure
  1993.  */
  1994. memset(info->busyluns, 0, sizeof(info->busyluns));
  1995. msgqueue_flush(&info->scsi.msgs);
  1996. info->scsi.reconnected.target = 0;
  1997. info->scsi.reconnected.lun = 0;
  1998. info->scsi.reconnected.tag = 0;
  1999. info->scsi.disconnectable = 0;
  2000. info->scsi.aborting = 0;
  2001. info->scsi.phase = PHASE_IDLE;
  2002. info->scsi.async_stp =
  2003. fas216_syncperiod(info, info->ifcfg.asyncperiod);
  2004. if (info->ifcfg.wide_max_size == 0)
  2005. wide_state = neg_invalid;
  2006. else
  2007. #ifdef SCSI2_WIDE
  2008. wide_state = neg_wait;
  2009. #else
  2010. wide_state = neg_invalid;
  2011. #endif
  2012. if (info->host->dma_channel == NO_DMA || !info->dma.setup)
  2013. sync_state = neg_invalid;
  2014. else
  2015. #ifdef SCSI2_SYNC
  2016. sync_state = neg_wait;
  2017. #else
  2018. sync_state = neg_invalid;
  2019. #endif
  2020. for (i = 0; i < 8; i++) {
  2021. info->device[i].disconnect_ok = info->ifcfg.disconnect_ok;
  2022. info->device[i].sync_state = sync_state;
  2023. info->device[i].wide_state = wide_state;
  2024. info->device[i].period = info->ifcfg.asyncperiod / 4;
  2025. info->device[i].stp = info->scsi.async_stp;
  2026. info->device[i].sof = 0;
  2027. info->device[i].wide_xfer = 0;
  2028. }
  2029. /*
  2030.  * Drain all commands on disconnected queue
  2031.  */
  2032. while (queue_remove(&info->queues.disconnected) != NULL);
  2033. /*
  2034.  * Remove executing commands.
  2035.  */
  2036. info->SCpnt     = NULL;
  2037. info->reqSCpnt  = NULL;
  2038. info->origSCpnt = NULL;
  2039. }
  2040. /* Function: int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
  2041.  * Purpose : Reset the device associated with this command
  2042.  * Params  : SCpnt - command specifing device to reset
  2043.  * Returns : FAILED if unable to reset
  2044.  */
  2045. int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
  2046. {
  2047. FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
  2048. printk("scsi%d.%c: "__FUNCTION__": calledn",
  2049. info->host->host_no, '0' + SCpnt->target);
  2050. return FAILED;
  2051. }
  2052. /* Function: int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
  2053.  * Purpose : Reset the bus associated with the command
  2054.  * Params  : SCpnt - command specifing bus to reset
  2055.  * Returns : FAILED if unable to reset
  2056.  * Notes   : io_request_lock is taken, and irqs are disabled
  2057.  */
  2058. int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
  2059. {
  2060. FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
  2061. int result = FAILED;
  2062. fas216_checkmagic(info);
  2063. info->stats.bus_resets += 1;
  2064. printk("scsi%d.%c: "__FUNCTION__": resetting busn",
  2065. info->host->host_no, '0' + SCpnt->target);
  2066. /*
  2067.  * Attempt to stop all activity on this interface.
  2068.  */
  2069. outb(info->scsi.cfg[2], REG_CNTL3(info));
  2070. fas216_stoptransfer(info);
  2071. /*
  2072.  * Clear any pending interrupts
  2073.  */
  2074. while (inb(REG_STAT(info)) & STAT_INT)
  2075. inb(REG_INST(info));
  2076. /*
  2077.  * Reset the SCSI bus
  2078.  */
  2079. outb(CMD_RESETSCSI, REG_CMD(info));
  2080. udelay(5);
  2081. /*
  2082.  * Clear reset interrupt
  2083.  */
  2084. if (inb(REG_STAT(info)) & STAT_INT &&
  2085.     inb(REG_INST(info)) & INST_BUSRESET)
  2086. result = SUCCESS;
  2087. fas216_reset_state(info);
  2088. return result;
  2089. }
  2090. /* Function: void fas216_init_chip(FAS216_Info *info)
  2091.  * Purpose : Initialise FAS216 state after reset
  2092.  * Params  : info - state structure for interface
  2093.  */
  2094. static void fas216_init_chip(FAS216_Info *info)
  2095. {
  2096. outb(fas216_clockrate(info->ifcfg.clockrate), REG_CLKF(info));
  2097. outb(info->scsi.cfg[0], REG_CNTL1(info));
  2098. outb(info->scsi.cfg[1], REG_CNTL2(info));
  2099. outb(info->scsi.cfg[2], REG_CNTL3(info));
  2100. outb(info->ifcfg.select_timeout, REG_STIM(info));
  2101. outb(0, REG_SOF(info));
  2102. outb(info->scsi.async_stp, REG_STP(info));
  2103. outb(info->scsi.cfg[0], REG_CNTL1(info));
  2104. }
  2105. /* Function: int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
  2106.  * Purpose : Reset the host associated with this command
  2107.  * Params  : SCpnt - command specifing host to reset
  2108.  * Returns : FAILED if unable to reset
  2109.  * Notes   : io_request_lock is taken, and irqs are disabled
  2110.  */
  2111. int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
  2112. {
  2113. FAS216_Info *info = (FAS216_Info *)SCpnt->host->hostdata;
  2114. fas216_checkmagic(info);
  2115. printk("scsi%d.%c: "__FUNCTION__": resetting hostn",
  2116. info->host->host_no, '0' + SCpnt->target);
  2117. /*
  2118.  * Reset the SCSI chip.
  2119.  */
  2120. outb(CMD_RESETCHIP, REG_CMD(info));
  2121. /*
  2122.  * Ugly ugly ugly!
  2123.  * We need to release the io_request_lock and enable
  2124.  * IRQs if we sleep, but we must relock and disable
  2125.  * IRQs after the sleep.
  2126.  */
  2127. spin_unlock_irq(&io_request_lock);
  2128. scsi_sleep(25*HZ/100);
  2129. spin_lock_irq(&io_request_lock);
  2130. /*
  2131.  * Release the SCSI reset.
  2132.  */
  2133. outb(CMD_NOP, REG_CMD(info));
  2134. fas216_init_chip(info);
  2135. return SUCCESS;
  2136. }
  2137. #define TYPE_UNKNOWN 0
  2138. #define TYPE_NCR53C90 1
  2139. #define TYPE_NCR53C90A 2
  2140. #define TYPE_NCR53C9x 3
  2141. #define TYPE_Am53CF94 4
  2142. #define TYPE_EmFAS216 5
  2143. #define TYPE_QLFAS216 6
  2144. static char *chip_types[] = {
  2145. "unknown",
  2146. "NS NCR53C90",
  2147. "NS NCR53C90A",
  2148. "NS NCR53C9x",
  2149. "AMD Am53CF94",
  2150. "Emulex FAS216",
  2151. "QLogic FAS216"
  2152. };
  2153. static int fas216_detect_type(FAS216_Info *info)
  2154. {
  2155. int family, rev;
  2156. /*
  2157.  * Reset the chip.
  2158.  */
  2159. outb(CMD_RESETCHIP, REG_CMD(info));
  2160. udelay(50);
  2161. outb(CMD_NOP, REG_CMD(info));
  2162. /*
  2163.  * Check to see if control reg 2 is present.
  2164.  */
  2165. outb(0, REG_CNTL3(info));
  2166. outb(CNTL2_S2FE, REG_CNTL2(info));
  2167. /*
  2168.  * If we are unable to read back control reg 2
  2169.  * correctly, it is not present, and we have a
  2170.  * NCR53C90.
  2171.  */
  2172. if ((inb(REG_CNTL2(info)) & (~0xe0)) != CNTL2_S2FE)
  2173. return TYPE_NCR53C90;
  2174. /*
  2175.  * Now, check control register 3
  2176.  */
  2177. outb(0, REG_CNTL2(info));
  2178. outb(0, REG_CNTL3(info));
  2179. outb(5, REG_CNTL3(info));
  2180. /*
  2181.  * If we are unable to read the register back
  2182.  * correctly, we have a NCR53C90A
  2183.  */
  2184. if (inb(REG_CNTL3(info)) != 5)
  2185. return TYPE_NCR53C90A;
  2186. /*
  2187.  * Now read the ID from the chip.
  2188.  */
  2189. outb(0, REG_CNTL3(info));
  2190. outb(CNTL3_ADIDCHK, REG_CNTL3(info));
  2191. outb(0, REG_CNTL3(info));
  2192. outb(CMD_RESETCHIP, REG_CMD(info));
  2193. udelay(5);
  2194. outb(CMD_WITHDMA | CMD_NOP, REG_CMD(info));
  2195. outb(CNTL2_ENF, REG_CNTL2(info));
  2196. outb(CMD_RESETCHIP, REG_CMD(info));
  2197. udelay(5);
  2198. outb(CMD_NOP, REG_CMD(info));
  2199. rev     = inb(REG1_ID(info));
  2200. family  = rev >> 3;
  2201. rev    &= 7;
  2202. switch (family) {
  2203. case 0x01:
  2204. if (rev == 4)
  2205. return TYPE_Am53CF94;
  2206. break;
  2207. case 0x02:
  2208. switch (rev) {
  2209. case 2:
  2210. return TYPE_EmFAS216;
  2211. case 3:
  2212. return TYPE_QLFAS216;
  2213. }
  2214. break;
  2215. default:
  2216. break;
  2217. }
  2218. printk("family %x rev %xn", family, rev);
  2219. return TYPE_NCR53C9x;
  2220. }
  2221. /* Function: int fas216_init(struct Scsi_Host *instance)
  2222.  * Purpose : initialise FAS/NCR/AMD SCSI ic.
  2223.  * Params  : instance - a driver-specific filled-out structure
  2224.  * Returns : 0 on success
  2225.  */
  2226. int fas216_init(struct Scsi_Host *instance)
  2227. {
  2228. FAS216_Info *info = (FAS216_Info *)instance->hostdata;
  2229. int type;
  2230. info->magic_start = MAGIC;
  2231. info->magic_end   = MAGIC;
  2232. info->host        = instance;
  2233. info->scsi.cfg[0] = instance->this_id;
  2234. info->scsi.cfg[1] = CNTL2_ENF | CNTL2_S2FE;
  2235. info->scsi.cfg[2] = info->ifcfg.cntl3 | CNTL3_ADIDCHK | CNTL3_G2CB;
  2236. memset(&info->stats, 0, sizeof(info->stats));
  2237. msgqueue_initialise(&info->scsi.msgs);
  2238. if (!queue_initialise(&info->queues.issue))
  2239. return 1;
  2240. if (!queue_initialise(&info->queues.disconnected)) {
  2241. queue_free(&info->queues.issue);
  2242. return 1;
  2243. }
  2244. fas216_reset_state(info);
  2245. type = fas216_detect_type(info);
  2246. info->scsi.type = chip_types[type];
  2247. udelay(300);
  2248. /*
  2249.  * Initialise the chip correctly.
  2250.  */
  2251. fas216_init_chip(info);
  2252. /*
  2253.  * Reset the SCSI bus.  We don't want to see
  2254.  * the resulting reset interrupt, so mask it
  2255.  * out.
  2256.  */
  2257. outb(info->scsi.cfg[0] | CNTL1_DISR, REG_CNTL1(info));
  2258. outb(CMD_RESETSCSI, REG_CMD(info));
  2259. /*
  2260.  * scsi standard says wait 250ms
  2261.  */
  2262. spin_unlock_irq(&io_request_lock);
  2263. scsi_sleep(25*HZ/100);
  2264. spin_lock_irq(&io_request_lock);
  2265. outb(info->scsi.cfg[0], REG_CNTL1(info));
  2266. inb(REG_INST(info));
  2267. fas216_checkmagic(info);
  2268. return 0;
  2269. }
  2270. /* Function: int fas216_release(struct Scsi_Host *instance)
  2271.  * Purpose : release all resources and put everything to bed for
  2272.  *           FAS/NCR/AMD SCSI ic.
  2273.  * Params  : instance - a driver-specific filled-out structure
  2274.  * Returns : 0 on success
  2275.  */
  2276. int fas216_release(struct Scsi_Host *instance)
  2277. {
  2278. FAS216_Info *info = (FAS216_Info *)instance->hostdata;
  2279. fas216_checkmagic(info);
  2280. outb(CMD_RESETCHIP, REG_CMD(info));
  2281. queue_free(&info->queues.disconnected);
  2282. queue_free(&info->queues.issue);
  2283. return 0;
  2284. }
  2285. /*
  2286.  * Function: int fas216_info(FAS216_Info *info, char *buffer)
  2287.  * Purpose : generate a string containing information about this
  2288.  *      host.
  2289.  * Params  : info   - FAS216 host information
  2290.  *      buffer - string buffer to build string
  2291.  * Returns : size of built string
  2292.  */
  2293. int fas216_info(FAS216_Info *info, char *buffer)
  2294. {
  2295. char *p = buffer;
  2296. p += sprintf(p, "(%s) at port 0x%08lX ",
  2297.      info->scsi.type, info->host->io_port);
  2298. if (info->host->irq != NO_IRQ)
  2299. p += sprintf(p, "irq %d ", info->host->irq);
  2300. else
  2301. p += sprintf(p, "no irq ");
  2302. if (info->host->dma_channel != NO_DMA)
  2303. p += sprintf(p, "dma %d ", info->host->dma_channel);
  2304. else
  2305. p += sprintf(p, "no dma ");
  2306. return p - buffer;
  2307. }
  2308. int fas216_print_host(FAS216_Info *info, char *buffer)
  2309. {
  2310. return sprintf(buffer,
  2311. "n"
  2312. "Chip    : %sn"
  2313. " Address: 0x%08lXn"
  2314. " IRQ    : %dn"
  2315. " DMA    : %dn",
  2316. info->scsi.type, info->host->io_port,
  2317. info->host->irq, info->host->dma_channel);
  2318. }
  2319. int fas216_print_stats(FAS216_Info *info, char *buffer)
  2320. {
  2321. return sprintf(buffer,
  2322. "n"
  2323. "Command Statistics:n"
  2324. " Queued     : %un"
  2325. " Issued     : %un"
  2326. " Completed  : %un"
  2327. " Reads      : %un"
  2328. " Writes     : %un"
  2329. " Others     : %un"
  2330. " Disconnects: %un"
  2331. " Aborts     : %un"
  2332. " Bus resets : %un"
  2333. " Host resets: %un",
  2334. info->stats.queues,  info->stats.removes,
  2335. info->stats.fins,  info->stats.reads,
  2336. info->stats.writes,  info->stats.miscs,
  2337. info->stats.disconnects, info->stats.aborts,
  2338. info->stats.bus_resets,  info->stats.host_resets);
  2339. }
  2340. int fas216_print_device(FAS216_Info *info, Scsi_Device *scd, char *buffer)
  2341. {
  2342. struct fas216_device *dev = &info->device[scd->id];
  2343. int len = 0;
  2344. char *p;
  2345. proc_print_scsidevice(scd, buffer, &len, 0);
  2346. p = buffer + len;
  2347. p += sprintf(p, "  Extensions: ");
  2348. if (scd->tagged_supported)
  2349. p += sprintf(p, "TAG %sabled [%d] ",
  2350.      scd->tagged_queue ? "en" : "dis",
  2351.      scd->current_tag);
  2352. p += sprintf(p, "n  Transfers : %d-bit ",
  2353.      8 << dev->wide_xfer);
  2354. if (dev->sof)
  2355. p += sprintf(p, "sync offset %d, %d nsn",
  2356. dev->sof, dev->period * 4);
  2357. else
  2358. p += sprintf(p, "asyncn");
  2359. return p - buffer;
  2360. }
  2361. EXPORT_SYMBOL(fas216_info);
  2362. EXPORT_SYMBOL(fas216_init);
  2363. EXPORT_SYMBOL(fas216_queue_command);
  2364. EXPORT_SYMBOL(fas216_command);
  2365. EXPORT_SYMBOL(fas216_intr);
  2366. EXPORT_SYMBOL(fas216_release);
  2367. EXPORT_SYMBOL(fas216_eh_abort);
  2368. EXPORT_SYMBOL(fas216_eh_device_reset);
  2369. EXPORT_SYMBOL(fas216_eh_bus_reset);
  2370. EXPORT_SYMBOL(fas216_eh_host_reset);
  2371. EXPORT_SYMBOL(fas216_print_host);
  2372. EXPORT_SYMBOL(fas216_print_stats);
  2373. EXPORT_SYMBOL(fas216_print_device);
  2374. MODULE_AUTHOR("Russell King");
  2375. MODULE_DESCRIPTION("Generic FAS216/NCR53C9x driver core");
  2376. MODULE_LICENSE("GPL");