Merge tag 'platform-drivers-x86-v4.14-1' of git://git.infradead.org/linux-platform...
[linux-2.6-microblaze.git] / drivers / scsi / libsas / sas_host_smp.c
index 45cbbc4..9ead93d 100644 (file)
@@ -225,47 +225,36 @@ static void sas_phy_control(struct sas_ha_struct *sas_ha, u8 phy_id,
                resp_data[2] = SMP_RESP_FUNC_ACC;
 }
 
-int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
-                        struct request *rsp)
+void sas_smp_host_handler(struct bsg_job *job, struct Scsi_Host *shost)
 {
-       u8 *req_data = NULL, *resp_data = NULL, *buf;
        struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
+       u8 *req_data, *resp_data;
+       unsigned int reslen = 0;
        int error = -EINVAL;
 
        /* eight is the minimum size for request and response frames */
-       if (blk_rq_bytes(req) < 8 || blk_rq_bytes(rsp) < 8)
+       if (job->request_payload.payload_len < 8 ||
+           job->reply_payload.payload_len < 8)
                goto out;
 
-       if (bio_offset(req->bio) + blk_rq_bytes(req) > PAGE_SIZE ||
-           bio_offset(rsp->bio) + blk_rq_bytes(rsp) > PAGE_SIZE) {
-               shost_printk(KERN_ERR, shost,
-                       "SMP request/response frame crosses page boundary");
+       error = -ENOMEM;
+       req_data = kzalloc(job->request_payload.payload_len, GFP_KERNEL);
+       if (!req_data)
                goto out;
-       }
-
-       req_data = kzalloc(blk_rq_bytes(req), GFP_KERNEL);
+       sg_copy_to_buffer(job->request_payload.sg_list,
+                         job->request_payload.sg_cnt, req_data,
+                         job->request_payload.payload_len);
 
        /* make sure frame can always be built ... we copy
         * back only the requested length */
-       resp_data = kzalloc(max(blk_rq_bytes(rsp), 128U), GFP_KERNEL);
-
-       if (!req_data || !resp_data) {
-               error = -ENOMEM;
-               goto out;
-       }
-
-       local_irq_disable();
-       buf = kmap_atomic(bio_page(req->bio));
-       memcpy(req_data, buf, blk_rq_bytes(req));
-       kunmap_atomic(buf - bio_offset(req->bio));
-       local_irq_enable();
+       resp_data = kzalloc(max(job->reply_payload.payload_len, 128U),
+                       GFP_KERNEL);
+       if (!resp_data)
+               goto out_free_req;
 
+       error = -EINVAL;
        if (req_data[0] != SMP_REQUEST)
-               goto out;
-
-       /* always succeeds ... even if we can't process the request
-        * the result is in the response frame */
-       error = 0;
+               goto out_free_resp;
 
        /* set up default don't know response */
        resp_data[0] = SMP_RESPONSE;
@@ -274,20 +263,18 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
 
        switch (req_data[1]) {
        case SMP_REPORT_GENERAL:
-               scsi_req(req)->resid_len -= 8;
-               scsi_req(rsp)->resid_len -= 32;
                resp_data[2] = SMP_RESP_FUNC_ACC;
                resp_data[9] = sas_ha->num_phys;
+               reslen = 32;
                break;
 
        case SMP_REPORT_MANUF_INFO:
-               scsi_req(req)->resid_len -= 8;
-               scsi_req(rsp)->resid_len -= 64;
                resp_data[2] = SMP_RESP_FUNC_ACC;
                memcpy(resp_data + 12, shost->hostt->name,
                       SAS_EXPANDER_VENDOR_ID_LEN);
                memcpy(resp_data + 20, "libsas virt phy",
                       SAS_EXPANDER_PRODUCT_ID_LEN);
+               reslen = 64;
                break;
 
        case SMP_READ_GPIO_REG:
@@ -295,14 +282,10 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
                break;
 
        case SMP_DISCOVER:
-               scsi_req(req)->resid_len -= 16;
-               if ((int)scsi_req(req)->resid_len < 0) {
-                       scsi_req(req)->resid_len = 0;
-                       error = -EINVAL;
-                       goto out;
-               }
-               scsi_req(rsp)->resid_len -= 56;
+               if (job->request_payload.payload_len < 16)
+                       goto out_free_resp;
                sas_host_smp_discover(sas_ha, resp_data, req_data[9]);
+               reslen = 56;
                break;
 
        case SMP_REPORT_PHY_ERR_LOG:
@@ -311,14 +294,10 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
                break;
 
        case SMP_REPORT_PHY_SATA:
-               scsi_req(req)->resid_len -= 16;
-               if ((int)scsi_req(req)->resid_len < 0) {
-                       scsi_req(req)->resid_len = 0;
-                       error = -EINVAL;
-                       goto out;
-               }
-               scsi_req(rsp)->resid_len -= 60;
+               if (job->request_payload.payload_len < 16)
+                       goto out_free_resp;
                sas_report_phy_sata(sas_ha, resp_data, req_data[9]);
+               reslen = 60;
                break;
 
        case SMP_REPORT_ROUTE_INFO:
@@ -330,16 +309,15 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
                const int base_frame_size = 11;
                int to_write = req_data[4];
 
-               if (blk_rq_bytes(req) < base_frame_size + to_write * 4 ||
-                   scsi_req(req)->resid_len < base_frame_size + to_write * 4) {
+               if (job->request_payload.payload_len <
+                               base_frame_size + to_write * 4) {
                        resp_data[2] = SMP_RESP_INV_FRM_LEN;
                        break;
                }
 
                to_write = sas_host_smp_write_gpio(sas_ha, resp_data, req_data[2],
                                                   req_data[3], to_write, &req_data[8]);
-               scsi_req(req)->resid_len -= base_frame_size + to_write * 4;
-               scsi_req(rsp)->resid_len -= 8;
+               reslen = 8;
                break;
        }
 
@@ -348,16 +326,12 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
                break;
 
        case SMP_PHY_CONTROL:
-               scsi_req(req)->resid_len -= 44;
-               if ((int)scsi_req(req)->resid_len < 0) {
-                       scsi_req(req)->resid_len = 0;
-                       error = -EINVAL;
-                       goto out;
-               }
-               scsi_req(rsp)->resid_len -= 8;
+               if (job->request_payload.payload_len < 44)
+                       goto out_free_resp;
                sas_phy_control(sas_ha, req_data[9], req_data[10],
                                req_data[32] >> 4, req_data[33] >> 4,
                                resp_data);
+               reslen = 8;
                break;
 
        case SMP_PHY_TEST_FUNCTION:
@@ -369,15 +343,15 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
                break;
        }
 
-       local_irq_disable();
-       buf = kmap_atomic(bio_page(rsp->bio));
-       memcpy(buf, resp_data, blk_rq_bytes(rsp));
-       flush_kernel_dcache_page(bio_page(rsp->bio));
-       kunmap_atomic(buf - bio_offset(rsp->bio));
-       local_irq_enable();
+       sg_copy_from_buffer(job->reply_payload.sg_list,
+                           job->reply_payload.sg_cnt, resp_data,
+                           job->reply_payload.payload_len);
 
- out:
-       kfree(req_data);
+       error = 0;
+out_free_resp:
        kfree(resp_data);
-       return error;
+out_free_req:
+       kfree(req_data);
+out:
+       bsg_job_done(job, error, reslen);
 }