summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sym53c8xx_2/sym_glue.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/sym53c8xx_2/sym_glue.c')
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index a2bfdf8417a2..d924997db48b 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -514,9 +514,10 @@ static inline int sym_setup_cdb(struct sym_hcb *np, struct scsi_cmnd *cmd, struc
*/
int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp)
{
- int dir;
struct sym_tcb *tp = &np->target[cp->target];
struct sym_lcb *lp = sym_lp(tp, cp->lun);
+ u32 lastp, goalp;
+ int dir;
/*
* Build the CDB.
@@ -534,15 +535,47 @@ int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct s
sym_set_cam_status(cmd, DID_ERROR);
goto out_abort;
}
+
+ /*
+ * No segments means no data.
+ */
+ if (!cp->segments)
+ dir = DMA_NONE;
} else {
cp->data_len = 0;
cp->segments = 0;
}
/*
- * Set data pointers.
+ * Set the data pointer.
+ */
+ switch (dir) {
+ case DMA_BIDIRECTIONAL:
+ printk("%s: got DMA_BIDIRECTIONAL command", sym_name(np));
+ sym_set_cam_status(cmd, DID_ERROR);
+ goto out_abort;
+ case DMA_TO_DEVICE:
+ goalp = SCRIPTA_BA(np, data_out2) + 8;
+ lastp = goalp - 8 - (cp->segments * (2*4));
+ break;
+ case DMA_FROM_DEVICE:
+ cp->host_flags |= HF_DATA_IN;
+ goalp = SCRIPTA_BA(np, data_in2) + 8;
+ lastp = goalp - 8 - (cp->segments * (2*4));
+ break;
+ case DMA_NONE:
+ default:
+ lastp = goalp = SCRIPTB_BA(np, no_data);
+ break;
+ }
+
+ /*
+ * Set all pointers values needed by SCRIPTS.
*/
- sym_setup_data_pointers(np, cp, dir);
+ cp->phys.head.lastp = cpu_to_scr(lastp);
+ cp->phys.head.savep = cpu_to_scr(lastp);
+ cp->startp = cp->phys.head.savep;
+ cp->goalp = cpu_to_scr(goalp);
/*
* When `#ifed 1', the code below makes the driver