[SCSI] ibmvfc: Handle Virtual I/O Server reboot
authorBrian King <brking@linux.vnet.ibm.com>
Tue, 21 Sep 2010 15:17:11 +0000 (10:17 -0500)
committerJames Bottomley <James.Bottomley@suse.de>
Thu, 7 Oct 2010 22:17:06 +0000 (17:17 -0500)
If a Virtual I/O server is rebooted, the client fibre channel sees a
transport event on its CRQ, which causes it to attempt to reconnect
to the CRQ. For a period of time during the VIOS reboot, the client's
attempts to register the CRQ will return H_CLOSED, indicating the server
side is not currently registered. The ibmvfc driver was not handling
this well and was taking the virtual adapter offline. Fix this by
re-enabling our interrupt and waiting for the event on our CRQ
indicating the server is back, at which point we can reconnect.

Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
drivers/scsi/ibmvscsi/ibmvfc.c

index f033bf39690fcf4d230ca05e76359f03964e78ea..00d08b25425fdf2faea0a1e3bd063167943291fc 100644 (file)
@@ -4302,8 +4302,10 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost)
                spin_unlock_irqrestore(vhost->host->host_lock, flags);
                rc = ibmvfc_reset_crq(vhost);
                spin_lock_irqsave(vhost->host->host_lock, flags);
-               if (rc || (rc = ibmvfc_send_crq_init(vhost)) ||
-                   (rc = vio_enable_interrupts(to_vio_dev(vhost->dev)))) {
+               if (rc == H_CLOSED)
+                       vio_enable_interrupts(to_vio_dev(vhost->dev));
+               else if (rc || (rc = ibmvfc_send_crq_init(vhost)) ||
+                        (rc = vio_enable_interrupts(to_vio_dev(vhost->dev)))) {
                        ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
                        dev_err(vhost->dev, "Error after reset (rc=%d)\n", rc);
                }