[SCSI] Disable sym2 driver queueing
[safe/jmp/linux-2.6] / drivers / scsi / sym53c8xx_2 / sym_hipd.c
index bec6448..a6cbb90 100644 (file)
@@ -70,32 +70,12 @@ static void sym_printl_hex(u_char *p, int n)
        printf (".\n");
 }
 
-/*
- *  Print out the content of a SCSI message.
- */
-static int sym_show_msg (u_char * msg)
-{
-       u_char i;
-       printf ("%x",*msg);
-       if (*msg==M_EXTENDED) {
-               for (i=1;i<8;i++) {
-                       if (i-1>msg[1]) break;
-                       printf ("-%x",msg[i]);
-               }
-               return (i+1);
-       } else if ((*msg & 0xf0) == 0x20) {
-               printf ("-%x",msg[1]);
-               return (2);
-       }
-       return (1);
-}
-
 static void sym_print_msg(struct sym_ccb *cp, char *label, u_char *msg)
 {
        sym_print_addr(cp->cmd, "%s: ", label);
 
-       sym_show_msg(msg);
-       printf(".\n");
+       spi_print_msg(msg);
+       printf("\n");
 }
 
 static void sym_print_nego_msg(struct sym_hcb *np, int target, char *label, u_char *msg)
@@ -103,8 +83,8 @@ static void sym_print_nego_msg(struct sym_hcb *np, int target, char *label, u_ch
        struct sym_tcb *tp = &np->target[target];
        dev_info(&tp->starget->dev, "%s: ", label);
 
-       sym_show_msg(msg);
-       printf(".\n");
+       spi_print_msg(msg);
+       printf("\n");
 }
 
 /*
@@ -492,7 +472,7 @@ static int sym_getpciclock (struct sym_hcb *np)
  *  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 
@@ -635,29 +615,6 @@ static __inline void sym_init_burst(struct sym_hcb *np, u_char bc)
        }
 }
 
-
-/*
- * Print out the list of targets that have some flag disabled by user.
- */
-static void sym_print_targets_flag(struct sym_hcb *np, int mask, char *msg)
-{
-       int cnt;
-       int i;
-
-       for (cnt = 0, i = 0 ; i < SYM_CONF_MAX_TARGET ; i++) {
-               if (i == np->myaddr)
-                       continue;
-               if (np->target[i].usrflags & mask) {
-                       if (!cnt++)
-                               printf("%s: %s disabled for targets",
-                                       sym_name(np), msg);
-                       printf(" %d", i);
-               }
-       }
-       if (cnt)
-               printf(".\n");
-}
-
 /*
  *  Save initial settings of some IO registers.
  *  Assumed to have been set by BIOS.
@@ -961,8 +918,10 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru
 
                tp->usrflags |= (SYM_DISC_ENABLED | SYM_TAGS_ENABLED);
                tp->usrtags = SYM_SETUP_MAX_TAG;
+               tp->usr_width = np->maxwide;
+               tp->usr_period = 9;
 
-               sym_nvram_setup_target(np, i, nvram);
+               sym_nvram_setup_target(tp, i, nvram);
 
                if (!tp->usrtags)
                        tp->usrflags &= ~SYM_TAGS_ENABLED;
@@ -1005,13 +964,6 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru
                        sym_name(np), np->rv_scntl3, np->rv_dmode, np->rv_dcntl,
                        np->rv_ctest3, np->rv_ctest4, np->rv_ctest5);
        }
-       /*
-        *  Let user be aware of targets that have some disable flags set.
-        */
-       sym_print_targets_flag(np, SYM_SCAN_BOOT_DISABLED, "SCAN AT BOOT");
-       if (sym_verbose)
-               sym_print_targets_flag(np, SYM_SCAN_LUNS_DISABLED,
-                                      "SCAN FOR LUNS");
 
        return 0;
 }
