diff options
Diffstat (limited to 'drivers/scsi/sym53c8xx_2/sym_glue.c')
-rw-r--r-- | drivers/scsi/sym53c8xx_2/sym_glue.c | 39 |
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 | |||
514 | */ | 514 | */ |
515 | int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp) | 515 | int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp) |
516 | { | 516 | { |
517 | int dir; | ||
518 | struct sym_tcb *tp = &np->target[cp->target]; | 517 | struct sym_tcb *tp = &np->target[cp->target]; |
519 | struct sym_lcb *lp = sym_lp(tp, cp->lun); | 518 | struct sym_lcb *lp = sym_lp(tp, cp->lun); |
519 | u32 lastp, goalp; | ||
520 | int dir; | ||
520 | 521 | ||
521 | /* | 522 | /* |
522 | * Build the CDB. | 523 | * Build the CDB. |
@@ -534,15 +535,47 @@ int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct s | |||
534 | sym_set_cam_status(cmd, DID_ERROR); | 535 | sym_set_cam_status(cmd, DID_ERROR); |
535 | goto out_abort; | 536 | goto out_abort; |
536 | } | 537 | } |
538 | |||
539 | /* | ||
540 | * No segments means no data. | ||
541 | */ | ||
542 | if (!cp->segments) | ||
543 | dir = DMA_NONE; | ||
537 | } else { | 544 | } else { |
538 | cp->data_len = 0; | 545 | cp->data_len = 0; |
539 | cp->segments = 0; | 546 | cp->segments = 0; |
540 | } | 547 | } |
541 | 548 | ||
542 | /* | 549 | /* |
543 | * Set data pointers. | 550 | * Set the data pointer. |
551 | */ | ||
552 | switch (dir) { | ||
553 | case DMA_BIDIRECTIONAL: | ||
554 | printk("%s: got DMA_BIDIRECTIONAL command", sym_name(np)); | ||
555 | sym_set_cam_status(cmd, DID_ERROR); | ||
556 | goto out_abort; | ||
557 | case DMA_TO_DEVICE: | ||
558 | goalp = SCRIPTA_BA(np, data_out2) + 8; | ||
559 | lastp = goalp - 8 - (cp->segments * (2*4)); | ||
560 | break; | ||
561 | case DMA_FROM_DEVICE: | ||
562 | cp->host_flags |= HF_DATA_IN; | ||
563 | goalp = SCRIPTA_BA(np, data_in2) + 8; | ||
564 | lastp = goalp - 8 - (cp->segments * (2*4)); | ||
565 | break; | ||
566 | case DMA_NONE: | ||
567 | default: | ||
568 | lastp = goalp = SCRIPTB_BA(np, no_data); | ||
569 | break; | ||
570 | } | ||
571 | |||
572 | /* | ||
573 | * Set all pointers values needed by SCRIPTS. | ||
544 | */ | 574 | */ |
545 | sym_setup_data_pointers(np, cp, dir); | 575 | cp->phys.head.lastp = cpu_to_scr(lastp); |
576 | cp->phys.head.savep = cpu_to_scr(lastp); | ||
577 | cp->startp = cp->phys.head.savep; | ||
578 | cp->goalp = cpu_to_scr(goalp); | ||
546 | 579 | ||
547 | /* | 580 | /* |
548 | * When `#ifed 1', the code below makes the driver | 581 | * When `#ifed 1', the code below makes the driver |