History

s390/dasd: fix read unit address configuration loop

Read unit address is done for all devices during online processing to read out LCU features. This is also done after disconnect/connect a LCU. Some older storage hardware does not provide the capability to read unit address configuration. This leads to a loop trying to read unit address configuration every 30 seconds. The device is still operational but logs are flooded with error messages. Fix the loop by recognizing a command reject saying that the suborder for ruac is not supported.

Stefan Haberland committed 14 years ago

Commit 03429f31 parent 12d7b101 file · +26 −1Browse files

Unified · Split

drivers/s390/block/dasd_alias.c+26−1
@@ -384,6 +384,29 @@ static void _remove_device_from_lcu(struct alias_lcu *lcu, · 383 unmodified lines
384384 group->next = NULL;
385385 };
386386
387+static int
388+suborder_not_supported(struct dasd_ccw_req *cqr)
389+{
390+ char *sense;
391+ char reason;
392+ char msg_format;
393+ char msg_no;
394+
395+ sense = dasd_get_sense(&cqr->irb);
396+ if (!sense)
397+ return 0;
398+
399+ reason = sense[0];
400+ msg_format = (sense[7] & 0xF0);
401+ msg_no = (sense[7] & 0x0F);
402+
403+ /* command reject, Format 0 MSG 4 - invalid parameter */
404+ if ((reason == 0x80) && (msg_format == 0x00) && (msg_no == 0x04))
405+ return 1;
406+
407+ return 0;
408+}
409+
387410 static int read_unit_address_configuration(struct dasd_device *device,
388411 struct alias_lcu *lcu)
389412 {
@@ -435,6 +458,8 @@ static int read_unit_address_configuration(struct dasd_device *device, · 45 unmodified lines
435458
436459 do {
437460 rc = dasd_sleep_on(cqr);
461+ if (rc && suborder_not_supported(cqr))
462+ return -EOPNOTSUPP;
438463 } while (rc && (cqr->retries > 0));
439464 if (rc) {
440465 spin_lock_irqsave(&lcu->lock, flags);
@@ -521,7 +546,7 @@ static void lcu_update_work(struct work_struct *work) · 80 unmodified lines
521546 * processing the data
522547 */
523548 spin_lock_irqsave(&lcu->lock, flags);
524− if (rc || (lcu->flags & NEED_UAC_UPDATE)) {
549+ if ((rc && (rc != -EOPNOTSUPP)) || (lcu->flags & NEED_UAC_UPDATE)) {
525550 DBF_DEV_EVENT(DBF_WARNING, device, "could not update"
526551 " alias data in lcu (rc = %d), retry later", rc);
527552 schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ);