* Many devices implement PPR in a buggy way, so only use it if we
         * really want to.
         */
-       if (goal->offset &&
-           (goal->iu || goal->dt || goal->qas || (goal->period < 0xa))) {
+       if (goal->renego == NS_PPR || (goal->offset &&
+           (goal->iu || goal->dt || goal->qas || (goal->period < 0xa)))) {
                nego = NS_PPR;
-       } else if (spi_width(starget) != goal->width) {
+       } else if (goal->renego == NS_WIDE || goal->width) {
                nego = NS_WIDE;
-       } else if (spi_period(starget) != goal->period ||
-                  spi_offset(starget) != goal->offset) {
+       } else if (goal->renego == NS_SYNC || goal->offset) {
                nego = NS_SYNC;
        } else {
                goal->check_nego = 0;
        struct sym_tcb *tp = &np->target[target];
        struct scsi_target *starget = tp->starget;
 
-       if (spi_width(starget) == wide)
-               return;
-
        sym_settrans(np, target, 0, 0, 0, wide, 0, 0);
 
+       if (wide)
+               tp->tgoal.renego = NS_WIDE;
+       else
+               tp->tgoal.renego = 0;
+       tp->tgoal.check_nego = 0;
        tp->tgoal.width = wide;
        spi_offset(starget) = 0;
        spi_period(starget) = 0;
 
        sym_settrans(np, target, 0, ofs, per, wide, div, fak);
 
+       if (wide)
+               tp->tgoal.renego = NS_WIDE;
+       else if (ofs)
+               tp->tgoal.renego = NS_SYNC;
+       else
+               tp->tgoal.renego = 0;
        spi_period(starget) = per;
        spi_offset(starget) = ofs;
        spi_iu(starget) = spi_dt(starget) = spi_qas(starget) = 0;
 
        sym_settrans(np, target, opts, ofs, per, wide, div, fak);
 
+       if (wide || ofs)
+               tp->tgoal.renego = NS_PPR;
+       else
+               tp->tgoal.renego = 0;
        spi_width(starget) = tp->tgoal.width = wide;
        spi_period(starget) = tp->tgoal.period = per;
        spi_offset(starget) = tp->tgoal.offset = ofs;
                        spi_dt(starget) = 0;
                        spi_qas(starget) = 0;
                        tp->tgoal.check_nego = 1;
+                       tp->tgoal.renego = 0;
                }
 
                /*
        /*
         *  Build a negotiation message if needed.
         *  (nego_status is filled by sym_prepare_nego())
+        *
+        *  Always negotiate on INQUIRY and REQUEST SENSE.
+        *
         */
        cp->nego_status = 0;
-       if (tp->tgoal.check_nego && !tp->nego_cp && lp) {
+       if ((tp->tgoal.check_nego ||
+            cmd->cmnd[0] == INQUIRY || cmd->cmnd[0] == REQUEST_SENSE) &&
+           !tp->nego_cp && lp) {
                msglen += sym_prepare_nego(np, cp, msgptr + msglen);
        }