Skip to content

Commit

Permalink
[SCSI] qla4xxx: fix data alignment and use nl helpers
Browse files Browse the repository at this point in the history
This has the driver use helpers for a common operation and fixes
a issue where if multiple iscsi params are sent they could be
sent at offsets that cause unaligned accesses. The nla helpers
account for the padding needed to align properly for the driver.

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
  • Loading branch information
Mike Christie authored and James Bottomley committed Oct 20, 2011
1 parent 88f4f51 commit 00c3188
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 19 deletions.
21 changes: 7 additions & 14 deletions drivers/scsi/qla4xxx/ql4_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ static int qla4xxx_conn_get_param(struct iscsi_cls_conn *conn,
enum iscsi_param param, char *buf);
static int qla4xxx_host_get_param(struct Scsi_Host *shost,
enum iscsi_host_param param, char *buf);
static int qla4xxx_iface_set_param(struct Scsi_Host *shost, char *data,
int count);
static int qla4xxx_iface_set_param(struct Scsi_Host *shost, void *data,
uint32_t len);
static int qla4xxx_get_iface_param(struct iscsi_iface *iface,
enum iscsi_param_type param_type,
int param, char *buf);
Expand Down Expand Up @@ -842,7 +842,7 @@ qla4xxx_initcb_to_acb(struct addr_ctrl_blk *init_fw_cb)
}

static int
qla4xxx_iface_set_param(struct Scsi_Host *shost, char *data, int count)
qla4xxx_iface_set_param(struct Scsi_Host *shost, void *data, uint32_t len)
{
struct scsi_qla_host *ha = to_qla_host(shost);
int rval = 0;
Expand All @@ -851,8 +851,8 @@ qla4xxx_iface_set_param(struct Scsi_Host *shost, char *data, int count)
dma_addr_t init_fw_cb_dma;
uint32_t mbox_cmd[MBOX_REG_COUNT];
uint32_t mbox_sts[MBOX_REG_COUNT];
uint32_t total_param_count;
uint32_t length;
uint32_t rem = len;
struct nlattr *attr;

init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,
sizeof(struct addr_ctrl_blk),
Expand All @@ -873,11 +873,8 @@ qla4xxx_iface_set_param(struct Scsi_Host *shost, char *data, int count)
goto exit_init_fw_cb;
}

total_param_count = count;
iface_param = (struct iscsi_iface_param_info *)data;

for ( ; total_param_count != 0; total_param_count--) {
length = iface_param->len;
nla_for_each_attr(attr, data, len, rem) {
iface_param = nla_data(attr);

if (iface_param->param_type != ISCSI_NET_PARAM)
continue;
Expand Down Expand Up @@ -914,10 +911,6 @@ qla4xxx_iface_set_param(struct Scsi_Host *shost, char *data, int count)
ql4_printk(KERN_ERR, ha, "Invalid iface type\n");
break;
}

iface_param = (struct iscsi_iface_param_info *)
((uint8_t *)iface_param +
sizeof(struct iscsi_iface_param_info) + length);
}

init_fw_cb->cookie = cpu_to_le32(0x11BEAD5A);
Expand Down
8 changes: 4 additions & 4 deletions drivers/scsi/scsi_transport_iscsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1890,7 +1890,7 @@ iscsi_set_path(struct iscsi_transport *transport, struct iscsi_uevent *ev)

static int
iscsi_set_iface_params(struct iscsi_transport *transport,
struct iscsi_uevent *ev)
struct iscsi_uevent *ev, uint32_t len)
{
char *data = (char *)ev + sizeof(*ev);
struct Scsi_Host *shost;
Expand All @@ -1906,8 +1906,7 @@ iscsi_set_iface_params(struct iscsi_transport *transport,
return -ENODEV;
}

err = transport->set_iface_param(shost, data,
ev->u.set_iface_params.count);
err = transport->set_iface_param(shost, data, len);
scsi_host_put(shost);
return err;
}
Expand Down Expand Up @@ -2052,7 +2051,8 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
err = iscsi_set_path(transport, ev);
break;
case ISCSI_UEVENT_SET_IFACE_PARAMS:
err = iscsi_set_iface_params(transport, ev);
err = iscsi_set_iface_params(transport, ev,
nlmsg_attrlen(nlh, sizeof(*ev)));
break;
default:
err = -ENOSYS;
Expand Down
3 changes: 2 additions & 1 deletion include/scsi/scsi_transport_iscsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ struct iscsi_transport {
int (*tgt_dscvr) (struct Scsi_Host *shost, enum iscsi_tgt_dscvr type,
uint32_t enable, struct sockaddr *dst_addr);
int (*set_path) (struct Scsi_Host *shost, struct iscsi_path *params);
int (*set_iface_param) (struct Scsi_Host *shost, char *data, int count);
int (*set_iface_param) (struct Scsi_Host *shost, void *data,
uint32_t len);
int (*get_iface_param) (struct iscsi_iface *iface,
enum iscsi_param_type param_type,
int param, char *buf);
Expand Down

0 comments on commit 00c3188

Please sign in to comment.