static void sym_print_msg(struct sym_ccb *cp, char *label, u_char *msg)
{
- sym_print_addr(cp->cmd, "%s: ", label);
+ if (label)
+ sym_print_addr(cp->cmd, "%s: ", label);
+ else
+ sym_print_addr(cp->cmd, "");
spi_print_msg(msg);
printf("\n");
* calculations more simple.
*/
#define _5M 5000000
-static u32 div_10M[] = {2*_5M, 3*_5M, 4*_5M, 6*_5M, 8*_5M, 12*_5M, 16*_5M};
+static const u32 div_10M[] = {2*_5M, 3*_5M, 4*_5M, 6*_5M, 8*_5M, 12*_5M, 16*_5M};
/*
* Get clock factor and sync divisor for a given
np->sv_ctest5 = INB(np, nc_ctest5) & 0x24;
}
+/*
+ * Set SCSI BUS mode.
+ * - LVD capable chips (895/895A/896/1010) report the current BUS mode
+ * through the STEST4 IO register.
+ * - For previous generation chips (825/825A/875), the user has to tell us
+ * how to check against HVD, since a 100% safe algorithm is not possible.
+ */
+static void sym_set_bus_mode(struct sym_hcb *np, struct sym_nvram *nvram)
+{
+ if (np->scsi_mode)
+ return;
+
+ np->scsi_mode = SMODE_SE;
+ if (np->features & (FE_ULTRA2|FE_ULTRA3))
+ np->scsi_mode = (np->sv_stest4 & SMODE);
+ else if (np->features & FE_DIFF) {
+ if (SYM_SETUP_SCSI_DIFF == 1) {
+ if (np->sv_scntl3) {
+ if (np->sv_stest2 & 0x20)
+ np->scsi_mode = SMODE_HVD;
+ } else if (nvram->type == SYM_SYMBIOS_NVRAM) {
+ if (!(INB(np, nc_gpreg) & 0x08))
+ np->scsi_mode = SMODE_HVD;
+ }
+ } else if (SYM_SETUP_SCSI_DIFF == 2)
+ np->scsi_mode = SMODE_HVD;
+ }
+ if (np->scsi_mode == SMODE_HVD)
+ np->rv_stest2 |= 0x20;
+}
+
/*
* Prepare io register values used by sym_start_up()
* according to selected and supported features.
u32 period;
int i;
- /*
- * Wide ?
- */
- np->maxwide = (np->features & FE_WIDE)? 1 : 0;
+ np->maxwide = (np->features & FE_WIDE) ? 1 : 0;
/*
* Guess the frequency of the chip's clock.
* are used. Disable internal cycles.
*/
if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 &&
- np->revision_id < 0x1)
+ np->s.device->revision < 0x1)
np->rv_ccntl0 |= DILS;
/*
* LOAD/STORE instructions does not need this work-around.
*/
if ((np->device_id == PCI_DEVICE_ID_NCR_53C810 &&
- np->revision_id >= 0x10 && np->revision_id <= 0x11) ||
+ np->s.device->revision >= 0x10 && np->s.device->revision <= 0x11) ||
(np->device_id == PCI_DEVICE_ID_NCR_53C860 &&
- np->revision_id <= 0x1))
+ np->s.device->revision <= 0x1))
np->features &= ~(FE_WRIE|FE_ERL|FE_ERMP);
/*
* Get parity checking, host ID and verbose mode from NVRAM
*/
np->myaddr = 255;
+ np->scsi_mode = 0;
sym_nvram_setup_host(shost, np, nvram);
/*
*/
sym_init_burst(np, burst_max);
- /*
- * Set SCSI BUS mode.
- * - LVD capable chips (895/895A/896/1010) report the
- * current BUS mode through the STEST4 IO register.
- * - For previous generation chips (825/825A/875),
- * user has to tell us how to check against HVD,
- * since a 100% safe algorithm is not possible.
- */
- np->scsi_mode = SMODE_SE;
- if (np->features & (FE_ULTRA2|FE_ULTRA3))
- np->scsi_mode = (np->sv_stest4 & SMODE);
- else if (np->features & FE_DIFF) {
- if (SYM_SETUP_SCSI_DIFF == 1) {
- if (np->sv_scntl3) {
- if (np->sv_stest2 & 0x20)
- np->scsi_mode = SMODE_HVD;
- }
- else if (nvram->type == SYM_SYMBIOS_NVRAM) {
- if (!(INB(np, nc_gpreg) & 0x08))
- np->scsi_mode = SMODE_HVD;
- }
- }
- else if (SYM_SETUP_SCSI_DIFF == 2)
- np->scsi_mode = SMODE_HVD;
- }
- if (np->scsi_mode == SMODE_HVD)
- np->rv_stest2 |= 0x20;
+ sym_set_bus_mode(np, nvram);
/*
* Set LED support from SCRIPTS.
*
* Has to be called with interrupts disabled.
*/
-#ifndef CONFIG_SCSI_SYM53C8XX_IOMAPPED
-static int sym_regtest (struct sym_hcb *np)
+#ifdef CONFIG_SCSI_SYM53C8XX_MMIO
+static int sym_regtest(struct sym_hcb *np)
{
register volatile u32 data;
/*
#endif
printf ("CACHE TEST FAILED: reg dstat-sstat2 readback %x.\n",
(unsigned) data);
- return (0x10);
+ return 0x10;
}
- return (0);
+ return 0;
+}
+#else
+static inline int sym_regtest(struct sym_hcb *np)
+{
+ return 0;
}
#endif
-static int sym_snooptest (struct sym_hcb *np)
+static int sym_snooptest(struct sym_hcb *np)
{
- u32 sym_rd, sym_wr, sym_bk, host_rd, host_wr, pc, dstat;
- int i, err=0;
-#ifndef CONFIG_SCSI_SYM53C8XX_IOMAPPED
- err |= sym_regtest (np);
- if (err) return (err);
-#endif
+ u32 sym_rd, sym_wr, sym_bk, host_rd, host_wr, pc, dstat;
+ int i, err;
+
+ err = sym_regtest(np);
+ if (err)
+ return err;
restart_test:
/*
* Enable Master Parity Checking as we intend
err |= 4;
}
- return (err);
+ return err;
}
/*
scr_to_cpu((int) *(u32 *)(script_base + script_ofs)));
}
- printf ("%s: regdump:", sym_name(np));
- for (i=0; i<24;i++)
- printf (" %02x", (unsigned)INB_OFF(np, i));
- printf (".\n");
+ printf("%s: regdump:", sym_name(np));
+ for (i = 0; i < 24; i++)
+ printf(" %02x", (unsigned)INB_OFF(np, i));
+ printf(".\n");
/*
* PCI BUS error.
sym_log_bus_error(np);
}
+void sym_dump_registers(struct sym_hcb *np)
+{
+ u_short sist;
+ u_char dstat;
+
+ sist = INW(np, nc_sist);
+ dstat = INB(np, nc_dstat);
+ sym_log_hard_error(np, sist, dstat);
+}
+
static struct sym_chip sym_dev_table[] = {
{PCI_DEVICE_ID_NCR_53C810, 0x0f, "810", 4, 8, 4, 64,
FE_ERL}
FE_RAM|FE_IO256|FE_LEDC}
};
-#define sym_num_devs \
- (sizeof(sym_dev_table) / sizeof(sym_dev_table[0]))
+#define sym_num_devs (ARRAY_SIZE(sym_dev_table))
/*
* Look up the chip table.
/*
* Insert a job into the start queue.
*/
-static void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp)
+void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp)
{
u_short qidx;
* I just don't want. :)
*/
if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 &&
- np->revision_id < 1)
+ np->s.device->revision < 1)
OUTB(np, nc_stest1, INB(np, nc_stest1) | 0x30);
/*
dstat |= INB(np, nc_dstat);
istatc = INB(np, nc_istat);
istat |= istatc;
+
+ /* Prevent deadlock waiting on a condition that may
+ * never clear. */
+ if (unlikely(sist == 0xffff && dstat == 0xff)) {
+ if (pci_channel_offline(np->s.device))
+ return;
+ }
} while (istatc & (SIP|DIP));
if (DEBUG_FLAGS & DEBUG_TINY)
switch (np->msgin [2]) {
case M_X_MODIFY_DP:
if (DEBUG_FLAGS & DEBUG_POINTER)
- sym_print_msg(cp,"modify DP",np->msgin);
+ sym_print_msg(cp, NULL, np->msgin);
tmp = (np->msgin[3]<<24) + (np->msgin[4]<<16) +
(np->msgin[5]<<8) + (np->msgin[6]);
sym_modify_dp(np, tp, cp, tmp);
*/
case M_IGN_RESIDUE:
if (DEBUG_FLAGS & DEBUG_POINTER)
- sym_print_msg(cp,"ign wide residue", np->msgin);
+ sym_print_msg(cp, NULL, np->msgin);
if (cp->host_flags & HF_SENSE)
OUTL_DSP(np, SCRIPTA_BA(np, clrack));
else
* Debugging purpose.
*/
#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
- assert(lp->busy_itl == 0);
+ if (lp->busy_itl != 0)
+ goto out_free;
#endif
/*
* Allocate resources for tags if not yet.
* Debugging purpose.
*/
#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
- assert(lp->busy_itl == 0 && lp->busy_itlq == 0);
+ if (lp->busy_itl != 0 || lp->busy_itlq != 0)
+ goto out_free;
#endif
/*
* Count this nexus for this LUN.
/*
* Allocate the array of lists of CCBs hashed by DSA.
*/
- np->ccbh = kcalloc(sizeof(struct sym_ccb **), CCB_HASH_SIZE, GFP_KERNEL);
+ np->ccbh = kcalloc(CCB_HASH_SIZE, sizeof(struct sym_ccb **), GFP_KERNEL);
if (!np->ccbh)
goto attach_failed;