@@ -1021,8 +973,8 @@ static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, stru
  *
  *  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;
        /*
@@ -1040,20 +992,25 @@ static int sym_regtest (struct sym_hcb *np)
 #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 
@@ -1142,7 +1099,7 @@ restart_test:
                err |= 4;
        }
 
-       return (err);
+       return err;
 }
 
 /*
@@ -1405,7 +1362,6 @@ static void sym_check_goals(struct sym_hcb *np, struct scsi_target *starget,
                goal->iu = 0;
                goal->dt = 0;
                goal->qas = 0;
-               goal->period = 0;
                goal->offset = 0;
                return;
        }
@@ -1465,7 +1421,8 @@ static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgp
         * Many devices implement PPR in a buggy way, so only use it if we
         * really want to.
         */
-       if (goal->iu || goal->dt || goal->qas || (goal->period < 0xa)) {
+       if (goal->offset &&
+           (goal->iu || goal->dt || goal->qas || (goal->period < 0xa))) {
                nego = NS_PPR;
        } else if (spi_width(starget) != goal->width) {
                nego = NS_WIDE;
@@ -1479,29 +1436,18 @@ static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgp
 
        switch (nego) {
        case NS_SYNC:
-               msgptr[msglen++] = M_EXTENDED;
-               msgptr[msglen++] = 3;
-               msgptr[msglen++] = M_X_SYNC_REQ;
-               msgptr[msglen++] = goal->period;
-               msgptr[msglen++] = goal->offset;
+               msglen += spi_populate_sync_msg(msgptr + msglen, goal->period,
+                               goal->offset);
                break;
        case NS_WIDE:
-               msgptr[msglen++] = M_EXTENDED;
-               msgptr[msglen++] = 2;
-               msgptr[msglen++] = M_X_WIDE_REQ;
-               msgptr[msglen++] = goal->width;
+               msglen += spi_populate_width_msg(msgptr + msglen, goal->width);
                break;
        case NS_PPR:
-               msgptr[msglen++] = M_EXTENDED;
-               msgptr[msglen++] = 6;
-               msgptr[msglen++] = M_X_PPR_REQ;
-               msgptr[msglen++] = goal->period;
-               msgptr[msglen++] = 0;
-               msgptr[msglen++] = goal->offset;
-               msgptr[msglen++] = goal->width;
-               msgptr[msglen++] = (goal->iu ? PPR_OPT_IU : 0) |
+               msglen += spi_populate_ppr_msg(msgptr + msglen, goal->period,
+                               goal->offset, goal->width,
+                               (goal->iu ? PPR_OPT_IU : 0) |
                                        (goal->dt ? PPR_OPT_DT : 0) |
-                                       (goal->qas ? PPR_OPT_QAS : 0);
+                                       (goal->qas ? PPR_OPT_QAS : 0));
                break;
        }
 
@@ -1523,7 +1469,7 @@ static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgp
 /*
  *  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;
 
@@ -3637,7 +3583,7 @@ static int sym_evaluate_dp(struct sym_hcb *np, struct sym_ccb *cp, u32 scr, int
 
        if (pm) {
                dp_scr  = scr_to_cpu(pm->ret);
-               dp_ofs -= scr_to_cpu(pm->sg.size);
+               dp_ofs -= scr_to_cpu(pm->sg.size) & 0x00ffffff;
        }
 
        /*
@@ -3654,7 +3600,7 @@ static int sym_evaluate_dp(struct sym_hcb *np, struct sym_ccb *cp, u32 scr, int
         *  If result is dp_sg = SYM_CONF_MAX_SG, then we are at the 
         *  end of the data.
         */
-       tmp = scr_to_cpu(sym_goalp(cp));
+       tmp = scr_to_cpu(cp->goalp);
        dp_sg = SYM_CONF_MAX_SG;
        if (dp_scr != tmp)
                dp_sg -= (tmp - 8 - (int)dp_scr) / (2*4);
@@ -3761,7 +3707,7 @@ static void sym_modify_dp(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb
         *  And our alchemy:) allows to easily calculate the data 
         *  script address we want to return for the next data phase.
         */
-       dp_ret = cpu_to_scr(sym_goalp(cp));
+       dp_ret = cpu_to_scr(cp->goalp);
        dp_ret = dp_ret - 8 - (SYM_CONF_MAX_SG - dp_sg) * (2*4);
 
        /*
@@ -3857,7 +3803,7 @@ int sym_compute_residual(struct sym_hcb *np, struct sym_ccb *cp)
         *  If all data has been transferred,
         *  there is no residual.
         */
-       if (cp->phys.head.lastp == sym_goalp(cp))
+       if (cp->phys.head.lastp == cp->goalp)
                return resid;
 
        /*
@@ -3997,11 +3943,7 @@ sym_sync_nego_check(struct sym_hcb *np, int req, struct sym_ccb *cp)
        /*
         *  It was a request. Prepare an answer message.
         */
-       np->msgout[0] = M_EXTENDED;
-       np->msgout[1] = 3;
-       np->msgout[2] = M_X_SYNC_REQ;
-       np->msgout[3] = per;
-       np->msgout[4] = ofs;
+       spi_populate_sync_msg(np->msgout, per, ofs);
 
        if (DEBUG_FLAGS & DEBUG_NEGO) {
                sym_print_nego_msg(np, target, "sync msgout", np->msgout);
@@ -4127,14 +4069,7 @@ sym_ppr_nego_check(struct sym_hcb *np, int req, int target)
        /*
         *  It was a request. Prepare an answer message.
         */
-       np->msgout[0] = M_EXTENDED;
-       np->msgout[1] = 6;
-       np->msgout[2] = M_X_PPR_REQ;
-       np->msgout[3] = per;
-       np->msgout[4] = 0;
-       np->msgout[5] = ofs;
-       np->msgout[6] = wide;
-       np->msgout[7] = opts;
+       spi_populate_ppr_msg(np->msgout, per, ofs, wide, opts);
 
        if (DEBUG_FLAGS & DEBUG_NEGO) {
                sym_print_nego_msg(np, target, "ppr msgout", np->msgout);
@@ -4246,10 +4181,7 @@ sym_wide_nego_check(struct sym_hcb *np, int req, struct sym_ccb *cp)
        /*
         *  It was a request. Prepare an answer message.
         */
-       np->msgout[0] = M_EXTENDED;
-       np->msgout[1] = 2;
-       np->msgout[2] = M_X_WIDE_REQ;
-       np->msgout[3] = wide;
+       spi_populate_width_msg(np->msgout, wide);
 
        np->msgin [0] = M_NOOP;
 
@@ -4294,11 +4226,8 @@ static void sym_wide_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb
                 * a single SCSI command (Suggested by Justin Gibbs).
                 */
                if (tp->tgoal.offset) {
-                       np->msgout[0] = M_EXTENDED;
-                       np->msgout[1] = 3;
-                       np->msgout[2] = M_X_SYNC_REQ;
-                       np->msgout[3] = tp->tgoal.period;
-                       np->msgout[4] = tp->tgoal.offset;
+                       spi_populate_sync_msg(np->msgout, tp->tgoal.period,
+                                       tp->tgoal.offset);
 
                        if (DEBUG_FLAGS & DEBUG_NEGO) {
                                sym_print_nego_msg(np, cp->target,
@@ -4673,7 +4602,8 @@ struct sym_ccb *sym_get_ccb (struct sym_hcb *np, struct scsi_cmnd *cmd, u_char t
                         *  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.
@@ -4718,7 +4648,8 @@ struct sym_ccb *sym_get_ccb (struct sym_hcb *np, struct scsi_cmnd *cmd, u_char t
                         *  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.
@@ -5470,7 +5401,7 @@ void sym_complete_ok (struct sym_hcb *np, struct sym_ccb *cp)
         *  extended error did occur, there is no residual.
         */
        resid = 0;
-       if (cp->phys.head.lastp != sym_goalp(cp))
+       if (cp->phys.head.lastp != cp->goalp)
                resid = sym_compute_residual(np, cp);
 
        /*