aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ipr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ipr.c')
-rw-r--r--drivers/scsi/ipr.c116
1 files changed, 80 insertions, 36 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 52568588039f..df9a12c8b373 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -1096,6 +1096,7 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res,
1096 res->bus = cfgtew->u.cfgte->res_addr.bus; 1096 res->bus = cfgtew->u.cfgte->res_addr.bus;
1097 res->target = cfgtew->u.cfgte->res_addr.target; 1097 res->target = cfgtew->u.cfgte->res_addr.target;
1098 res->lun = cfgtew->u.cfgte->res_addr.lun; 1098 res->lun = cfgtew->u.cfgte->res_addr.lun;
1099 res->lun_wwn = get_unaligned_be64(cfgtew->u.cfgte->lun_wwn);
1099 } 1100 }
1100 1101
1101 ipr_update_ata_class(res, proto); 1102 ipr_update_ata_class(res, proto);
@@ -1142,7 +1143,7 @@ static char *ipr_format_res_path(u8 *res_path, char *buffer, int len)
1142 int i; 1143 int i;
1143 char *p = buffer; 1144 char *p = buffer;
1144 1145
1145 res_path[0] = '\0'; 1146 *p = '\0';
1146 p += snprintf(p, buffer + len - p, "%02X", res_path[0]); 1147 p += snprintf(p, buffer + len - p, "%02X", res_path[0]);
1147 for (i = 1; res_path[i] != 0xff && ((i * 3) < len); i++) 1148 for (i = 1; res_path[i] != 0xff && ((i * 3) < len); i++)
1148 p += snprintf(p, buffer + len - p, "-%02X", res_path[i]); 1149 p += snprintf(p, buffer + len - p, "-%02X", res_path[i]);
@@ -1670,7 +1671,7 @@ static void ipr_log_enhanced_array_error(struct ipr_ioa_cfg *ioa_cfg,
1670 1671
1671 array_entry = error->array_member; 1672 array_entry = error->array_member;
1672 num_entries = min_t(u32, be32_to_cpu(error->num_entries), 1673 num_entries = min_t(u32, be32_to_cpu(error->num_entries),
1673 sizeof(error->array_member)); 1674 ARRAY_SIZE(error->array_member));
1674 1675
1675 for (i = 0; i < num_entries; i++, array_entry++) { 1676 for (i = 0; i < num_entries; i++, array_entry++) {
1676 if (!memcmp(array_entry->vpd.vpd.sn, zero_sn, IPR_SERIAL_NUM_LEN)) 1677 if (!memcmp(array_entry->vpd.vpd.sn, zero_sn, IPR_SERIAL_NUM_LEN))
@@ -2151,8 +2152,8 @@ static void ipr_log_sis64_array_error(struct ipr_ioa_cfg *ioa_cfg,
2151 ipr_err_separator; 2152 ipr_err_separator;
2152 2153
2153 array_entry = error->array_member; 2154 array_entry = error->array_member;
2154 num_entries = min_t(u32, be32_to_cpu(error->num_entries), 2155 num_entries = min_t(u32, error->num_entries,
2155 sizeof(error->array_member)); 2156 ARRAY_SIZE(error->array_member));
2156 2157
2157 for (i = 0; i < num_entries; i++, array_entry++) { 2158 for (i = 0; i < num_entries; i++, array_entry++) {
2158 2159
@@ -2166,10 +2167,10 @@ static void ipr_log_sis64_array_error(struct ipr_ioa_cfg *ioa_cfg,
2166 2167
2167 ipr_err("Array Member %d:\n", i); 2168 ipr_err("Array Member %d:\n", i);
2168 ipr_log_ext_vpd(&array_entry->vpd); 2169 ipr_log_ext_vpd(&array_entry->vpd);
2169 ipr_err("Current Location: %s", 2170 ipr_err("Current Location: %s\n",
2170 ipr_format_res_path(array_entry->res_path, buffer, 2171 ipr_format_res_path(array_entry->res_path, buffer,
2171 sizeof(buffer))); 2172 sizeof(buffer)));
2172 ipr_err("Expected Location: %s", 2173 ipr_err("Expected Location: %s\n",
2173 ipr_format_res_path(array_entry->expected_res_path, 2174 ipr_format_res_path(array_entry->expected_res_path,
2174 buffer, sizeof(buffer))); 2175 buffer, sizeof(buffer)));
2175 2176
@@ -4089,6 +4090,7 @@ static int ipr_change_queue_type(struct scsi_device *sdev, int tag_type)
4089/** 4090/**
4090 * ipr_show_adapter_handle - Show the adapter's resource handle for this device 4091 * ipr_show_adapter_handle - Show the adapter's resource handle for this device
4091 * @dev: device struct 4092 * @dev: device struct
4093 * @attr: device attribute structure
4092 * @buf: buffer 4094 * @buf: buffer
4093 * 4095 *
4094 * Return value: 4096 * Return value:
@@ -4122,6 +4124,7 @@ static struct device_attribute ipr_adapter_handle_attr = {
4122 * ipr_show_resource_path - Show the resource path or the resource address for 4124 * ipr_show_resource_path - Show the resource path or the resource address for
4123 * this device. 4125 * this device.
4124 * @dev: device struct 4126 * @dev: device struct
4127 * @attr: device attribute structure
4125 * @buf: buffer 4128 * @buf: buffer
4126 * 4129 *
4127 * Return value: 4130 * Return value:
@@ -4159,8 +4162,45 @@ static struct device_attribute ipr_resource_path_attr = {
4159}; 4162};
4160 4163
4161/** 4164/**
4165 * ipr_show_device_id - Show the device_id for this device.
4166 * @dev: device struct
4167 * @attr: device attribute structure
4168 * @buf: buffer
4169 *
4170 * Return value:
4171 * number of bytes printed to buffer
4172 **/
4173static ssize_t ipr_show_device_id(struct device *dev, struct device_attribute *attr, char *buf)
4174{
4175 struct scsi_device *sdev = to_scsi_device(dev);
4176 struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata;
4177 struct ipr_resource_entry *res;
4178 unsigned long lock_flags = 0;
4179 ssize_t len = -ENXIO;
4180
4181 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
4182 res = (struct ipr_resource_entry *)sdev->hostdata;
4183 if (res && ioa_cfg->sis64)
4184 len = snprintf(buf, PAGE_SIZE, "0x%llx\n", res->dev_id);
4185 else if (res)
4186 len = snprintf(buf, PAGE_SIZE, "0x%llx\n", res->lun_wwn);
4187
4188 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
4189 return len;
4190}
4191
4192static struct device_attribute ipr_device_id_attr = {
4193 .attr = {
4194 .name = "device_id",
4195 .mode = S_IRUGO,
4196 },
4197 .show = ipr_show_device_id
4198};
4199
4200/**
4162 * ipr_show_resource_type - Show the resource type for this device. 4201 * ipr_show_resource_type - Show the resource type for this device.
4163 * @dev: device struct 4202 * @dev: device struct
4203 * @attr: device attribute structure
4164 * @buf: buffer 4204 * @buf: buffer
4165 * 4205 *
4166 * Return value: 4206 * Return value:
@@ -4195,6 +4235,7 @@ static struct device_attribute ipr_resource_type_attr = {
4195static struct device_attribute *ipr_dev_attrs[] = { 4235static struct device_attribute *ipr_dev_attrs[] = {
4196 &ipr_adapter_handle_attr, 4236 &ipr_adapter_handle_attr,
4197 &ipr_resource_path_attr, 4237 &ipr_resource_path_attr,
4238 &ipr_device_id_attr,
4198 &ipr_resource_type_attr, 4239 &ipr_resource_type_attr,
4199 NULL, 4240 NULL,
4200}; 4241};
@@ -4898,39 +4939,15 @@ static int ipr_eh_abort(struct scsi_cmnd * scsi_cmd)
4898/** 4939/**
4899 * ipr_handle_other_interrupt - Handle "other" interrupts 4940 * ipr_handle_other_interrupt - Handle "other" interrupts
4900 * @ioa_cfg: ioa config struct 4941 * @ioa_cfg: ioa config struct
4942 * @int_reg: interrupt register
4901 * 4943 *
4902 * Return value: 4944 * Return value:
4903 * IRQ_NONE / IRQ_HANDLED 4945 * IRQ_NONE / IRQ_HANDLED
4904 **/ 4946 **/
4905static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg) 4947static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg,
4948 volatile u32 int_reg)
4906{ 4949{
4907 irqreturn_t rc = IRQ_HANDLED; 4950 irqreturn_t rc = IRQ_HANDLED;
4908 volatile u32 int_reg, int_mask_reg;
4909
4910 int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg32);
4911 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg;
4912
4913 /* If an interrupt on the adapter did not occur, ignore it.
4914 * Or in the case of SIS 64, check for a stage change interrupt.
4915 */
4916 if ((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0) {
4917 if (ioa_cfg->sis64) {
4918 int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
4919 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
4920 if (int_reg & IPR_PCII_IPL_STAGE_CHANGE) {
4921
4922 /* clear stage change */
4923 writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_reg);
4924 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
4925 list_del(&ioa_cfg->reset_cmd->queue);
4926 del_timer(&ioa_cfg->reset_cmd->timer);
4927 ipr_reset_ioa_job(ioa_cfg->reset_cmd);
4928 return IRQ_HANDLED;
4929 }
4930 }
4931
4932 return IRQ_NONE;
4933 }
4934 4951
4935 if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) { 4952 if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) {
4936 /* Mask the interrupt */ 4953 /* Mask the interrupt */
@@ -4991,7 +5008,7 @@ static irqreturn_t ipr_isr(int irq, void *devp)
4991{ 5008{
4992 struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)devp; 5009 struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)devp;
4993 unsigned long lock_flags = 0; 5010 unsigned long lock_flags = 0;
4994 volatile u32 int_reg; 5011 volatile u32 int_reg, int_mask_reg;
4995 u32 ioasc; 5012 u32 ioasc;
4996 u16 cmd_index; 5013 u16 cmd_index;
4997 int num_hrrq = 0; 5014 int num_hrrq = 0;
@@ -5006,6 +5023,33 @@ static irqreturn_t ipr_isr(int irq, void *devp)
5006 return IRQ_NONE; 5023 return IRQ_NONE;
5007 } 5024 }
5008 5025
5026 int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg32);
5027 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg;
5028
5029 /* If an interrupt on the adapter did not occur, ignore it.
5030 * Or in the case of SIS 64, check for a stage change interrupt.
5031 */
5032 if (unlikely((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0)) {
5033 if (ioa_cfg->sis64) {
5034 int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
5035 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
5036 if (int_reg & IPR_PCII_IPL_STAGE_CHANGE) {
5037
5038 /* clear stage change */
5039 writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_reg);
5040 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
5041 list_del(&ioa_cfg->reset_cmd->queue);
5042 del_timer(&ioa_cfg->reset_cmd->timer);
5043 ipr_reset_ioa_job(ioa_cfg->reset_cmd);
5044 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
5045 return IRQ_HANDLED;
5046 }
5047 }
5048
5049 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
5050 return IRQ_NONE;
5051 }
5052
5009 while (1) { 5053 while (1) {
5010 ipr_cmd = NULL; 5054 ipr_cmd = NULL;
5011 5055
@@ -5045,7 +5089,7 @@ static irqreturn_t ipr_isr(int irq, void *devp)
5045 /* Clear the PCI interrupt */ 5089 /* Clear the PCI interrupt */
5046 do { 5090 do {
5047 writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32); 5091 writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32);
5048 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32); 5092 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg;
5049 } while (int_reg & IPR_PCII_HRRQ_UPDATED && 5093 } while (int_reg & IPR_PCII_HRRQ_UPDATED &&
5050 num_hrrq++ < IPR_MAX_HRRQ_RETRIES); 5094 num_hrrq++ < IPR_MAX_HRRQ_RETRIES);
5051 5095
@@ -5060,7 +5104,7 @@ static irqreturn_t ipr_isr(int irq, void *devp)
5060 } 5104 }
5061 5105
5062 if (unlikely(rc == IRQ_NONE)) 5106 if (unlikely(rc == IRQ_NONE))
5063 rc = ipr_handle_other_interrupt(ioa_cfg); 5107 rc = ipr_handle_other_interrupt(ioa_cfg, int_reg);
5064 5108
5065 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 5109 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
5066 return rc; 5110 return rc;