From patchwork Wed Oct 21 16:22:58 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chandra Seetharaman X-Patchwork-Id: 55144 Received: from hormel.redhat.com (hormel1.redhat.com [209.132.177.33]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n9LGNFlF004305 for ; Wed, 21 Oct 2009 16:23:15 GMT Received: from listman.util.phx.redhat.com (listman.util.phx.redhat.com [10.8.4.110]) by hormel.redhat.com (Postfix) with ESMTP id 310D78E013D; Wed, 21 Oct 2009 12:23:15 -0400 (EDT) Received: from int-mx01.intmail.prod.int.phx2.redhat.com (nat-pool.util.phx.redhat.com [10.8.5.200]) by listman.util.phx.redhat.com (8.13.1/8.13.1) with ESMTP id n9LGNDTB020085 for ; Wed, 21 Oct 2009 12:23:13 -0400 Received: from mx1.redhat.com (ext-mx08.extmail.prod.ext.phx2.redhat.com [10.5.110.12]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id n9LGNDfq020471 for ; Wed, 21 Oct 2009 12:23:13 -0400 Received: from e5.ny.us.ibm.com (e5.ny.us.ibm.com [32.97.182.145]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n9LGN0wR031484 for ; Wed, 21 Oct 2009 12:23:00 -0400 Received: from d01relay05.pok.ibm.com (d01relay05.pok.ibm.com [9.56.227.237]) by e5.ny.us.ibm.com (8.14.3/8.13.1) with ESMTP id n9LGD8fk007813 for ; Wed, 21 Oct 2009 12:13:08 -0400 Received: from d01av01.pok.ibm.com (d01av01.pok.ibm.com [9.56.224.215]) by d01relay05.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id n9LGMxHD173318 for ; Wed, 21 Oct 2009 12:22:59 -0400 Received: from d01av01.pok.ibm.com (d03av01 [127.0.0.1]) by d01av01.pok.ibm.com (8.14.3/8.13.1/NCO v10.0 AVout) with ESMTP id n9LGMxO6032761 for ; Wed, 21 Oct 2009 12:22:59 -0400 Received: from [127.0.1.1] (chandra-ubuntu.beaverton.ibm.com [9.47.17.98]) by d01av01.pok.ibm.com (8.14.3/8.13.1/NCO v10.0 AVin) with ESMTP id n9LGMwQ8032680; Wed, 21 Oct 2009 12:22:58 -0400 From: Chandra Seetharaman To: linux-scsi@vger.kernel.org Date: Wed, 21 Oct 2009 09:22:58 -0700 Message-Id: <20091021162258.8473.32042.sendpatchset@chandra-ubuntu> In-Reply-To: <20091021162240.8473.99556.sendpatchset@chandra-ubuntu> References: <20091021162240.8473.99556.sendpatchset@chandra-ubuntu> X-RedHat-Spam-Score: -3.556 (AWL,RCVD_IN_DNSWL_MED) X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-Scanned-By: MIMEDefang 2.67 on 10.5.110.12 X-loop: dm-devel@redhat.com Cc: michaelc@cs.wisc.edu, dm-devel@redhat.com, Benoit_Arthur@emc.com, Eddie.Williams@steeleye.com Subject: [dm-devel] [PATCH 3/4] scsi_dh: Make hp hardware handler's activate() async X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.5 Precedence: junk Reply-To: device-mapper development List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com Index: linux-2.6.32-rc5/drivers/scsi/device_handler/scsi_dh_hp_sw.c =================================================================== --- linux-2.6.32-rc5.orig/drivers/scsi/device_handler/scsi_dh_hp_sw.c 2009-10-20 18:26:14.000000000 -0700 +++ linux-2.6.32-rc5/drivers/scsi/device_handler/scsi_dh_hp_sw.c 2009-10-20 18:26:44.000000000 -0700 @@ -39,8 +39,14 @@ unsigned char sense[SCSI_SENSE_BUFFERSIZE]; int path_state; int retries; + int retry_cnt; + struct scsi_device *sdev; + activate_complete callback_fn; + void *callback_data; }; +static int hp_sw_start_stop(struct hp_sw_dh_data *); + static inline struct hp_sw_dh_data *get_hp_sw_data(struct scsi_device *sdev) { struct scsi_dh_data *scsi_dh_data = sdev->scsi_dh_data; @@ -191,19 +197,53 @@ return rc; } +static void start_stop_endio(struct request *req, int error) +{ + struct hp_sw_dh_data *h = req->end_io_data; + unsigned err = SCSI_DH_OK; + + if (error || host_byte(req->errors) != DID_OK || + msg_byte(req->errors) != COMMAND_COMPLETE) { + sdev_printk(KERN_WARNING, h->sdev, + "%s: sending start_stop_unit failed with %x\n", + HP_SW_NAME, req->errors); + err = SCSI_DH_IO; + goto done; + } + + if (req->sense_len > 0) { + err = start_done(h->sdev, h->sense); + if (err == SCSI_DH_RETRY) { + err = SCSI_DH_IO; + if (--h->retry_cnt) { + blk_put_request(req); + err = hp_sw_start_stop(h); + if (err == SCSI_DH_OK) + return; + } + } + } +done: + blk_put_request(req); + if (h->callback_fn) { + h->callback_fn(h->callback_data, err); + h->callback_fn = h->callback_data = NULL; + } + return; + +} + /* * hp_sw_start_stop - Send START STOP UNIT command * @sdev: sdev command should be sent to * * Sending START STOP UNIT activates the SP. */ -static int hp_sw_start_stop(struct scsi_device *sdev, struct hp_sw_dh_data *h) +static int hp_sw_start_stop(struct hp_sw_dh_data *h) { struct request *req; - int ret, retry; -retry: - req = blk_get_request(sdev->request_queue, WRITE, GFP_NOIO); + req = blk_get_request(h->sdev->request_queue, WRITE, GFP_ATOMIC); if (!req) return SCSI_DH_RES_TEMP_UNAVAIL; @@ -217,32 +257,10 @@ req->sense = h->sense; memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE); req->sense_len = 0; - retry = h->retries; + req->end_io_data = h; - ret = blk_execute_rq(req->q, NULL, req, 1); - if (ret == -EIO) { - if (req->sense_len > 0) { - ret = start_done(sdev, h->sense); - } else { - sdev_printk(KERN_WARNING, sdev, - "%s: sending start_stop_unit failed with %x\n", - HP_SW_NAME, req->errors); - ret = SCSI_DH_IO; - } - } else - ret = SCSI_DH_OK; - - if (ret == SCSI_DH_RETRY) { - if (--retry) { - blk_put_request(req); - goto retry; - } - ret = SCSI_DH_IO; - } - - blk_put_request(req); - - return ret; + blk_execute_rq_nowait(req->q, NULL, req, 1, start_stop_endio); + return SCSI_DH_OK; } static int hp_sw_prep_fn(struct scsi_device *sdev, struct request *req) @@ -277,11 +295,13 @@ ret = hp_sw_tur(sdev, h); if (ret == SCSI_DH_OK && h->path_state == HP_SW_PATH_PASSIVE) { - ret = hp_sw_start_stop(sdev, h); + h->retry_cnt = h->retries; + h->callback_fn = fn; + h->callback_data = data; + ret = hp_sw_start_stop(h); if (ret == SCSI_DH_OK) - sdev_printk(KERN_INFO, sdev, - "%s: activated path\n", - HP_SW_NAME); + return 0; + h->callback_fn = h->callback_data = NULL; } if (fn) @@ -329,6 +349,7 @@ h = (struct hp_sw_dh_data *) scsi_dh_data->buf; h->path_state = HP_SW_PATH_UNINITIALIZED; h->retries = HP_SW_RETRIES; + h->sdev = sdev; ret = hp_sw_tur(sdev, h); if (ret != SCSI_DH_OK || h->path_state == HP_SW_PATH_UNINITIALIZED)