patch-2.1.79 linux/drivers/scsi/ncr53c8xx.c
Next file: linux/drivers/scsi/ncr53c8xx.h
Previous file: linux/drivers/scsi/ide-scsi.c
Back to the patch index
Back to the overall index
- Lines: 365
- Date:
Mon Jan 12 15:05:27 1998
- Orig file:
v2.1.78/linux/drivers/scsi/ncr53c8xx.c
- Orig date:
Tue Dec 23 16:30:59 1997
diff -u --recursive --new-file v2.1.78/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c
@@ -67,7 +67,7 @@
*/
/*
-** 20 September 1997, version 2.5c
+** 2 January 1998, version 2.5f
**
** Supported SCSI-II features:
** Synchronous negotiation
@@ -504,7 +504,7 @@
unsigned master_parity : 1;
unsigned scsi_parity : 1;
unsigned disconnection : 1;
- unsigned special_features : 1;
+ unsigned special_features : 2;
unsigned ultra_scsi : 2;
unsigned force_sync_nego: 1;
unsigned reverse_probe: 1;
@@ -520,6 +520,7 @@
u_char settle_delay;
u_char diff_support;
u_char irqm;
+ u_char bus_check;
};
static struct ncr_driver_setup
@@ -578,7 +579,8 @@
u_short flags1;
#define SYMBIOS_SCAN_HI_LO (1)
u_short word10; /* 0x00 */
- u_short word12; /* 0x00 */
+ u_short flags3; /* 0x00 */
+#define SYMBIOS_REMOVABLE_FLAGS (3) /* 0=none, 1=bootable, 2=all */
u_char host_id;
u_char byte15; /* 0x04 */
u_short word16; /* 0x0410 */
@@ -693,7 +695,7 @@
ncr_slot slot;
ncr_chip chip;
ncr_nvram *nvram;
- int attached;
+ int attach_done;
} ncr_device;
/*==========================================================
@@ -1883,7 +1885,7 @@
ncrcmd prepare2 [ 24];
ncrcmd setmsg [ 5];
ncrcmd clrack [ 2];
- ncrcmd dispatch [ 33];
+ ncrcmd dispatch [ 38];
ncrcmd no_data [ 17];
ncrcmd checkatn [ 10];
ncrcmd command [ 15];
@@ -1985,6 +1987,7 @@
static void ncr_timeout (ncb_p np);
static void ncr_wakeup (ncb_p np, u_long code);
static void ncr_start_reset (ncb_p np, int settle_delay);
+static int ncr_reset_scsi_bus (ncb_p np, int enab_int, int settle_delay);
#ifdef SCSI_NCR_USER_COMMAND_SUPPORT
static void ncr_usercmd (ncb_p np);
@@ -2380,8 +2383,21 @@
0,
SCR_RETURN ^ IFTRUE (WHEN (SCR_DATA_OUT)),
0,
- SCR_RETURN ^ IFTRUE (IF (SCR_DATA_IN)),
+ /*
+ ** DEL 397 - 53C875 Rev 3 - Part Number 609-0392410 - ITEM 4.
+ ** Possible data corruption during Memory Write and Invalidate.
+ ** This work-around resets the addressing logic prior to the
+ ** start of the first MOVE of a DATA IN phase.
+ ** (See README.ncr53c8xx for more information)
+ */
+ SCR_JUMPR ^ IFFALSE (IF (SCR_DATA_IN)),
+ 20,
+ SCR_COPY (4),
+ RADDR (scratcha),
+ RADDR (scratcha),
+ SCR_RETURN,
0,
+
SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT)),
PADDR (msg_out),
SCR_JUMP ^ IFTRUE (IF (SCR_MSG_IN)),
@@ -4602,7 +4618,11 @@
** Then enable disconnects.
*/
save_flags(flags); cli();
- ncr_start_reset(np, driver_setup.settle_delay);
+ if (ncr_reset_scsi_bus(np, 0, driver_setup.settle_delay) != 0) {
+ printf("%s: FATAL ERROR: CHECK SCSI BUS - CABLES, TERMINATION, DEVICE POWER etc.!\n", ncr_name(np));
+ restore_flags(flags);
+ goto attach_error;
+ }
ncr_exception (np);
restore_flags(flags);
@@ -4670,6 +4690,16 @@
#endif
release_region(np->port, 128);
}
+ if (np->irq) {
+#ifdef DEBUG_NCR53C8XX
+ printf("%s: freeing irq %d\n", ncr_name(np), np->irq);
+#endif
+#if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,70)
+ free_irq(np->irq, np);
+#else
+ free_irq(np->irq);
+#endif
+ }
scsi_unregister(instance);
return -1;
@@ -5191,21 +5221,64 @@
save_flags(flags); cli();
if (!np->settle_time) {
- if (bootverbose > 1)
- printf("%s: resetting, command processing suspended for %d seconds\n",
- ncr_name(np), settle_delay);
- np->settle_time = jiffies + settle_delay * HZ;
- OUTB (nc_istat, SRST);
- DELAY (1000);
- OUTB (nc_istat, 0);
- OUTW (nc_sien, RST);
- OUTB (nc_scntl1, CRST);
- DELAY (100);
+ (void) ncr_reset_scsi_bus(np, 1, settle_delay);
}
-
restore_flags(flags);
}
+static int ncr_reset_scsi_bus(ncb_p np, int enab_int, int settle_delay)
+{
+ u_int32 term;
+ int retv = 0;
+
+ np->settle_time = jiffies + settle_delay * HZ;
+
+ if (bootverbose > 1)
+ printf("%s: resetting, "
+ "command processing suspended for %d seconds\n",
+ ncr_name(np), settle_delay);
+
+ OUTB (nc_istat, SRST);
+ DELAY (1000);
+ OUTB (nc_istat, 0);
+ if (enab_int)
+ OUTW (nc_sien, RST);
+ OUTB (nc_scntl1, CRST);
+ DELAY (100);
+
+ if (!driver_setup.bus_check)
+ goto out;
+ /*
+ ** Check for no terminators or SCSI bus shorts to ground.
+ ** Read SCSI data bus, data parity bits and control signals.
+ ** We are expecting RESET to be TRUE and other signals to be
+ ** FALSE.
+ */
+ term = INB(nc_sstat0); /* rst, sdp0 */
+ term = ((term & 2) << 7) + ((term & 1) << 16);
+ term |= ((INB(nc_sstat2) & 0x01) << 25) | /* sdp1 */
+ (INW(nc_sbdl) << 9) | /* d15-0 */
+ INB(nc_sbcl); /* req, ack, bsy, sel, atn, msg, cd, io */
+
+ if (!(np->features & FE_WIDE))
+ term &= 0x3ffff;
+
+ if (term != (2<<7)) {
+ printf("%s: suspicious SCSI data while resetting the BUS.\n",
+ ncr_name(np));
+ printf("%s: %sdp0,d7-0,rst,req,ack,bsy,sel,atn,msg,c/d,i/o = "
+ "0x%lx, expecting 0x%lx\n",
+ ncr_name(np),
+ (np->features & FE_WIDE) ? "dp1,d15-8," : "",
+ (u_long)term, (u_long)(2<<7));
+ if (driver_setup.bus_check == 1)
+ retv = 1;
+ }
+out:
+ OUTB (nc_scntl1, 0);
+ return retv;
+}
+
/*==========================================================
**
**
@@ -5618,10 +5691,12 @@
** Check the status.
*/
if ( (cp->host_status == HS_COMPLETE)
- && (cp->scsi_status == S_GOOD)) {
-
+ && (cp->scsi_status == S_GOOD ||
+ cp->scsi_status == S_COND_MET)) {
/*
- ** All went well.
+ ** All went well (GOOD status).
+ ** CONDITION MET status is returned on
+ ** `Pre-Fetch' or `Search data' success.
*/
cmd->result = ScsiResult(DID_OK, cp->scsi_status);
@@ -5716,7 +5791,8 @@
}
} else if ((cp->host_status == HS_COMPLETE)
- && (cp->scsi_status == S_BUSY)) {
+ && (cp->scsi_status == S_BUSY ||
+ cp->scsi_status == S_CONFLICT)) {
/*
** Target is busy.
@@ -6250,7 +6326,7 @@
if (tp->period < 500) scsi = "FAST-40";
else if (tp->period < 1000) scsi = "FAST-20";
else if (tp->period < 2000) scsi = "FAST-10";
- else scsi = "SLOW";
+ else scsi = "FAST-5";
printf ("%s %sSCSI %d.%d MB/s (%d ns, offset %d)\n", scsi,
tp->widedone > 1 ? "WIDE " : "",
@@ -6929,9 +7005,16 @@
ncr_int_sir (np);
return;
}
- if (!(sist & (SBMC|PAR)) && !(dstat & SSI))
- printf("%s: unknown interrupt(s) ignored sist=%x dstat=%x\n",
- ncr_name(np), sist, dstat);
+ /*
+ ** DEL 397 - 53C875 Rev 3 - Part Number 609-0392410 - ITEM 2.
+ */
+ if (!(sist & (SBMC|PAR)) && !(dstat & SSI)) {
+ printf( "%s: unknown interrupt(s) ignored, "
+ "ISTAT=%x DSTAT=%x SIST=%x\n",
+ ncr_name(np), istat, dstat, sist);
+ return;
+ }
+
OUTONB (nc_dcntl, (STD|NOCOM));
return;
};
@@ -6958,6 +7041,11 @@
if ((sist & STO) &&
!(dstat & (MDPE|BF|ABRT))) {
+ /*
+ ** DEL 397 - 53C875 Rev 3 - Part Number 609-0392410 - ITEM 1.
+ */
+ OUTONB (nc_ctest3, CLF);
+
ncr_int_sto (np);
return;
};
@@ -8915,6 +9003,8 @@
driver_setup.irqm = val;
else if (!strncmp(cur, "pcifix:", 7))
driver_setup.pci_fix_up = val;
+ else if (!strncmp(cur, "buschk:", 7))
+ driver_setup.bus_check = val;
#ifdef SCSI_NCR_NVRAM_SUPPORT
else if (!strncmp(cur, "nvram:", 6))
driver_setup.use_nvram = val;
@@ -8958,9 +9048,9 @@
)
{
#define YesNo(y) y ? 'y' : 'n'
- printk("ncr53c8xx: setup=disc:%c,specf:%c,ultra:%c,tags:%d,sync:%d,burst:%d,wide:%c,diff:%d\n",
+ printk("ncr53c8xx: setup=disc:%c,specf:%d,ultra:%c,tags:%d,sync:%d,burst:%d,wide:%c,diff:%d\n",
YesNo(driver_setup.disconnection),
- YesNo(driver_setup.special_features),
+ driver_setup.special_features,
YesNo(driver_setup.ultra_scsi),
driver_setup.default_tags,
driver_setup.default_sync,
@@ -9059,10 +9149,10 @@
h->device_id == devp->chip.device_id)
break;
}
- if (j < count && !devp->attached &&
- !ncr_attach (tpnt, attach_count, devp)) {
- attach_count++;
- devp->attached = 1;
+ if (j < count && !devp->attach_done) {
+ if (!ncr_attach (tpnt, attach_count, devp))
+ attach_count++;
+ devp->attach_done = 1;
}
}
@@ -9171,8 +9261,6 @@
#endif
printf(KERN_INFO "ncr53c8xx: 53c%s detected %s\n",
device[count].chip.name, msg);
-
- device[count].attached = 0;
++count;
}
}
@@ -9185,9 +9273,9 @@
** so try to attach them here.
*/
for (i= 0; i < count; i++) {
- if ((!device[i].attached) && (!ncr_attach (tpnt, attach_count, &device[i]))) {
+ if (!device[i].attach_done &&
+ !ncr_attach (tpnt, attach_count, &device[i])) {
attach_count++;
- device[i].attached = 1;
}
}
@@ -9281,10 +9369,10 @@
command |= PCI_COMMAND_MASTER|PCI_COMMAND_IO|PCI_COMMAND_MEMORY;
pcibios_write_config_word(bus, device_fn, PCI_COMMAND, command);
}
- if (io_port >= 0x10000000) {
+ if (io_port >= 0x10000000) {
io_port = (io_port & 0x00FFFFFF) | 0x01000000;
pcibios_write_config_dword(bus, device_fn, PCI_BASE_ADDRESS_0, io_port);
- }
+ }
if (base >= 0x10000000) {
base = (base & 0x00FFFFFF) | 0x01000000;
pcibios_write_config_dword(bus, device_fn, PCI_BASE_ADDRESS_1, base);
@@ -9339,8 +9427,12 @@
/*
* Fix some features according to driver setup.
*/
- if (!driver_setup.special_features)
+ if (!(driver_setup.special_features & 1))
chip->features &= ~FE_SPECIAL_SET;
+ else {
+ if (driver_setup.special_features & 2)
+ chip->features &= ~FE_WRIE;
+ }
if (driver_setup.ultra_scsi < 2 && (chip->features & FE_ULTRA2)) {
chip->features |= FE_ULTRA;
chip->features &= ~FE_ULTRA2;
@@ -9359,7 +9451,12 @@
#if defined(__i386) && !defined(MODULE)
if ((driver_setup.pci_fix_up & 1) &&
(chip->features & FE_CLSE) && cache_line_size == 0) {
- switch(boot_cpu_data.x86) {
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,1,75)
+ extern char x86;
+ switch(x86) {
+#else
+ switch(boot_cpu_data.x86) {
+#endif
case 4: cache_line_size = 4; break;
case 5: cache_line_size = 8; break;
}
@@ -9446,7 +9543,7 @@
device->slot.base_2 = base_2;
device->slot.io_port = io_port;
device->slot.irq = irq;
- device->attached = 0;
+ device->attach_done = 0;
#ifdef SCSI_NCR_NVRAM_SUPPORT
if (!nvram)
goto out;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov