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.
Unified · Split
| @@ -384,6 +384,29 @@ static void _remove_device_from_lcu(struct alias_lcu *lcu, · 383 unmodified lines | ||
| 384 | 384 | group->next = NULL; |
| 385 | 385 | }; |
| 386 | 386 | |
| 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 | + | |
| 387 | 410 | static int read_unit_address_configuration(struct dasd_device *device, |
| 388 | 411 | struct alias_lcu *lcu) |
| 389 | 412 | { |
| @@ -435,6 +458,8 @@ static int read_unit_address_configuration(struct dasd_device *device, · 45 unmodified lines | ||
| 435 | 458 | |
| 436 | 459 | do { |
| 437 | 460 | rc = dasd_sleep_on(cqr); |
| 461 | + if (rc && suborder_not_supported(cqr)) | |
| 462 | + return -EOPNOTSUPP; | |
| 438 | 463 | } while (rc && (cqr->retries > 0)); |
| 439 | 464 | if (rc) { |
| 440 | 465 | spin_lock_irqsave(&lcu->lock, flags); |
| @@ -521,7 +546,7 @@ static void lcu_update_work(struct work_struct *work) · 80 unmodified lines | ||
| 521 | 546 | * processing the data |
| 522 | 547 | */ |
| 523 | 548 | spin_lock_irqsave(&lcu->lock, flags); |
| 524 | − if (rc || (lcu->flags & NEED_UAC_UPDATE)) { | |
| 549 | + if ((rc && (rc != -EOPNOTSUPP)) || (lcu->flags & NEED_UAC_UPDATE)) { | |
| 525 | 550 | DBF_DEV_EVENT(DBF_WARNING, device, "could not update" |
| 526 | 551 | " alias data in lcu (rc = %d), retry later", rc); |
| 527 | 552 | schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ); |