Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] iscsi class: add bsg support to iscsi class

This patch adds bsg support to the iscsi class. There is only
1 request, the host vendor one, supported. It is expected that
this would be used for things like flash updates.

This patch is made over this one
http://marc.info/?l=linux-scsi&m=131149780020992&w=2

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>

authored by

Mike Christie and committed by
James Bottomley
90eeb01a 6ac73e8c

+230 -2
+1
drivers/scsi/Kconfig
··· 309 309 config SCSI_ISCSI_ATTRS 310 310 tristate "iSCSI Transport Attributes" 311 311 depends on SCSI && NET 312 + select BLK_DEV_BSGLIB 312 313 help 313 314 If you wish to export transport-specific information about 314 315 each attached iSCSI device to sysfs, say Y.
+113 -1
drivers/scsi/scsi_transport_iscsi.c
··· 23 23 #include <linux/module.h> 24 24 #include <linux/mutex.h> 25 25 #include <linux/slab.h> 26 + #include <linux/bsg-lib.h> 26 27 #include <net/tcp.h> 27 28 #include <scsi/scsi.h> 28 29 #include <scsi/scsi_host.h> ··· 32 31 #include <scsi/scsi_transport_iscsi.h> 33 32 #include <scsi/iscsi_if.h> 34 33 #include <scsi/scsi_cmnd.h> 34 + #include <scsi/scsi_bsg_iscsi.h> 35 35 36 36 #define ISCSI_TRANSPORT_VERSION "2.0-870" 37 37 ··· 449 447 } 450 448 EXPORT_SYMBOL_GPL(iscsi_destroy_iface); 451 449 450 + /* 451 + * BSG support 452 + */ 453 + /** 454 + * iscsi_bsg_host_dispatch - Dispatch command to LLD. 455 + * @job: bsg job to be processed 456 + */ 457 + static int iscsi_bsg_host_dispatch(struct bsg_job *job) 458 + { 459 + struct Scsi_Host *shost = iscsi_job_to_shost(job); 460 + struct iscsi_bsg_request *req = job->request; 461 + struct iscsi_bsg_reply *reply = job->reply; 462 + struct iscsi_internal *i = to_iscsi_internal(shost->transportt); 463 + int cmdlen = sizeof(uint32_t); /* start with length of msgcode */ 464 + int ret; 465 + 466 + /* check if we have the msgcode value at least */ 467 + if (job->request_len < sizeof(uint32_t)) { 468 + ret = -ENOMSG; 469 + goto fail_host_msg; 470 + } 471 + 472 + /* Validate the host command */ 473 + switch (req->msgcode) { 474 + case ISCSI_BSG_HST_VENDOR: 475 + cmdlen += sizeof(struct iscsi_bsg_host_vendor); 476 + if ((shost->hostt->vendor_id == 0L) || 477 + (req->rqst_data.h_vendor.vendor_id != 478 + shost->hostt->vendor_id)) { 479 + ret = -ESRCH; 480 + goto fail_host_msg; 481 + } 482 + break; 483 + default: 484 + ret = -EBADR; 485 + goto fail_host_msg; 486 + } 487 + 488 + /* check if we really have all the request data needed */ 489 + if (job->request_len < cmdlen) { 490 + ret = -ENOMSG; 491 + goto fail_host_msg; 492 + } 493 + 494 + ret = i->iscsi_transport->bsg_request(job); 495 + if (!ret) 496 + return 0; 497 + 498 + fail_host_msg: 499 + /* return the errno failure code as the only status */ 500 + BUG_ON(job->reply_len < sizeof(uint32_t)); 501 + reply->reply_payload_rcv_len = 0; 502 + reply->result = ret; 503 + job->reply_len = sizeof(uint32_t); 504 + bsg_job_done(job, ret, 0); 505 + return 0; 506 + } 507 + 508 + /** 509 + * iscsi_bsg_host_add - Create and add the bsg hooks to receive requests 510 + * @shost: shost for iscsi_host 511 + * @cls_host: iscsi_cls_host adding the structures to 512 + */ 513 + static int 514 + iscsi_bsg_host_add(struct Scsi_Host *shost, struct iscsi_cls_host *ihost) 515 + { 516 + struct device *dev = &shost->shost_gendev; 517 + struct iscsi_internal *i = to_iscsi_internal(shost->transportt); 518 + struct request_queue *q; 519 + char bsg_name[20]; 520 + int ret; 521 + 522 + if (!i->iscsi_transport->bsg_request) 523 + return -ENOTSUPP; 524 + 525 + snprintf(bsg_name, sizeof(bsg_name), "iscsi_host%d", shost->host_no); 526 + 527 + q = __scsi_alloc_queue(shost, bsg_request_fn); 528 + if (!q) 529 + return -ENOMEM; 530 + 531 + ret = bsg_setup_queue(dev, q, bsg_name, iscsi_bsg_host_dispatch, 0); 532 + if (ret) { 533 + shost_printk(KERN_ERR, shost, "bsg interface failed to " 534 + "initialize - no request queue\n"); 535 + blk_cleanup_queue(q); 536 + return ret; 537 + } 538 + 539 + ihost->bsg_q = q; 540 + return 0; 541 + } 542 + 452 543 static int iscsi_setup_host(struct transport_container *tc, struct device *dev, 453 544 struct device *cdev) 454 545 { ··· 551 456 memset(ihost, 0, sizeof(*ihost)); 552 457 atomic_set(&ihost->nr_scans, 0); 553 458 mutex_init(&ihost->mutex); 459 + 460 + iscsi_bsg_host_add(shost, ihost); 461 + /* ignore any bsg add error - we just can't do sgio */ 462 + 463 + return 0; 464 + } 465 + 466 + static int iscsi_remove_host(struct transport_container *tc, 467 + struct device *dev, struct device *cdev) 468 + { 469 + struct Scsi_Host *shost = dev_to_shost(dev); 470 + struct iscsi_cls_host *ihost = shost->shost_data; 471 + 472 + if (ihost->bsg_q) { 473 + bsg_remove_queue(ihost->bsg_q); 474 + blk_cleanup_queue(ihost->bsg_q); 475 + } 554 476 return 0; 555 477 } 556 478 557 479 static DECLARE_TRANSPORT_CLASS(iscsi_host_class, 558 480 "iscsi_host", 559 481 iscsi_setup_host, 560 - NULL, 482 + iscsi_remove_host, 561 483 NULL); 562 484 563 485 static DECLARE_TRANSPORT_CLASS(iscsi_session_class,
+110
include/scsi/scsi_bsg_iscsi.h
··· 1 + /* 2 + * iSCSI Transport BSG Interface 3 + * 4 + * Copyright (C) 2009 James Smart, Emulex Corporation 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + * 20 + */ 21 + 22 + #ifndef SCSI_BSG_ISCSI_H 23 + #define SCSI_BSG_ISCSI_H 24 + 25 + /* 26 + * This file intended to be included by both kernel and user space 27 + */ 28 + 29 + #include <scsi/scsi.h> 30 + 31 + /* 32 + * iSCSI Transport SGIO v4 BSG Message Support 33 + */ 34 + 35 + /* Default BSG request timeout (in seconds) */ 36 + #define ISCSI_DEFAULT_BSG_TIMEOUT (10 * HZ) 37 + 38 + 39 + /* 40 + * Request Message Codes supported by the iSCSI Transport 41 + */ 42 + 43 + /* define the class masks for the message codes */ 44 + #define ISCSI_BSG_CLS_MASK 0xF0000000 /* find object class */ 45 + #define ISCSI_BSG_HST_MASK 0x80000000 /* iscsi host class */ 46 + 47 + /* iscsi host Message Codes */ 48 + #define ISCSI_BSG_HST_VENDOR (ISCSI_BSG_HST_MASK | 0x000000FF) 49 + 50 + 51 + /* 52 + * iSCSI Host Messages 53 + */ 54 + 55 + /* ISCSI_BSG_HST_VENDOR : */ 56 + 57 + /* Request: 58 + * Note: When specifying vendor_id, be sure to read the Vendor Type and ID 59 + * formatting requirements specified in scsi_netlink.h 60 + */ 61 + struct iscsi_bsg_host_vendor { 62 + /* 63 + * Identifies the vendor that the message is formatted for. This 64 + * should be the recipient of the message. 65 + */ 66 + uint64_t vendor_id; 67 + 68 + /* start of vendor command area */ 69 + uint32_t vendor_cmd[0]; 70 + }; 71 + 72 + /* Response: 73 + */ 74 + struct iscsi_bsg_host_vendor_reply { 75 + /* start of vendor response area */ 76 + uint32_t vendor_rsp[0]; 77 + }; 78 + 79 + 80 + /* request (CDB) structure of the sg_io_v4 */ 81 + struct iscsi_bsg_request { 82 + uint32_t msgcode; 83 + union { 84 + struct iscsi_bsg_host_vendor h_vendor; 85 + } rqst_data; 86 + } __attribute__((packed)); 87 + 88 + 89 + /* response (request sense data) structure of the sg_io_v4 */ 90 + struct iscsi_bsg_reply { 91 + /* 92 + * The completion result. Result exists in two forms: 93 + * if negative, it is an -Exxx system errno value. There will 94 + * be no further reply information supplied. 95 + * else, it's the 4-byte scsi error result, with driver, host, 96 + * msg and status fields. The per-msgcode reply structure 97 + * will contain valid data. 98 + */ 99 + uint32_t result; 100 + 101 + /* If there was reply_payload, how much was recevied ? */ 102 + uint32_t reply_payload_rcv_len; 103 + 104 + union { 105 + struct iscsi_bsg_host_vendor_reply vendor_reply; 106 + } reply_data; 107 + }; 108 + 109 + 110 + #endif /* SCSI_BSG_ISCSI_H */
+6 -1
include/scsi/scsi_transport_iscsi.h
··· 38 38 struct iscsi_task; 39 39 struct sockaddr; 40 40 struct iscsi_iface; 41 + struct bsg_job; 41 42 42 43 /** 43 44 * struct iscsi_transport - iSCSI Transport template ··· 142 141 enum iscsi_param_type param_type, 143 142 int param, char *buf); 144 143 mode_t (*attr_is_visible)(int param_type, int param); 144 + int (*bsg_request)(struct bsg_job *job); 145 145 }; 146 - 147 146 148 147 /* 149 148 * transport registration upcalls ··· 228 227 struct iscsi_cls_host { 229 228 atomic_t nr_scans; 230 229 struct mutex mutex; 230 + struct request_queue *bsg_q; 231 231 }; 232 + 233 + #define iscsi_job_to_shost(_job) \ 234 + dev_to_shost(_job->dev) 232 235 233 236 extern void iscsi_host_for_each_session(struct Scsi_Host *shost, 234 237 void (*fn)(struct iscsi_cls_session *));