* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+
+#include <linux/slab.h>
+#include <asm/param.h> /* for timeouts in units of HZ */
+
#include "sym_glue.h"
#include "sym_nvram.h"
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);
+ if (label)
+ sym_print_addr(cp->cmd, "%s: ", label);
+ else
+ sym_print_addr(cp->cmd, "");
- 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)
{
struct sym_tcb *tp = &np->target[target];
- dev_info(&tp->sdev->sdev_target->dev, "%s: ", label);
+ dev_info(&tp->starget->dev, "%s: ", label);
- sym_show_msg(msg);
- printf(".\n");
+ spi_print_msg(msg);
+ printf("\n");
}
/*
static void sym_chip_reset (struct sym_hcb *np)
{
OUTB(np, nc_istat, SRST);
+ INB(np, nc_mbox1);
udelay(10);
OUTB(np, nc_istat, 0);
+ INB(np, nc_mbox1);
udelay(2000); /* For BUS MODE to settle */
}
OUTB(np, nc_stest3, TE);
OUTB(np, nc_dcntl, (np->rv_dcntl & IRQM));
OUTB(np, nc_scntl1, CRST);
+ INB(np, nc_mbox1);
udelay(200);
if (!SYM_SETUP_SCSI_BUS_CHECK)
if (!i)
printf("%s: the chip cannot lock the frequency\n",
sym_name(np));
- } else
- udelay((50+10));
+ } else {
+ INB(np, nc_mbox1);
+ udelay(50+10);
+ }
OUTB(np, nc_stest3, HSC); /* Halt the scsi clock */
OUTB(np, nc_scntl3, scntl3);
OUTB(np, nc_stest1, (DBLEN|DBLSEL));/* Select clock multiplier */
* 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
}
}
-
-/*
- * 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.
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.
* 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.
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;
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;
}
*
* 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;
}
/*
goal->iu = 0;
goal->dt = 0;
goal->qas = 0;
- goal->period = 0;
goal->offset = 0;
return;
}
static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgptr)
{
struct sym_tcb *tp = &np->target[cp->target];
- struct scsi_target *starget = tp->sdev->sdev_target;
+ struct scsi_target *starget = tp->starget;
struct sym_trans *goal = &tp->tgoal;
int msglen = 0;
int nego;
* 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;
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;
}
if (cam_status)
sym_set_cam_status(cmd, cam_status);
#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
- if (sym_get_cam_status(cmd) == CAM_REQUEUE_REQ) {
+ if (sym_get_cam_status(cmd) == DID_SOFT_ERROR) {
struct sym_tcb *tp = &np->target[cp->target];
struct sym_lcb *lp = sym_lp(tp, cp->lun);
if (lp) {
/*
* Wakeup all pending jobs.
*/
- sym_flush_busy_queue(np, CAM_SCSI_BUS_RESET);
+ sym_flush_busy_queue(np, DID_RESET);
/*
* Init chip.
*/
OUTB(np, nc_istat, 0x00); /* Remove Reset, abort */
+ INB(np, nc_mbox1);
udelay(2000); /* The 895 needs time for the bus mode to settle */
OUTB(np, nc_scntl0, np->rv_scntl0 | 0xc0);
if (np->features & (FE_ULTRA2|FE_ULTRA3)) {
OUTONW(np, nc_sien, SBMC);
if (reason == 0) {
+ INB(np, nc_mbox1);
mdelay(100);
INW(np, nc_sist);
}
static void sym_setwide(struct sym_hcb *np, int target, u_char wide)
{
struct sym_tcb *tp = &np->target[target];
- struct scsi_target *starget = tp->sdev->sdev_target;
+ struct scsi_target *starget = tp->starget;
if (spi_width(starget) == wide)
return;
u_char ofs, u_char per, u_char div, u_char fak)
{
struct sym_tcb *tp = &np->target[target];
- struct scsi_target *starget = tp->sdev->sdev_target;
+ struct scsi_target *starget = tp->starget;
u_char wide = (tp->head.wval & EWS) ? BUS_16_BIT : BUS_8_BIT;
sym_settrans(np, target, 0, ofs, per, wide, div, fak);
u_char per, u_char wide, u_char div, u_char fak)
{
struct sym_tcb *tp = &np->target[target];
- struct scsi_target *starget = tp->sdev->sdev_target;
+ struct scsi_target *starget = tp->starget;
sym_settrans(np, target, opts, ofs, per, wide, div, fak);
* Dequeue from the START queue all CCBs that match
* a given target/lun/task condition (-1 means all),
* and move them from the BUSY queue to the COMP queue
- * with CAM_REQUEUE_REQ status condition.
+ * with DID_SOFT_ERROR status condition.
* This function is used during error handling/recovery.
* It is called with SCRIPTS not running.
*/
if ((target == -1 || cp->target == target) &&
(lun == -1 || cp->lun == lun) &&
(task == -1 || cp->tag == task)) {
- sym_set_cam_status(cp->cmd, CAM_REQUEUE_REQ);
+ sym_set_cam_status(cp->cmd, DID_SOFT_ERROR);
sym_remque(&cp->link_ccbq);
sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
}
/*
* Message table indirect structure.
*/
- cp->phys.smsg.addr = cpu_to_scr(CCB_BA(cp, scsi_smsg2));
+ cp->phys.smsg.addr = CCB_BA(cp, scsi_smsg2);
cp->phys.smsg.size = cpu_to_scr(msglen);
/*
* sense command
*/
- cp->phys.cmd.addr = cpu_to_scr(CCB_BA(cp, sensecmd));
+ cp->phys.cmd.addr = CCB_BA(cp, sensecmd);
cp->phys.cmd.size = cpu_to_scr(6);
/*
* sense data
*/
memset(cp->sns_bbuf, 0, SYM_SNS_BBUF_LEN);
- cp->phys.sense.addr = cpu_to_scr(CCB_BA(cp, sns_bbuf));
+ cp->phys.sense.addr = CCB_BA(cp, sns_bbuf);
cp->phys.sense.size = cpu_to_scr(SYM_SNS_BBUF_LEN);
/*
sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
/* Preserve the software timeout condition */
- if (sym_get_cam_status(cmd) != CAM_CMD_TIMEOUT)
+ if (sym_get_cam_status(cmd) != DID_TIME_OUT)
sym_set_cam_status(cmd, cam_status);
++i;
#if 0
* Make sure at least our IO to abort has been dequeued.
*/
#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
- assert(i && sym_get_cam_status(cp->cmd) == CAM_REQUEUE_REQ);
+ assert(i && sym_get_cam_status(cp->cmd) == DID_SOFT_ERROR);
#else
sym_remque(&cp->link_ccbq);
sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
* Keep track in cam status of the reason of the abort.
*/
if (cp->to_abort == 2)
- sym_set_cam_status(cp->cmd, CAM_CMD_TIMEOUT);
+ sym_set_cam_status(cp->cmd, DID_TIME_OUT);
else
- sym_set_cam_status(cp->cmd, CAM_REQ_ABORTED);
+ sym_set_cam_status(cp->cmd, DID_ABORT);
/*
* Complete with error everything that we have dequeued.
* conditions not due to timeout.
*/
if (cp->to_abort == 2)
- sym_set_cam_status(cp->cmd, CAM_CMD_TIMEOUT);
+ sym_set_cam_status(cp->cmd, DID_TIME_OUT);
cp->to_abort = 0; /* We donnot expect to fail here */
break;
case SIR_ABORT_SENT:
target = INB(np, nc_sdid) & 0xf;
tp = &np->target[target];
- starget = tp->sdev->sdev_target;
+ starget = tp->starget;
/*
** If we didn't abort anything, leave here.
*/
i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
sym_dequeue_from_squeue(np, i, target, lun, -1);
- sym_clear_tasks(np, CAM_REQ_ABORTED, target, lun, task);
+ sym_clear_tasks(np, DID_ABORT, target, lun, task);
sym_flush_comp_queue(np, 0);
/*
* Print to the log the message we intend to send.
*/
if (num == SIR_TARGET_SELECTED) {
- dev_info(&tp->sdev->sdev_target->dev, "control msgout:");
+ dev_info(&tp->starget->dev, "control msgout:");
sym_printl_hex(np->abrt_msg, np->abrt_tbl.size);
np->abrt_tbl.size = cpu_to_scr(np->abrt_tbl.size);
}
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;
}
/*
* 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);
* 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);
/*
* 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;
/*
resid += (tmp & 0xffffff);
}
+ resid -= cp->odd_byte_adjustment;
+
/*
* Hopefully, the result is not too wrong.
*/
/*
* 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);
/*
* 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);
/*
* 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;
* 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,
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
goto out;
cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
-#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
- /*
- * If the LCB is not yet available and the LUN
- * has been probed ok, try to allocate the LCB.
- */
- if (!lp && sym_is_bit(tp->lun_map, ln)) {
- lp = sym_alloc_lcb(np, tn, ln);
- if (!lp)
- goto out_free;
- }
-#endif
-
- /*
- * If the LCB is not available here, then the
- * logical unit is not yet discovered. For those
- * ones only accept 1 SCSI IO per logical unit,
- * since we cannot allow disconnections.
- */
- if (!lp) {
- if (!sym_is_bit(tp->busy0_map, ln))
- sym_set_bit(tp->busy0_map, ln);
- else
- goto out_free;
- } else {
+ {
/*
* If we have been asked for a tagged command.
*/
* 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.
}
#endif
- /*
- * Remember all informations needed to free this CCB.
- */
cp->to_abort = 0;
+ cp->odd_byte_adjustment = 0;
cp->tag = tag;
cp->order = tag_order;
cp->target = tn;
lp->head.resel_sa =
cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
}
- /*
- * Otherwise, we only accept 1 IO per LUN.
- * Clear the bit that keeps track of this IO.
- */
- else
- sym_clr_bit(tp->busy0_map, cp->lun);
/*
* We donnot queue more than 1 ccb per target
struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln)
{
struct sym_tcb *tp = &np->target[tn];
- struct sym_lcb *lp = sym_lp(tp, ln);
-
- /*
- * Already done, just return.
- */
- if (lp)
- return lp;
-
- /*
- * Donnot allow LUN control block
- * allocation for not probed LUNs.
- */
- if (!sym_is_bit(tp->lun_map, ln))
- return NULL;
+ struct sym_lcb *lp = NULL;
/*
* Initialize the target control block if not yet.
lp->started_max = SYM_CONF_MAX_TASK;
lp->started_limit = SYM_CONF_MAX_TASK;
#endif
- /*
- * If we are busy, count the IO.
- */
- if (sym_is_bit(tp->busy0_map, ln)) {
- lp->busy_itl = 1;
- sym_clr_bit(tp->busy0_map, ln);
- }
+
fail:
return lp;
}
struct sym_lcb *lp = sym_lp(tp, ln);
int i;
- /*
- * If LCB not available, try to allocate it.
- */
- if (!lp && !(lp = sym_alloc_lcb(np, tn, ln)))
- goto fail;
-
/*
* Allocate the task table and and the tag allocation
* circular buffer. We want both or none.
lp->itlq_tbl = sym_calloc_dma(SYM_CONF_MAX_TASK*4, "ITLQ_TBL");
if (!lp->itlq_tbl)
goto fail;
- lp->cb_tags = kcalloc(SYM_CONF_MAX_TASK, 1, GFP_KERNEL);
+ lp->cb_tags = kcalloc(SYM_CONF_MAX_TASK, 1, GFP_ATOMIC);
if (!lp->cb_tags) {
sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4, "ITLQ_TBL");
lp->itlq_tbl = NULL;
/*
* message
*/
- cp->phys.smsg.addr = cpu_to_scr(CCB_BA(cp, scsi_smsg));
+ cp->phys.smsg.addr = CCB_BA(cp, scsi_smsg);
cp->phys.smsg.size = cpu_to_scr(msglen);
/*
}
/*
- * Complete execution of a SCSI command with extented
+ * Complete execution of a SCSI command with extended
* error, SCSI status error, or having been auto-sensed.
*
* The SCRIPTS processor is not running there, so we
/*
* Let's requeue it to device.
*/
- sym_set_cam_status(cmd, CAM_REQUEUE_REQ);
+ sym_set_cam_status(cmd, DID_SOFT_ERROR);
goto finish;
}
weirdness:
/*
* Donnot start more than 1 command after an error.
*/
- if (lp)
- sym_start_next_ccbs(np, lp, 1);
+ sym_start_next_ccbs(np, lp, 1);
#endif
}
tp = &np->target[cp->target];
lp = sym_lp(tp, cp->lun);
- /*
- * Assume device discovered on first success.
- */
- if (!lp)
- sym_set_bit(tp->lun_map, cp->lun);
-
/*
* If all data have been transferred, given than no
* 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);
/*
*/
sym_set_cam_result_ok(cp, cmd, resid);
-#ifdef SYM_OPT_SNIFF_INQUIRY
- /*
- * On standard INQUIRY response (EVPD and CmDt
- * not set), sniff out device capabilities.
- */
- if (cp->cdb_buf[0] == INQUIRY && !(cp->cdb_buf[1] & 0x3))
- sym_sniff_inquiry(np, cmd, resid);
-#endif
-
#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
/*
* If max number of started ccbs had been reduced,
/*
* Requeue a couple of awaiting scsi commands.
*/
- if (lp && !sym_que_empty(&lp->waiting_ccbq))
+ if (!sym_que_empty(&lp->waiting_ccbq))
sym_start_next_ccbs(np, lp, 2);
#endif
/*
SYM_QUEHEAD *qp;
struct sym_ccb *cp;
struct sym_tcb *tp;
- struct sym_lcb *lp;
- int target, lun;
+ int target;
if (np->scriptz0)
sym_mfree_dma(np->scriptz0, np->scriptz_sz, "SCRIPTZ0");
for (target = 0; target < SYM_CONF_MAX_TARGET ; target++) {
tp = &np->target[target];
- for (lun = 0 ; lun < SYM_CONF_MAX_LUN ; lun++) {
- lp = sym_lp(tp, lun);
- if (!lp)
- continue;
- if (lp->itlq_tbl)
- sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4,
- "ITLQ_TBL");
- kfree(lp->cb_tags);
- sym_mfree_dma(lp, sizeof(*lp), "LCB");
- }
#if SYM_CONF_MAX_LUN > 1
kfree(tp->lunmp);
#endif