aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@steeleye.com>2005-05-08 17:00:15 -0400
committerJames Bottomley <jejb@titanic.(none)>2005-05-20 16:54:33 -0400
commitfad01ef88d2a27303757924c1fc013b31fe9a76b (patch)
tree8f1fe69d0610117452335a4b5224c856c8f2d256
parent62a8612972eaea804e1e42c63ee403cd4e14cc35 (diff)
[SCSI] correct aic7xxx period setting routines
This is similar to the previous sym2 problem. For Domain Validation to work we can't allow any period setting to turn wide on if it was previously off. Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c71
1 files changed, 37 insertions, 34 deletions
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index d978e4a3e973..0ed9ccc3091e 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -3346,6 +3346,32 @@ ahc_platform_dump_card_state(struct ahc_softc *ahc)
3346 3346
3347static void ahc_linux_exit(void); 3347static void ahc_linux_exit(void);
3348 3348
3349static void ahc_linux_get_width(struct scsi_target *starget)
3350{
3351 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
3352 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
3353 struct ahc_tmode_tstate *tstate;
3354 struct ahc_initiator_tinfo *tinfo
3355 = ahc_fetch_transinfo(ahc,
3356 starget->channel + 'A',
3357 shost->this_id, starget->id, &tstate);
3358 spi_width(starget) = tinfo->curr.width;
3359}
3360
3361static void ahc_linux_set_width(struct scsi_target *starget, int width)
3362{
3363 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
3364 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
3365 struct ahc_devinfo devinfo;
3366 unsigned long flags;
3367
3368 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
3369 starget->channel + 'A', ROLE_INITIATOR);
3370 ahc_lock(ahc, &flags);
3371 ahc_set_width(ahc, &devinfo, width, AHC_TRANS_GOAL, FALSE);
3372 ahc_unlock(ahc, &flags);
3373}
3374
3349static void ahc_linux_get_period(struct scsi_target *starget) 3375static void ahc_linux_get_period(struct scsi_target *starget)
3350{ 3376{
3351 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 3377 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
@@ -3378,6 +3404,14 @@ static void ahc_linux_set_period(struct scsi_target *starget, int period)
3378 3404
3379 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, 3405 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
3380 starget->channel + 'A', ROLE_INITIATOR); 3406 starget->channel + 'A', ROLE_INITIATOR);
3407
3408 /* all PPR requests apart from QAS require wide transfers */
3409 if (ppr_options & ~MSG_EXT_PPR_QAS_REQ) {
3410 ahc_linux_get_width(starget);
3411 if (spi_width(starget) == 0)
3412 ppr_options &= MSG_EXT_PPR_QAS_REQ;
3413 }
3414
3381 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT); 3415 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
3382 ahc_lock(ahc, &flags); 3416 ahc_lock(ahc, &flags);
3383 ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset, 3417 ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset,
@@ -3425,32 +3459,6 @@ static void ahc_linux_set_offset(struct scsi_target *starget, int offset)
3425 ahc_unlock(ahc, &flags); 3459 ahc_unlock(ahc, &flags);
3426} 3460}
3427 3461
3428static void ahc_linux_get_width(struct scsi_target *starget)
3429{
3430 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
3431 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
3432 struct ahc_tmode_tstate *tstate;
3433 struct ahc_initiator_tinfo *tinfo
3434 = ahc_fetch_transinfo(ahc,
3435 starget->channel + 'A',
3436 shost->this_id, starget->id, &tstate);
3437 spi_width(starget) = tinfo->curr.width;
3438}
3439
3440static void ahc_linux_set_width(struct scsi_target *starget, int width)
3441{
3442 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
3443 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
3444 struct ahc_devinfo devinfo;
3445 unsigned long flags;
3446
3447 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
3448 starget->channel + 'A', ROLE_INITIATOR);
3449 ahc_lock(ahc, &flags);
3450 ahc_set_width(ahc, &devinfo, width, AHC_TRANS_GOAL, FALSE);
3451 ahc_unlock(ahc, &flags);
3452}
3453
3454static void ahc_linux_get_dt(struct scsi_target *starget) 3462static void ahc_linux_get_dt(struct scsi_target *starget)
3455{ 3463{
3456 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 3464 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
@@ -3481,8 +3489,7 @@ static void ahc_linux_set_dt(struct scsi_target *starget, int dt)
3481 3489
3482 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, 3490 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
3483 starget->channel + 'A', ROLE_INITIATOR); 3491 starget->channel + 'A', ROLE_INITIATOR);
3484 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, 3492 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,AHC_SYNCRATE_DT);
3485 dt ? AHC_SYNCRATE_DT : AHC_SYNCRATE_ULTRA2);
3486 ahc_lock(ahc, &flags); 3493 ahc_lock(ahc, &flags);
3487 ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset, 3494 ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset,
3488 ppr_options, AHC_TRANS_GOAL, FALSE); 3495 ppr_options, AHC_TRANS_GOAL, FALSE);
@@ -3514,7 +3521,6 @@ static void ahc_linux_set_qas(struct scsi_target *starget, int qas)
3514 unsigned int ppr_options = tinfo->curr.ppr_options 3521 unsigned int ppr_options = tinfo->curr.ppr_options
3515 & ~MSG_EXT_PPR_QAS_REQ; 3522 & ~MSG_EXT_PPR_QAS_REQ;
3516 unsigned int period = tinfo->curr.period; 3523 unsigned int period = tinfo->curr.period;
3517 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
3518 unsigned long flags; 3524 unsigned long flags;
3519 struct ahc_syncrate *syncrate; 3525 struct ahc_syncrate *syncrate;
3520 3526
@@ -3523,8 +3529,7 @@ static void ahc_linux_set_qas(struct scsi_target *starget, int qas)
3523 3529
3524 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, 3530 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
3525 starget->channel + 'A', ROLE_INITIATOR); 3531 starget->channel + 'A', ROLE_INITIATOR);
3526 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, 3532 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
3527 dt ? AHC_SYNCRATE_DT : AHC_SYNCRATE_ULTRA2);
3528 ahc_lock(ahc, &flags); 3533 ahc_lock(ahc, &flags);
3529 ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset, 3534 ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset,
3530 ppr_options, AHC_TRANS_GOAL, FALSE); 3535 ppr_options, AHC_TRANS_GOAL, FALSE);
@@ -3556,7 +3561,6 @@ static void ahc_linux_set_iu(struct scsi_target *starget, int iu)
3556 unsigned int ppr_options = tinfo->curr.ppr_options 3561 unsigned int ppr_options = tinfo->curr.ppr_options
3557 & ~MSG_EXT_PPR_IU_REQ; 3562 & ~MSG_EXT_PPR_IU_REQ;
3558 unsigned int period = tinfo->curr.period; 3563 unsigned int period = tinfo->curr.period;
3559 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
3560 unsigned long flags; 3564 unsigned long flags;
3561 struct ahc_syncrate *syncrate; 3565 struct ahc_syncrate *syncrate;
3562 3566
@@ -3565,8 +3569,7 @@ static void ahc_linux_set_iu(struct scsi_target *starget, int iu)
3565 3569
3566 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, 3570 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
3567 starget->channel + 'A', ROLE_INITIATOR); 3571 starget->channel + 'A', ROLE_INITIATOR);
3568 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, 3572 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
3569 dt ? AHC_SYNCRATE_DT : AHC_SYNCRATE_ULTRA2);
3570 ahc_lock(ahc, &flags); 3573 ahc_lock(ahc, &flags);
3571 ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset, 3574 ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset,
3572 ppr_options, AHC_TRANS_GOAL, FALSE); 3575 ppr_options, AHC_TRANS_GOAL, FALSE);