diff options
Diffstat (limited to 'drivers/scsi/sym53c8xx_2/sym_hipd.c')
-rw-r--r-- | drivers/scsi/sym53c8xx_2/sym_hipd.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c index 98df1651404f..fe6359d4e1ef 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c | |||
@@ -1433,13 +1433,12 @@ static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgp | |||
1433 | * Many devices implement PPR in a buggy way, so only use it if we | 1433 | * Many devices implement PPR in a buggy way, so only use it if we |
1434 | * really want to. | 1434 | * really want to. |
1435 | */ | 1435 | */ |
1436 | if (goal->offset && | 1436 | if (goal->renego == NS_PPR || (goal->offset && |
1437 | (goal->iu || goal->dt || goal->qas || (goal->period < 0xa))) { | 1437 | (goal->iu || goal->dt || goal->qas || (goal->period < 0xa)))) { |
1438 | nego = NS_PPR; | 1438 | nego = NS_PPR; |
1439 | } else if (spi_width(starget) != goal->width) { | 1439 | } else if (goal->renego == NS_WIDE || goal->width) { |
1440 | nego = NS_WIDE; | 1440 | nego = NS_WIDE; |
1441 | } else if (spi_period(starget) != goal->period || | 1441 | } else if (goal->renego == NS_SYNC || goal->offset) { |
1442 | spi_offset(starget) != goal->offset) { | ||
1443 | nego = NS_SYNC; | 1442 | nego = NS_SYNC; |
1444 | } else { | 1443 | } else { |
1445 | goal->check_nego = 0; | 1444 | goal->check_nego = 0; |
@@ -2049,11 +2048,13 @@ static void sym_setwide(struct sym_hcb *np, int target, u_char wide) | |||
2049 | struct sym_tcb *tp = &np->target[target]; | 2048 | struct sym_tcb *tp = &np->target[target]; |
2050 | struct scsi_target *starget = tp->starget; | 2049 | struct scsi_target *starget = tp->starget; |
2051 | 2050 | ||
2052 | if (spi_width(starget) == wide) | ||
2053 | return; | ||
2054 | |||
2055 | sym_settrans(np, target, 0, 0, 0, wide, 0, 0); | 2051 | sym_settrans(np, target, 0, 0, 0, wide, 0, 0); |
2056 | 2052 | ||
2053 | if (wide) | ||
2054 | tp->tgoal.renego = NS_WIDE; | ||
2055 | else | ||
2056 | tp->tgoal.renego = 0; | ||
2057 | tp->tgoal.check_nego = 0; | ||
2057 | tp->tgoal.width = wide; | 2058 | tp->tgoal.width = wide; |
2058 | spi_offset(starget) = 0; | 2059 | spi_offset(starget) = 0; |
2059 | spi_period(starget) = 0; | 2060 | spi_period(starget) = 0; |
@@ -2080,6 +2081,12 @@ sym_setsync(struct sym_hcb *np, int target, | |||
2080 | 2081 | ||
2081 | sym_settrans(np, target, 0, ofs, per, wide, div, fak); | 2082 | sym_settrans(np, target, 0, ofs, per, wide, div, fak); |
2082 | 2083 | ||
2084 | if (wide) | ||
2085 | tp->tgoal.renego = NS_WIDE; | ||
2086 | else if (ofs) | ||
2087 | tp->tgoal.renego = NS_SYNC; | ||
2088 | else | ||
2089 | tp->tgoal.renego = 0; | ||
2083 | spi_period(starget) = per; | 2090 | spi_period(starget) = per; |
2084 | spi_offset(starget) = ofs; | 2091 | spi_offset(starget) = ofs; |
2085 | spi_iu(starget) = spi_dt(starget) = spi_qas(starget) = 0; | 2092 | spi_iu(starget) = spi_dt(starget) = spi_qas(starget) = 0; |
@@ -2106,6 +2113,10 @@ sym_setpprot(struct sym_hcb *np, int target, u_char opts, u_char ofs, | |||
2106 | 2113 | ||
2107 | sym_settrans(np, target, opts, ofs, per, wide, div, fak); | 2114 | sym_settrans(np, target, opts, ofs, per, wide, div, fak); |
2108 | 2115 | ||
2116 | if (wide || ofs) | ||
2117 | tp->tgoal.renego = NS_PPR; | ||
2118 | else | ||
2119 | tp->tgoal.renego = 0; | ||
2109 | spi_width(starget) = tp->tgoal.width = wide; | 2120 | spi_width(starget) = tp->tgoal.width = wide; |
2110 | spi_period(starget) = tp->tgoal.period = per; | 2121 | spi_period(starget) = tp->tgoal.period = per; |
2111 | spi_offset(starget) = tp->tgoal.offset = ofs; | 2122 | spi_offset(starget) = tp->tgoal.offset = ofs; |
@@ -3516,6 +3527,7 @@ static void sym_sir_task_recovery(struct sym_hcb *np, int num) | |||
3516 | spi_dt(starget) = 0; | 3527 | spi_dt(starget) = 0; |
3517 | spi_qas(starget) = 0; | 3528 | spi_qas(starget) = 0; |
3518 | tp->tgoal.check_nego = 1; | 3529 | tp->tgoal.check_nego = 1; |
3530 | tp->tgoal.renego = 0; | ||
3519 | } | 3531 | } |
3520 | 3532 | ||
3521 | /* | 3533 | /* |
@@ -5135,9 +5147,14 @@ int sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb * | |||
5135 | /* | 5147 | /* |
5136 | * Build a negotiation message if needed. | 5148 | * Build a negotiation message if needed. |
5137 | * (nego_status is filled by sym_prepare_nego()) | 5149 | * (nego_status is filled by sym_prepare_nego()) |
5150 | * | ||
5151 | * Always negotiate on INQUIRY and REQUEST SENSE. | ||
5152 | * | ||
5138 | */ | 5153 | */ |
5139 | cp->nego_status = 0; | 5154 | cp->nego_status = 0; |
5140 | if (tp->tgoal.check_nego && !tp->nego_cp && lp) { | 5155 | if ((tp->tgoal.check_nego || |
5156 | cmd->cmnd[0] == INQUIRY || cmd->cmnd[0] == REQUEST_SENSE) && | ||
5157 | !tp->nego_cp && lp) { | ||
5141 | msglen += sym_prepare_nego(np, cp, msgptr + msglen); | 5158 | msglen += sym_prepare_nego(np, cp, msgptr + msglen); |
5142 | } | 5159 | } |
5143 | 5160 | ||