Skip to content

Commit f8ee25d

Browse files
wxiong38James Bottomley
authored andcommitted
ipr: AF DASD raw mode implementation in ipr driver
This patch implements raw mode support for AF DASD in ipr driver which allows for tools to send commands directly to physical devices which are members of RAID arrays when enabled in the firmware. [jejb: fix up whitespace] Signed-off-by: Wen Xiong<wenxiong@linux.vnet.ibm.com> Signed-off-by: Brian King <brking@linux.vnet.ibm.com> Reviewed-by: Daniel Kreling <kreling@linux.vnet.ibm.com> Signed-off-by: James Bottomley <JBottomley@Odin.com>
1 parent ea30c1d commit f8ee25d

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

drivers/scsi/ipr.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,10 @@ struct ipr_error_table_t ipr_error_table[] = {
498498
"4061: Multipath redundancy level got better"},
499499
{0x066B9200, 0, IPR_DEFAULT_LOG_LEVEL,
500500
"4060: Multipath redundancy level got worse"},
501+
{0x06808100, 0, IPR_DEFAULT_LOG_LEVEL,
502+
"9083: Device raw mode enabled"},
503+
{0x06808200, 0, IPR_DEFAULT_LOG_LEVEL,
504+
"9084: Device raw mode disabled"},
501505
{0x07270000, 0, 0,
502506
"Failure due to other device"},
503507
{0x07278000, 0, IPR_DEFAULT_LOG_LEVEL,
@@ -4496,11 +4500,83 @@ static struct device_attribute ipr_resource_type_attr = {
44964500
.show = ipr_show_resource_type
44974501
};
44984502

4503+
/**
4504+
* ipr_show_raw_mode - Show the adapter's raw mode
4505+
* @dev: class device struct
4506+
* @buf: buffer
4507+
*
4508+
* Return value:
4509+
* number of bytes printed to buffer
4510+
**/
4511+
static ssize_t ipr_show_raw_mode(struct device *dev,
4512+
struct device_attribute *attr, char *buf)
4513+
{
4514+
struct scsi_device *sdev = to_scsi_device(dev);
4515+
struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata;
4516+
struct ipr_resource_entry *res;
4517+
unsigned long lock_flags = 0;
4518+
ssize_t len;
4519+
4520+
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
4521+
res = (struct ipr_resource_entry *)sdev->hostdata;
4522+
if (res)
4523+
len = snprintf(buf, PAGE_SIZE, "%d\n", res->raw_mode);
4524+
else
4525+
len = -ENXIO;
4526+
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
4527+
return len;
4528+
}
4529+
4530+
/**
4531+
* ipr_store_raw_mode - Change the adapter's raw mode
4532+
* @dev: class device struct
4533+
* @buf: buffer
4534+
*
4535+
* Return value:
4536+
* number of bytes printed to buffer
4537+
**/
4538+
static ssize_t ipr_store_raw_mode(struct device *dev,
4539+
struct device_attribute *attr,
4540+
const char *buf, size_t count)
4541+
{
4542+
struct scsi_device *sdev = to_scsi_device(dev);
4543+
struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata;
4544+
struct ipr_resource_entry *res;
4545+
unsigned long lock_flags = 0;
4546+
ssize_t len;
4547+
4548+
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
4549+
res = (struct ipr_resource_entry *)sdev->hostdata;
4550+
if (res) {
4551+
if (ioa_cfg->sis64 && ipr_is_af_dasd_device(res)) {
4552+
res->raw_mode = simple_strtoul(buf, NULL, 10);
4553+
len = strlen(buf);
4554+
if (res->sdev)
4555+
sdev_printk(KERN_INFO, res->sdev, "raw mode is %s\n",
4556+
res->raw_mode ? "enabled" : "disabled");
4557+
} else
4558+
len = -EINVAL;
4559+
} else
4560+
len = -ENXIO;
4561+
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
4562+
return len;
4563+
}
4564+
4565+
static struct device_attribute ipr_raw_mode_attr = {
4566+
.attr = {
4567+
.name = "raw_mode",
4568+
.mode = S_IRUGO | S_IWUSR,
4569+
},
4570+
.show = ipr_show_raw_mode,
4571+
.store = ipr_store_raw_mode
4572+
};
4573+
44994574
static struct device_attribute *ipr_dev_attrs[] = {
45004575
&ipr_adapter_handle_attr,
45014576
&ipr_resource_path_attr,
45024577
&ipr_device_id_attr,
45034578
&ipr_resource_type_attr,
4579+
&ipr_raw_mode_attr,
45044580
NULL,
45054581
};
45064582

@@ -6152,6 +6228,13 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg,
61526228
break;
61536229
case IPR_IOASC_NR_INIT_CMD_REQUIRED:
61546230
break;
6231+
case IPR_IOASC_IR_NON_OPTIMIZED:
6232+
if (res->raw_mode) {
6233+
res->raw_mode = 0;
6234+
scsi_cmd->result |= (DID_IMM_RETRY << 16);
6235+
} else
6236+
scsi_cmd->result |= (DID_ERROR << 16);
6237+
break;
61556238
default:
61566239
if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR)
61576240
scsi_cmd->result |= (DID_ERROR << 16);
@@ -6291,6 +6374,8 @@ static int ipr_queuecommand(struct Scsi_Host *shost,
62916374
(!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE)) {
62926375
ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
62936376
}
6377+
if (res->raw_mode && ipr_is_af_dasd_device(res))
6378+
ioarcb->cmd_pkt.request_type = IPR_RQTYPE_PIPE;
62946379

62956380
if (ioa_cfg->sis64)
62966381
rc = ipr_build_ioadl64(ioa_cfg, ipr_cmd);

drivers/scsi/ipr.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@
138138
#define IPR_IOASC_BUS_WAS_RESET 0x06290000
139139
#define IPR_IOASC_BUS_WAS_RESET_BY_OTHER 0x06298000
140140
#define IPR_IOASC_ABORTED_CMD_TERM_BY_HOST 0x0B5A0000
141+
#define IPR_IOASC_IR_NON_OPTIMIZED 0x05258200
141142

142143
#define IPR_FIRST_DRIVER_IOASC 0x10000000
143144
#define IPR_IOASC_IOA_WAS_RESET 0x10000001
@@ -521,6 +522,7 @@ struct ipr_cmd_pkt {
521522
#define IPR_RQTYPE_IOACMD 0x01
522523
#define IPR_RQTYPE_HCAM 0x02
523524
#define IPR_RQTYPE_ATA_PASSTHRU 0x04
525+
#define IPR_RQTYPE_PIPE 0x05
524526

525527
u8 reserved2;
526528

@@ -1274,6 +1276,7 @@ struct ipr_resource_entry {
12741276
u8 del_from_ml:1;
12751277
u8 resetting_device:1;
12761278
u8 reset_occurred:1;
1279+
u8 raw_mode:1;
12771280

12781281
u32 bus; /* AKA channel */
12791282
u32 target; /* AKA id */

0 commit comments

Comments
 (0)