aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWen Xiong <wenxiong@linux.vnet.ibm.com>2015-03-26 12:23:58 -0400
committerJames Bottomley <JBottomley@Odin.com>2015-04-09 17:17:57 -0400
commitf8ee25d7d2395212ba614ba08c12d1255f612f0e (patch)
tree0fc2365b051f02592a1097a45c04a3590ecfaac3
parentea30c1deb6c6ccbceb29b6a3d48e1f601aefddf1 (diff)
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>
-rw-r--r--drivers/scsi/ipr.c85
-rw-r--r--drivers/scsi/ipr.h3
2 files changed, 88 insertions, 0 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index a9a464c728dd..3128407b407d 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -498,6 +498,10 @@ struct ipr_error_table_t ipr_error_table[] = {
498 "4061: Multipath redundancy level got better"}, 498 "4061: Multipath redundancy level got better"},
499 {0x066B9200, 0, IPR_DEFAULT_LOG_LEVEL, 499 {0x066B9200, 0, IPR_DEFAULT_LOG_LEVEL,
500 "4060: Multipath redundancy level got worse"}, 500 "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"},
501 {0x07270000, 0, 0, 505 {0x07270000, 0, 0,
502 "Failure due to other device"}, 506 "Failure due to other device"},
503 {0x07278000, 0, IPR_DEFAULT_LOG_LEVEL, 507 {0x07278000, 0, IPR_DEFAULT_LOG_LEVEL,
@@ -4496,11 +4500,83 @@ static struct device_attribute ipr_resource_type_attr = {
4496 .show = ipr_show_resource_type 4500 .show = ipr_show_resource_type
4497}; 4501};
4498 4502
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 **/
4511static 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 **/
4538static 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
4565static 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
4499static struct device_attribute *ipr_dev_attrs[] = { 4574static struct device_attribute *ipr_dev_attrs[] = {
4500 &ipr_adapter_handle_attr, 4575 &ipr_adapter_handle_attr,
4501 &ipr_resource_path_attr, 4576 &ipr_resource_path_attr,
4502 &ipr_device_id_attr, 4577 &ipr_device_id_attr,
4503 &ipr_resource_type_attr, 4578 &ipr_resource_type_attr,
4579 &ipr_raw_mode_attr,
4504 NULL, 4580 NULL,
4505}; 4581};
4506 4582
@@ -6152,6 +6228,13 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg,
6152 break; 6228 break;
6153 case IPR_IOASC_NR_INIT_CMD_REQUIRED: 6229 case IPR_IOASC_NR_INIT_CMD_REQUIRED:
6154 break; 6230 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;
6155 default: 6238 default:
6156 if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR) 6239 if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR)
6157 scsi_cmd->result |= (DID_ERROR << 16); 6240 scsi_cmd->result |= (DID_ERROR << 16);
@@ -6291,6 +6374,8 @@ static int ipr_queuecommand(struct Scsi_Host *shost,
6291 (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE)) { 6374 (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE)) {
6292 ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; 6375 ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD;
6293 } 6376 }
6377 if (res->raw_mode && ipr_is_af_dasd_device(res))
6378 ioarcb->cmd_pkt.request_type = IPR_RQTYPE_PIPE;
6294 6379
6295 if (ioa_cfg->sis64) 6380 if (ioa_cfg->sis64)
6296 rc = ipr_build_ioadl64(ioa_cfg, ipr_cmd); 6381 rc = ipr_build_ioadl64(ioa_cfg, ipr_cmd);
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index f7d0e375e4f6..8d7547ffa953 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -138,6 +138,7 @@
138#define IPR_IOASC_BUS_WAS_RESET 0x06290000 138#define IPR_IOASC_BUS_WAS_RESET 0x06290000
139#define IPR_IOASC_BUS_WAS_RESET_BY_OTHER 0x06298000 139#define IPR_IOASC_BUS_WAS_RESET_BY_OTHER 0x06298000
140#define IPR_IOASC_ABORTED_CMD_TERM_BY_HOST 0x0B5A0000 140#define IPR_IOASC_ABORTED_CMD_TERM_BY_HOST 0x0B5A0000
141#define IPR_IOASC_IR_NON_OPTIMIZED 0x05258200
141 142
142#define IPR_FIRST_DRIVER_IOASC 0x10000000 143#define IPR_FIRST_DRIVER_IOASC 0x10000000
143#define IPR_IOASC_IOA_WAS_RESET 0x10000001 144#define IPR_IOASC_IOA_WAS_RESET 0x10000001
@@ -521,6 +522,7 @@ struct ipr_cmd_pkt {
521#define IPR_RQTYPE_IOACMD 0x01 522#define IPR_RQTYPE_IOACMD 0x01
522#define IPR_RQTYPE_HCAM 0x02 523#define IPR_RQTYPE_HCAM 0x02
523#define IPR_RQTYPE_ATA_PASSTHRU 0x04 524#define IPR_RQTYPE_ATA_PASSTHRU 0x04
525#define IPR_RQTYPE_PIPE 0x05
524 526
525 u8 reserved2; 527 u8 reserved2;
526 528
@@ -1274,6 +1276,7 @@ struct ipr_resource_entry {
1274 u8 del_from_ml:1; 1276 u8 del_from_ml:1;
1275 u8 resetting_device:1; 1277 u8 resetting_device:1;
1276 u8 reset_occurred:1; 1278 u8 reset_occurred:1;
1279 u8 raw_mode:1;
1277 1280
1278 u32 bus; /* AKA channel */ 1281 u32 bus; /* AKA channel */
1279 u32 target; /* AKA id */ 1282 u32 target; /* AKA id */