]> git.openfabrics.org - ~shefty/rdma-dev.git/commitdiff
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 10 Oct 2012 10:52:19 +0000 (19:52 +0900)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 10 Oct 2012 10:52:19 +0000 (19:52 +0900)
Pull scsi target updates from Nicholas Bellinger:
 "Things have been calm for the most part with no new fabric drivers in
  flight for v3.7 (we're up to eight now !), so this update is primarily
  focused on addressing a few long-standing items within target-core and
  iscsi-target fabric code.

  The highlights include:

   - target: Simplify fabric sense data length handling (roland)
   - qla2xxx: Fix endianness of task management response code (roland)
   - target: fix truncation of mode data, support zero allocation length
     (paolo)
   - target: Properly support zero-length commands in normal processing
     path (paolo)
   - iscsi-target: Correctly set 0xffffffff field within ISCSI_OP_REJECT
     PDU (ronnie + nab)
   - iscsi-target: Add explicit set of cache_dynamic_acls=1 for TPG
     demo-mode (ronnie + nab)
   - target/file: Re-enable optional fd_buffered_io=1 operation (nab +
     hch)
   - iscsi-target: Add MaxXmitDataSegmenthLength forr target ->
     initiator MDRSL declaration (nab)
   - target: Add target_submit_cmd_map_sgls for SGL fabric memory
     passthrough (nab + hch)
   - tcm_loop: Convert I/O path to use target_submit_cmd_map_sgls (hch +
     nab)
   - tcm_vhost: Convert I/O path to use target_submit_cmd_map_sgls (nab
     + hch)

  The last series for adding a new target_submit_cmd_map_sgls() fabric
  caller (as requested by hch) that accepts pre-allocated SGL memory
  (using existing logic), along with converting tcm_loop + tcm_vhost has
  only been in -next for the last days, but has gotten enough review
  +testing and is clear enough a mechanical change that I think it's
  reasonable to merge for -rc1 code.

  Thanks again to everyone who contributed this round! Extra special
  thanks to Roland (PureStorage) for tracking down the qla2xxx target
  TMR response code endian issue, and to Paolo (Redhat) for resolving
  the long standing zero-length CDB issues within target-core between
  virtual and pSCSI backends."

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (44 commits)
  iscsi-target: Bump defaults for nopin_timeout + nopin_response_timeout values
  iscsit: proper endianess conversions
  iscsit: use the itt_t abstract type
  iscsit: add missing endianess conversion in iscsit_check_inaddr_any
  iscsit: remove incorrect unlock in iscsit_build_sendtargets_resp
  iscsit: mark various functions static
  target/iscsi: precedence bug in iscsit_set_dataout_sequence_values()
  target/usb-gadget: strlen() doesn't count the terminator
  target/usb-gadget: remove duplicate initialization
  tcm_vhost: Convert I/O path to use target_submit_cmd_map_sgls
  target: Add control CDB READ payload zero work-around
  tcm_loop: Convert I/O path to use target_submit_cmd_map_sgls
  target: Add target_submit_cmd_map_sgls for SGL fabric memory passthrough
  iscsi-target: Add explicit set of cache_dynamic_acls=1 for TPG demo-mode
  iscsi-target: Change iscsi_target_seq_pdu_list.c to honor MaxXmitDataSegmentLength
  iscsi-target: Add MaxXmitDataSegmentLength connection recovery check
  iscsi-target: Convert incoming PDU payload checks to MaxXmitDataSegmentLength
  iscsi-target: Enable MaxXmitDataSegmentLength operation in login path
  iscsi-target: Add base MaxXmitDataSegmentLength code
  target/file: Re-enable optional fd_buffered_io=1 operation
  ...

1  2 
drivers/scsi/qla2xxx/qla_target.c
drivers/target/iscsi/iscsi_target_parameters.c
drivers/usb/gadget/tcm_usb_gadget.c

index bddc97c5c8e92fdd1de11b24d9ac338653daca8e,41b74ba8d4e584699d57a0a8f8a84b38b9b78783..0e09d8f433d1683e61ba61074d7c67b71919d970
@@@ -969,7 -969,7 +969,7 @@@ void qlt_stop_phase1(struct qla_tgt *tg
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
        mutex_unlock(&ha->tgt.tgt_mutex);
  
 -      flush_delayed_work_sync(&tgt->sess_del_work);
 +      flush_delayed_work(&tgt->sess_del_work);
  
        ql_dbg(ql_dbg_tgt_mgt, vha, 0xf009,
            "Waiting for sess works (tgt %p)", tgt);
@@@ -1403,7 -1403,7 +1403,7 @@@ static void qlt_24xx_send_task_mgmt_cti
        ctio->u.status1.scsi_status =
            __constant_cpu_to_le16(SS_RESPONSE_INFO_LEN_VALID);
        ctio->u.status1.response_len = __constant_cpu_to_le16(8);
-       ((uint32_t *)ctio->u.status1.sense_data)[0] = cpu_to_be32(resp_code);
+       ctio->u.status1.sense_data[0] = resp_code;
  
        qla2x00_start_iocbs(ha, ha->req);
  }
index 240f7aa76ed1cfd962c6a16fd7eed27701023ee5,3678ff2139dee5c73fca69213d698554cd62c414..90b740048f26ee7151eda956b092e12fad74e70c
@@@ -334,6 -334,13 +334,13 @@@ int iscsi_create_default_params(struct 
        if (!param)
                goto out;
  
+       param = iscsi_set_default_param(pl, MAXXMITDATASEGMENTLENGTH,
+                       INITIAL_MAXXMITDATASEGMENTLENGTH,
+                       PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
+                       TYPERANGE_512_TO_16777215, USE_ALL);
+       if (!param)
+               goto out;
        param = iscsi_set_default_param(pl, MAXRECVDATASEGMENTLENGTH,
                        INITIAL_MAXRECVDATASEGMENTLENGTH,
                        PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
@@@ -467,6 -474,8 +474,8 @@@ int iscsi_set_keys_to_negotiate
                        SET_PSTATE_NEGOTIATE(param);
                } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
                        SET_PSTATE_NEGOTIATE(param);
+               } else if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) {
+                       continue;
                } else if (!strcmp(param->name, MAXBURSTLENGTH)) {
                        SET_PSTATE_NEGOTIATE(param);
                } else if (!strcmp(param->name, FIRSTBURSTLENGTH)) {
@@@ -662,7 -671,7 +671,7 @@@ int iscsi_extract_key_value(char *textb
  {
        *value = strchr(textbuf, '=');
        if (!*value) {
 -              pr_err("Unable to locate \"=\" seperator for key,"
 +              pr_err("Unable to locate \"=\" separator for key,"
                                " ignoring request.\n");
                return -1;
        }
@@@ -1056,7 -1065,8 +1065,8 @@@ out
        return proposer_values;
  }
  
- static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value)
+ static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value,
+                               struct iscsi_conn *conn)
  {
        u8 acceptor_boolean_value = 0, proposer_boolean_value = 0;
        char *negoitated_value = NULL;
                                return -1;
                }
  
-               if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
-                       SET_PSTATE_REPLY_OPTIONAL(param);
+               if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
+                       struct iscsi_param *param_mxdsl;
+                       unsigned long long tmp;
+                       int rc;
+                       rc = strict_strtoull(param->value, 0, &tmp);
+                       if (rc < 0)
+                               return -1;
+                       conn->conn_ops->MaxRecvDataSegmentLength = tmp;
+                       pr_debug("Saving op->MaxRecvDataSegmentLength from"
+                               " original initiator received value: %u\n",
+                               conn->conn_ops->MaxRecvDataSegmentLength);
+                       param_mxdsl = iscsi_find_param_from_key(
+                                               MAXXMITDATASEGMENTLENGTH,
+                                               conn->param_list);
+                       if (!param_mxdsl)
+                               return -1;
+                       rc = iscsi_update_param_value(param,
+                                               param_mxdsl->value);
+                       if (rc < 0)
+                               return -1;
+                       pr_debug("Updated %s to target MXDSL value: %s\n",
+                                       param->name, param->value);
+               }
        } else if (IS_TYPE_NUMBER_RANGE(param)) {
                negoitated_value = iscsi_get_value_from_number_range(
                                        param, value);
@@@ -1269,7 -1306,7 +1306,7 @@@ static int iscsi_check_value(struct isc
                comma_ptr = strchr(value, ',');
  
                if (comma_ptr && !IS_TYPE_VALUE_LIST(param)) {
 -                      pr_err("Detected value seperator \",\", but"
 +                      pr_err("Detected value separator \",\", but"
                                " key \"%s\" does not allow a value list,"
                                " protocol error.\n", param->name);
                        return -1;
@@@ -1526,8 -1563,9 +1563,9 @@@ int iscsi_decode_text_input
        u8 sender,
        char *textbuf,
        u32 length,
-       struct iscsi_param_list *param_list)
+       struct iscsi_conn *conn)
  {
+       struct iscsi_param_list *param_list = conn->param_list;
        char *tmpbuf, *start = NULL, *end = NULL;
  
        tmpbuf = kzalloc(length + 1, GFP_KERNEL);
                        }
                        SET_PSTATE_RESPONSE_GOT(param);
                } else {
-                       if (iscsi_check_acceptor_state(param, value) < 0) {
+                       if (iscsi_check_acceptor_state(param, value, conn) < 0) {
                                kfree(tmpbuf);
                                return -1;
                        }
@@@ -1720,6 -1758,18 +1758,18 @@@ void iscsi_set_connection_parameters
        pr_debug("---------------------------------------------------"
                        "---------------\n");
        list_for_each_entry(param, &param_list->param_list, p_list) {
+               /*
+                * Special case to set MAXXMITDATASEGMENTLENGTH from the
+                * target requested MaxRecvDataSegmentLength, even though
+                * this key is not sent over the wire.
+                */
+               if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) {
+                       ops->MaxXmitDataSegmentLength =
+                               simple_strtoul(param->value, &tmpptr, 0);
+                       pr_debug("MaxXmitDataSegmentLength:     %s\n",
+                               param->value);
+               }
                if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param))
                        continue;
                if (!strcmp(param->name, AUTHMETHOD)) {
                        pr_debug("DataDigest:                   %s\n",
                                param->value);
                } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
-                       ops->MaxRecvDataSegmentLength =
-                               simple_strtoul(param->value, &tmpptr, 0);
-                       pr_debug("MaxRecvDataSegmentLength:     %s\n",
-                               param->value);
+                       /*
+                        * At this point iscsi_check_acceptor_state() will have
+                        * set ops->MaxRecvDataSegmentLength from the original
+                        * initiator provided value.
+                        */
+                       pr_debug("MaxRecvDataSegmentLength:     %u\n",
+                               ops->MaxRecvDataSegmentLength);
                } else if (!strcmp(param->name, OFMARKER)) {
                        ops->OFMarker = !strcmp(param->value, YES);
                        pr_debug("OFMarker:                     %s\n",
index eaa1005377fc58ff9304ced98db1169823d8d81d,5662d6e927c010407a46bfd889f44600419c1d4c..97e68b38cfdf5ebab332f1ae0f670ed7b7edc56b
  #include <target/configfs_macros.h>
  #include <asm/unaligned.h>
  
 -#include "usbstring.c"
 -#include "epautoconf.c"
 -#include "config.c"
 -#include "composite.c"
 -
  #include "tcm_usb_gadget.h"
  
 +USB_GADGET_COMPOSITE_OPTIONS();
 +
  static struct target_fabric_configfs *usbg_fabric_configfs;
  
  static inline struct f_uas *to_f_uas(struct usb_function *f)
@@@ -1472,16 -1475,6 +1472,6 @@@ static int usbg_queue_tm_rsp(struct se_
        return 0;
  }
  
- static u16 usbg_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
- {
-       return 0;
- }
- static u16 usbg_get_fabric_sense_len(void)
- {
-       return 0;
- }
  static const char *usbg_check_wwn(const char *name)
  {
        const char *n;
@@@ -1822,7 -1815,7 +1812,7 @@@ static ssize_t tcm_usbg_tpg_store_nexus
                ret = tcm_usbg_drop_nexus(tpg);
                return (!ret) ? count : ret;
        }
-       if (strlen(page) > USBG_NAMELEN) {
+       if (strlen(page) >= USBG_NAMELEN) {
                pr_err("Emulated NAA Sas Address: %s, exceeds"
                                " max: %d\n", page, USBG_NAMELEN);
                return -EINVAL;
@@@ -1907,8 -1900,6 +1897,6 @@@ static struct target_core_fabric_ops us
        .queue_data_in                  = usbg_send_read_response,
        .queue_status                   = usbg_send_status_response,
        .queue_tm_rsp                   = usbg_queue_tm_rsp,
-       .get_fabric_sense_len           = usbg_get_fabric_sense_len,
-       .set_fabric_sense_len           = usbg_set_fabric_sense_len,
        .check_stop_free                = usbg_check_stop_free,
  
        .fabric_make_wwn                = usbg_make_tport,
@@@ -1968,12 -1959,12 +1956,11 @@@ static void usbg_deregister_configfs(vo
  static struct usb_interface_descriptor bot_intf_desc = {
        .bLength =              sizeof(bot_intf_desc),
        .bDescriptorType =      USB_DT_INTERFACE,
-       .bAlternateSetting =    0,
        .bNumEndpoints =        2,
        .bAlternateSetting =    USB_G_ALT_INT_BBB,
        .bInterfaceClass =      USB_CLASS_MASS_STORAGE,
        .bInterfaceSubClass =   USB_SC_SCSI,
        .bInterfaceProtocol =   USB_PR_BULK,
 -      .iInterface =           USB_G_STR_INT_UAS,
  };
  
  static struct usb_interface_descriptor uasp_intf_desc = {
        .bInterfaceClass =      USB_CLASS_MASS_STORAGE,
        .bInterfaceSubClass =   USB_SC_SCSI,
        .bInterfaceProtocol =   USB_PR_UAS,
 -      .iInterface =           USB_G_STR_INT_BBB,
  };
  
  static struct usb_endpoint_descriptor uasp_bi_desc = {
@@@ -2204,16 -2196,20 +2191,16 @@@ static struct usb_device_descriptor usb
        .bDeviceClass =         USB_CLASS_PER_INTERFACE,
        .idVendor =             cpu_to_le16(UAS_VENDOR_ID),
        .idProduct =            cpu_to_le16(UAS_PRODUCT_ID),
 -      .iManufacturer =        USB_G_STR_MANUFACTOR,
 -      .iProduct =             USB_G_STR_PRODUCT,
 -      .iSerialNumber =        USB_G_STR_SERIAL,
 -
        .bNumConfigurations =   1,
  };
  
  static struct usb_string      usbg_us_strings[] = {
 -      { USB_G_STR_MANUFACTOR, "Target Manufactor"},
 -      { USB_G_STR_PRODUCT,    "Target Product"},
 -      { USB_G_STR_SERIAL,     "000000000001"},
 -      { USB_G_STR_CONFIG,     "default config"},
 -      { USB_G_STR_INT_UAS,    "USB Attached SCSI"},
 -      { USB_G_STR_INT_BBB,    "Bulk Only Transport"},
 +      [USB_GADGET_MANUFACTURER_IDX].s = "Target Manufactor",
 +      [USB_GADGET_PRODUCT_IDX].s      = "Target Product",
 +      [USB_GADGET_SERIAL_IDX].s       = "000000000001",
 +      [USB_G_STR_CONFIG].s            = "default config",
 +      [USB_G_STR_INT_UAS].s           = "USB Attached SCSI",
 +      [USB_G_STR_INT_BBB].s           = "Bulk Only Transport",
        { },
  };
  
@@@ -2235,6 -2231,7 +2222,6 @@@ static int guas_unbind(struct usb_compo
  static struct usb_configuration usbg_config_driver = {
        .label                  = "Linux Target",
        .bConfigurationValue    = 1,
 -      .iConfiguration         = USB_G_STR_CONFIG,
        .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
  };
  
@@@ -2407,9 -2404,6 +2394,9 @@@ static int usbg_cfg_bind(struct usb_con
        fu->function.disable = usbg_disable;
        fu->tpg = the_only_tpg_I_currently_have;
  
 +      bot_intf_desc.iInterface = usbg_us_strings[USB_G_STR_INT_BBB].id;
 +      uasp_intf_desc.iInterface = usbg_us_strings[USB_G_STR_INT_UAS].id;
 +
        ret = usb_add_function(c, &fu->function);
        if (ret)
                goto err;
@@@ -2424,38 -2418,22 +2411,38 @@@ static int usb_target_bind(struct usb_c
  {
        int ret;
  
 +      ret = usb_string_ids_tab(cdev, usbg_us_strings);
 +      if (ret)
 +              return ret;
 +
 +      usbg_device_desc.iManufacturer =
 +              usbg_us_strings[USB_GADGET_MANUFACTURER_IDX].id;
 +      usbg_device_desc.iProduct = usbg_us_strings[USB_GADGET_PRODUCT_IDX].id;
 +      usbg_device_desc.iSerialNumber =
 +              usbg_us_strings[USB_GADGET_SERIAL_IDX].id;
 +      usbg_config_driver.iConfiguration =
 +              usbg_us_strings[USB_G_STR_CONFIG].id;
 +
        ret = usb_add_config(cdev, &usbg_config_driver,
                        usbg_cfg_bind);
 +      if (ret)
 +              return ret;
 +      usb_composite_overwrite_options(cdev, &coverwrite);
        return 0;
  }
  
 -static struct usb_composite_driver usbg_driver = {
 +static __refdata struct usb_composite_driver usbg_driver = {
        .name           = "g_target",
        .dev            = &usbg_device_desc,
        .strings        = usbg_strings,
        .max_speed      = USB_SPEED_SUPER,
 +      .bind           = usb_target_bind,
        .unbind         = guas_unbind,
  };
  
  static int usbg_attach(struct usbg_tpg *tpg)
  {
 -      return usb_composite_probe(&usbg_driver, usb_target_bind);
 +      return usb_composite_probe(&usbg_driver);
  }
  
  static void usbg_detach(struct usbg_tpg *tpg)