patch-2.4.0-test12 linux/drivers/scsi/wd33c93.c
Next file: linux/drivers/scsi/wd33c93.h
Previous file: linux/drivers/scsi/u14-34f.h
Back to the patch index
Back to the overall index
- Lines: 104
- Date:
Tue Dec 5 12:43:48 2000
- Orig file:
v2.4.0-test11/linux/drivers/scsi/wd33c93.c
- Orig date:
Mon Mar 27 09:48:11 2000
diff -u --recursive --new-file v2.4.0-test11/linux/drivers/scsi/wd33c93.c linux/drivers/scsi/wd33c93.c
@@ -66,8 +66,14 @@
* this thing into as good a shape as possible, and I'm positive
* there are lots of lurking bugs and "Stupid Places".
*
+ * Updates:
+ *
+ * Added support for pre -A chips, which don't have advanced features
+ * and will generate CSR_RESEL rather than CSR_RESEL_AM.
+ * Richard Hirst <richard@sleepie.demon.co.uk> August 2000
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <asm/system.h>
@@ -1251,11 +1257,16 @@
case CSR_RESEL_AM:
-DB(DB_INTR,printk("RESEL"))
+ case CSR_RESEL:
+DB(DB_INTR,printk("RESEL%s", sr == CSR_RESEL_AM ? "_AM" : ""))
- /* First we have to make sure this reselection didn't */
- /* happen during Arbitration/Selection of some other device. */
- /* If yes, put losing command back on top of input_Q. */
+ /* Old chips (pre -A ???) don't have advanced features and will
+ * generate CSR_RESEL. In that case we have to extract the LUN the
+ * hard way (see below).
+ * First we have to make sure this reselection didn't
+ * happen during Arbitration/Selection of some other device.
+ * If yes, put losing command back on top of input_Q.
+ */
if (hostdata->level2 <= L2_NONE) {
@@ -1295,10 +1306,53 @@
* not the right way to go, but...)
*/
- lun = read_wd33c93(regp, WD_DATA);
- if (hostdata->level2 < L2_RESELECT)
- write_wd33c93_cmd(regp,WD_CMD_NEGATE_ACK);
- lun &= 7;
+ if (sr == CSR_RESEL_AM) {
+ lun = read_wd33c93(regp, WD_DATA);
+ if (hostdata->level2 < L2_RESELECT)
+ write_wd33c93_cmd(regp,WD_CMD_NEGATE_ACK);
+ lun &= 7;
+ }
+ else {
+ /* Old chip; wait for msgin phase to pick up the LUN. */
+ for (lun = 255; lun; lun--) {
+ if ((asr = READ_AUX_STAT()) & ASR_INT)
+ break;
+ udelay(10);
+ }
+ if (!(asr & ASR_INT)) {
+ printk("wd33c93: Reselected without IDENTIFY\n");
+ lun = 0;
+ }
+ else {
+ /* Verify this is a change to MSG_IN and read the message */
+ sr = read_wd33c93(regp, WD_SCSI_STATUS);
+ if (sr == (CSR_ABORT | PHS_MESS_IN) ||
+ sr == (CSR_UNEXP | PHS_MESS_IN) ||
+ sr == (CSR_SRV_REQ | PHS_MESS_IN)) {
+ /* Got MSG_IN, grab target LUN */
+ lun = read_1_byte(regp);
+ /* Now we expect a 'paused with ACK asserted' int.. */
+ asr = READ_AUX_STAT();
+ if (!(asr & ASR_INT)) {
+ udelay(10);
+ asr = READ_AUX_STAT();
+ if (!(asr & ASR_INT))
+ printk("wd33c93: No int after LUN on RESEL (%02x)\n",
+ asr);
+ }
+ sr = read_wd33c93(regp, WD_SCSI_STATUS);
+ if (sr != CSR_MSGIN)
+ printk("wd33c93: Not paused with ACK on RESEL (%02x)\n",
+ sr);
+ lun &= 7;
+ write_wd33c93_cmd(regp,WD_CMD_NEGATE_ACK);
+ }
+ else {
+ printk("wd33c93: Not MSG_IN on reselect (%02x)\n", sr);
+ lun = 0;
+ }
+ }
+ }
/* Now we look for the command that's reconnecting. */
@@ -1372,6 +1426,9 @@
write_wd33c93(regp, WD_SYNCHRONOUS_TRANSFER,
calc_sync_xfer(hostdata->default_sx_per/4,DEFAULT_SX_OFF));
write_wd33c93(regp, WD_COMMAND, WD_CMD_RESET);
+#ifdef CONFIG_MVME147_SCSI
+ udelay(25); /* The old wd33c93 on MVME147 needs this, at least */
+#endif
while (!(READ_AUX_STAT() & ASR_INT))
;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)