Commit a54a52ca authored by Mike Christie's avatar Mike Christie Committed by James Bottomley

[SCSI] iscsi: fixup set/get param functions

Reduce duplication in the software iscsi_transport modules by
adding a libiscsi function to handle the common grunt work.

This also has the drivers return specifc -EXXX values for different
errors so userspace can finally handle them in a sane way.

Also just pass the sysfs buffers to the drivers so HW iscsi can
get/set its string values, like targetname, and initiatorname.
Signed-off-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 01cb225d
......@@ -1697,6 +1697,185 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session,
}
EXPORT_SYMBOL_GPL(iscsi_conn_bind);
int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
enum iscsi_param param, char *buf, int buflen)
{
struct iscsi_conn *conn = cls_conn->dd_data;
struct iscsi_session *session = conn->session;
uint32_t value;
switch(param) {
case ISCSI_PARAM_MAX_RECV_DLENGTH:
sscanf(buf, "%d", &conn->max_recv_dlength);
break;
case ISCSI_PARAM_MAX_XMIT_DLENGTH:
sscanf(buf, "%d", &conn->max_xmit_dlength);
break;
case ISCSI_PARAM_HDRDGST_EN:
sscanf(buf, "%d", &conn->hdrdgst_en);
break;
case ISCSI_PARAM_DATADGST_EN:
sscanf(buf, "%d", &conn->datadgst_en);
break;
case ISCSI_PARAM_INITIAL_R2T_EN:
sscanf(buf, "%d", &session->initial_r2t_en);
break;
case ISCSI_PARAM_MAX_R2T:
sscanf(buf, "%d", &session->max_r2t);
break;
case ISCSI_PARAM_IMM_DATA_EN:
sscanf(buf, "%d", &session->imm_data_en);
break;
case ISCSI_PARAM_FIRST_BURST:
sscanf(buf, "%d", &session->first_burst);
break;
case ISCSI_PARAM_MAX_BURST:
sscanf(buf, "%d", &session->max_burst);
break;
case ISCSI_PARAM_PDU_INORDER_EN:
sscanf(buf, "%d", &session->pdu_inorder_en);
break;
case ISCSI_PARAM_DATASEQ_INORDER_EN:
sscanf(buf, "%d", &session->dataseq_inorder_en);
break;
case ISCSI_PARAM_ERL:
sscanf(buf, "%d", &session->erl);
break;
case ISCSI_PARAM_IFMARKER_EN:
sscanf(buf, "%d", &value);
BUG_ON(value);
break;
case ISCSI_PARAM_OFMARKER_EN:
sscanf(buf, "%d", &value);
BUG_ON(value);
break;
case ISCSI_PARAM_EXP_STATSN:
sscanf(buf, "%u", &conn->exp_statsn);
break;
case ISCSI_PARAM_TARGET_NAME:
/* this should not change between logins */
if (session->targetname)
break;
session->targetname = kstrdup(buf, GFP_KERNEL);
if (!session->targetname)
return -ENOMEM;
break;
case ISCSI_PARAM_TPGT:
sscanf(buf, "%d", &session->tpgt);
break;
case ISCSI_PARAM_PERSISTENT_PORT:
sscanf(buf, "%d", &conn->persistent_port);
break;
case ISCSI_PARAM_PERSISTENT_ADDRESS:
/*
* this is the address returned in discovery so it should
* not change between logins.
*/
if (conn->persistent_address)
break;
conn->persistent_address = kstrdup(buf, GFP_KERNEL);
if (!conn->persistent_address)
return -ENOMEM;
break;
default:
return -ENOSYS;
}
return 0;
}
EXPORT_SYMBOL_GPL(iscsi_set_param);
int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
enum iscsi_param param, char *buf)
{
struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
int len;
switch(param) {
case ISCSI_PARAM_INITIAL_R2T_EN:
len = sprintf(buf, "%d\n", session->initial_r2t_en);
break;
case ISCSI_PARAM_MAX_R2T:
len = sprintf(buf, "%hu\n", session->max_r2t);
break;
case ISCSI_PARAM_IMM_DATA_EN:
len = sprintf(buf, "%d\n", session->imm_data_en);
break;
case ISCSI_PARAM_FIRST_BURST:
len = sprintf(buf, "%u\n", session->first_burst);
break;
case ISCSI_PARAM_MAX_BURST:
len = sprintf(buf, "%u\n", session->max_burst);
break;
case ISCSI_PARAM_PDU_INORDER_EN:
len = sprintf(buf, "%d\n", session->pdu_inorder_en);
break;
case ISCSI_PARAM_DATASEQ_INORDER_EN:
len = sprintf(buf, "%d\n", session->dataseq_inorder_en);
break;
case ISCSI_PARAM_ERL:
len = sprintf(buf, "%d\n", session->erl);
break;
case ISCSI_PARAM_TARGET_NAME:
len = sprintf(buf, "%s\n", session->targetname);
break;
case ISCSI_PARAM_TPGT:
len = sprintf(buf, "%d\n", session->tpgt);
break;
default:
return -ENOSYS;
}
return len;
}
EXPORT_SYMBOL_GPL(iscsi_session_get_param);
int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
enum iscsi_param param, char *buf)
{
struct iscsi_conn *conn = cls_conn->dd_data;
int len;
switch(param) {
case ISCSI_PARAM_MAX_RECV_DLENGTH:
len = sprintf(buf, "%u\n", conn->max_recv_dlength);
break;
case ISCSI_PARAM_MAX_XMIT_DLENGTH:
len = sprintf(buf, "%u\n", conn->max_xmit_dlength);
break;
case ISCSI_PARAM_HDRDGST_EN:
len = sprintf(buf, "%d\n", conn->hdrdgst_en);
break;
case ISCSI_PARAM_DATADGST_EN:
len = sprintf(buf, "%d\n", conn->datadgst_en);
break;
case ISCSI_PARAM_IFMARKER_EN:
len = sprintf(buf, "%d\n", conn->ifmarker_en);
break;
case ISCSI_PARAM_OFMARKER_EN:
len = sprintf(buf, "%d\n", conn->ofmarker_en);
break;
case ISCSI_PARAM_EXP_STATSN:
len = sprintf(buf, "%u\n", conn->exp_statsn);
break;
case ISCSI_PARAM_PERSISTENT_PORT:
len = sprintf(buf, "%d\n", conn->persistent_port);
break;
case ISCSI_PARAM_PERSISTENT_ADDRESS:
len = sprintf(buf, "%s\n", conn->persistent_address);
break;
default:
return -ENOSYS;
}
return len;
}
EXPORT_SYMBOL_GPL(iscsi_conn_get_param);
MODULE_AUTHOR("Mike Christie");
MODULE_DESCRIPTION("iSCSI library functions");
MODULE_LICENSE("GPL");
This diff is collapsed.
......@@ -157,6 +157,11 @@ struct iscsi_conn {
int max_xmit_dlength; /* target_max_recv_dsl */
int hdrdgst_en;
int datadgst_en;
int ifmarker_en;
int ofmarker_en;
/* values userspace uses to id a conn */
int persistent_port;
char *persistent_address;
/* MIB-statistics */
uint64_t txdata_octets;
......@@ -196,8 +201,8 @@ struct iscsi_session {
int pdu_inorder_en;
int dataseq_inorder_en;
int erl;
int ifmarker_en;
int ofmarker_en;
int tpgt;
char *targetname;
/* control data */
struct iscsi_transport *tt;
......@@ -240,6 +245,10 @@ iscsi_session_setup(struct iscsi_transport *, struct scsi_transport_template *,
extern void iscsi_session_teardown(struct iscsi_cls_session *);
extern struct iscsi_session *class_to_transport_session(struct iscsi_cls_session *);
extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *);
extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
enum iscsi_param param, char *buf, int buflen);
extern int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
enum iscsi_param param, char *buf);
#define session_to_cls(_sess) \
hostdata_session(_sess->host->hostdata)
......@@ -255,6 +264,8 @@ extern void iscsi_conn_stop(struct iscsi_cls_conn *, int);
extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *,
int);
extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err);
extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
enum iscsi_param param, char *buf);
/*
* pdu and task processing
......
......@@ -34,6 +34,7 @@ struct iscsi_cls_conn;
struct iscsi_conn;
struct iscsi_cmd_task;
struct iscsi_mgmt_task;
struct sockaddr;
/**
* struct iscsi_transport - iSCSI Transport template
......@@ -46,7 +47,12 @@ struct iscsi_mgmt_task;
* @bind_conn: associate this connection with existing iSCSI session
* and specified transport descriptor
* @destroy_conn: destroy inactive iSCSI connection
* @set_param: set iSCSI Data-Path operational parameter
* @set_param: set iSCSI parameter. Return 0 on success, -ENODATA
* when param is not supported, and a -Exx value on other
* error.
* @get_param get iSCSI parameter. Must return number of bytes
* copied to buffer on success, -ENODATA when param
* is not supported, and a -Exx value on other error
* @start_conn: set connection to be operational
* @stop_conn: suspend/recover/terminate connection
* @send_pdu: send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text.
......@@ -97,15 +103,11 @@ struct iscsi_transport {
void (*stop_conn) (struct iscsi_cls_conn *conn, int flag);
void (*destroy_conn) (struct iscsi_cls_conn *conn);
int (*set_param) (struct iscsi_cls_conn *conn, enum iscsi_param param,
uint32_t value);
char *buf, int buflen);
int (*get_conn_param) (struct iscsi_cls_conn *conn,
enum iscsi_param param, uint32_t *value);
enum iscsi_param param, char *buf);
int (*get_session_param) (struct iscsi_cls_session *session,
enum iscsi_param param, uint32_t *value);
int (*get_conn_str_param) (struct iscsi_cls_conn *conn,
enum iscsi_param param, char *buf);
int (*get_session_str_param) (struct iscsi_cls_session *session,
enum iscsi_param param, char *buf);
enum iscsi_param param, char *buf);
int (*send_pdu) (struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
char *data, uint32_t data_size);
void (*get_stats) (struct iscsi_cls_conn *conn,
......@@ -157,13 +159,6 @@ struct iscsi_cls_conn {
struct iscsi_transport *transport;
uint32_t cid; /* connection id */
/* portal/group values we got during discovery */
char *persistent_address;
int persistent_port;
/* portal/group values we are currently using */
char *address;
int port;
int active; /* must be accessed with the connlock */
struct device dev; /* sysfs transport/container device */
struct mempool_zone *z_error;
......@@ -187,10 +182,6 @@ struct iscsi_cls_session {
struct list_head host_list;
struct iscsi_transport *transport;
/* iSCSI values used as unique id by userspace. */
char *targetname;
int tpgt;
/* recovery fields */
int recovery_tmo;
struct work_struct recovery_work;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment