diff options
| -rw-r--r-- | drivers/scsi/ipr.c | 131 | ||||
| -rw-r--r-- | drivers/scsi/ipr.h | 26 |
2 files changed, 98 insertions, 59 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 735402f61aba..8c2f4c4041c1 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
| @@ -567,7 +567,8 @@ static void ipr_trc_hook(struct ipr_cmnd *ipr_cmd, | |||
| 567 | static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd) | 567 | static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd) |
| 568 | { | 568 | { |
| 569 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 569 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
| 570 | struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; | 570 | struct ipr_ioasa *ioasa = &ipr_cmd->s.ioasa; |
| 571 | struct ipr_ioasa64 *ioasa64 = &ipr_cmd->s.ioasa64; | ||
| 571 | dma_addr_t dma_addr = ipr_cmd->dma_addr; | 572 | dma_addr_t dma_addr = ipr_cmd->dma_addr; |
| 572 | 573 | ||
| 573 | memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); | 574 | memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); |
| @@ -576,19 +577,19 @@ static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd) | |||
| 576 | ioarcb->ioadl_len = 0; | 577 | ioarcb->ioadl_len = 0; |
| 577 | ioarcb->read_ioadl_len = 0; | 578 | ioarcb->read_ioadl_len = 0; |
| 578 | 579 | ||
| 579 | if (ipr_cmd->ioa_cfg->sis64) | 580 | if (ipr_cmd->ioa_cfg->sis64) { |
| 580 | ioarcb->u.sis64_addr_data.data_ioadl_addr = | 581 | ioarcb->u.sis64_addr_data.data_ioadl_addr = |
| 581 | cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64)); | 582 | cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64)); |
| 582 | else { | 583 | ioasa64->u.gata.status = 0; |
| 584 | } else { | ||
| 583 | ioarcb->write_ioadl_addr = | 585 | ioarcb->write_ioadl_addr = |
| 584 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl)); | 586 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl)); |
| 585 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; | 587 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; |
| 588 | ioasa->u.gata.status = 0; | ||
| 586 | } | 589 | } |
| 587 | 590 | ||
| 588 | ioasa->ioasc = 0; | 591 | ioasa->hdr.ioasc = 0; |
| 589 | ioasa->residual_data_len = 0; | 592 | ioasa->hdr.residual_data_len = 0; |
| 590 | ioasa->u.gata.status = 0; | ||
| 591 | |||
| 592 | ipr_cmd->scsi_cmd = NULL; | 593 | ipr_cmd->scsi_cmd = NULL; |
| 593 | ipr_cmd->qc = NULL; | 594 | ipr_cmd->qc = NULL; |
| 594 | ipr_cmd->sense_buffer[0] = 0; | 595 | ipr_cmd->sense_buffer[0] = 0; |
| @@ -768,8 +769,8 @@ static void ipr_fail_all_ops(struct ipr_ioa_cfg *ioa_cfg) | |||
| 768 | list_for_each_entry_safe(ipr_cmd, temp, &ioa_cfg->pending_q, queue) { | 769 | list_for_each_entry_safe(ipr_cmd, temp, &ioa_cfg->pending_q, queue) { |
| 769 | list_del(&ipr_cmd->queue); | 770 | list_del(&ipr_cmd->queue); |
| 770 | 771 | ||
| 771 | ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_IOA_WAS_RESET); | 772 | ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_IOA_WAS_RESET); |
| 772 | ipr_cmd->ioasa.ilid = cpu_to_be32(IPR_DRIVER_ILID); | 773 | ipr_cmd->s.ioasa.hdr.ilid = cpu_to_be32(IPR_DRIVER_ILID); |
| 773 | 774 | ||
| 774 | if (ipr_cmd->scsi_cmd) | 775 | if (ipr_cmd->scsi_cmd) |
| 775 | ipr_cmd->done = ipr_scsi_eh_done; | 776 | ipr_cmd->done = ipr_scsi_eh_done; |
| @@ -1319,7 +1320,7 @@ static void ipr_process_ccn(struct ipr_cmnd *ipr_cmd) | |||
| 1319 | { | 1320 | { |
| 1320 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 1321 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
| 1321 | struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb; | 1322 | struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb; |
| 1322 | u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); | 1323 | u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); |
| 1323 | 1324 | ||
| 1324 | list_del(&hostrcb->queue); | 1325 | list_del(&hostrcb->queue); |
| 1325 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); | 1326 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); |
| @@ -2354,7 +2355,7 @@ static void ipr_process_error(struct ipr_cmnd *ipr_cmd) | |||
| 2354 | { | 2355 | { |
| 2355 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 2356 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
| 2356 | struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb; | 2357 | struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb; |
| 2357 | u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); | 2358 | u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); |
| 2358 | u32 fd_ioasc; | 2359 | u32 fd_ioasc; |
| 2359 | 2360 | ||
| 2360 | if (ioa_cfg->sis64) | 2361 | if (ioa_cfg->sis64) |
| @@ -4509,11 +4510,16 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg, | |||
| 4509 | } | 4510 | } |
| 4510 | 4511 | ||
| 4511 | ipr_send_blocking_cmd(ipr_cmd, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT); | 4512 | ipr_send_blocking_cmd(ipr_cmd, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT); |
| 4512 | ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); | 4513 | ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); |
| 4513 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); | 4514 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); |
| 4514 | if (ipr_is_gata(res) && res->sata_port && ioasc != IPR_IOASC_IOA_WAS_RESET) | 4515 | if (ipr_is_gata(res) && res->sata_port && ioasc != IPR_IOASC_IOA_WAS_RESET) { |
| 4515 | memcpy(&res->sata_port->ioasa, &ipr_cmd->ioasa.u.gata, | 4516 | if (ipr_cmd->ioa_cfg->sis64) |
| 4516 | sizeof(struct ipr_ioasa_gata)); | 4517 | memcpy(&res->sata_port->ioasa, &ipr_cmd->s.ioasa64.u.gata, |
| 4518 | sizeof(struct ipr_ioasa_gata)); | ||
| 4519 | else | ||
| 4520 | memcpy(&res->sata_port->ioasa, &ipr_cmd->s.ioasa.u.gata, | ||
| 4521 | sizeof(struct ipr_ioasa_gata)); | ||
| 4522 | } | ||
| 4517 | 4523 | ||
| 4518 | LEAVE; | 4524 | LEAVE; |
| 4519 | return (IPR_IOASC_SENSE_KEY(ioasc) ? -EIO : 0); | 4525 | return (IPR_IOASC_SENSE_KEY(ioasc) ? -EIO : 0); |
| @@ -4768,7 +4774,7 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd) | |||
| 4768 | scmd_printk(KERN_ERR, scsi_cmd, "Aborting command: %02X\n", | 4774 | scmd_printk(KERN_ERR, scsi_cmd, "Aborting command: %02X\n", |
| 4769 | scsi_cmd->cmnd[0]); | 4775 | scsi_cmd->cmnd[0]); |
| 4770 | ipr_send_blocking_cmd(ipr_cmd, ipr_abort_timeout, IPR_CANCEL_ALL_TIMEOUT); | 4776 | ipr_send_blocking_cmd(ipr_cmd, ipr_abort_timeout, IPR_CANCEL_ALL_TIMEOUT); |
| 4771 | ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); | 4777 | ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); |
| 4772 | 4778 | ||
| 4773 | /* | 4779 | /* |
| 4774 | * If the abort task timed out and we sent a bus reset, we will get | 4780 | * If the abort task timed out and we sent a bus reset, we will get |
| @@ -4940,7 +4946,7 @@ static irqreturn_t ipr_isr(int irq, void *devp) | |||
| 4940 | 4946 | ||
| 4941 | ipr_cmd = ioa_cfg->ipr_cmnd_list[cmd_index]; | 4947 | ipr_cmd = ioa_cfg->ipr_cmnd_list[cmd_index]; |
| 4942 | 4948 | ||
| 4943 | ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); | 4949 | ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); |
| 4944 | 4950 | ||
| 4945 | ipr_trc_hook(ipr_cmd, IPR_TRACE_FINISH, ioasc); | 4951 | ipr_trc_hook(ipr_cmd, IPR_TRACE_FINISH, ioasc); |
| 4946 | 4952 | ||
| @@ -5137,7 +5143,7 @@ static void ipr_erp_done(struct ipr_cmnd *ipr_cmd) | |||
| 5137 | struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; | 5143 | struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; |
| 5138 | struct ipr_resource_entry *res = scsi_cmd->device->hostdata; | 5144 | struct ipr_resource_entry *res = scsi_cmd->device->hostdata; |
| 5139 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 5145 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
| 5140 | u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); | 5146 | u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); |
| 5141 | 5147 | ||
| 5142 | if (IPR_IOASC_SENSE_KEY(ioasc) > 0) { | 5148 | if (IPR_IOASC_SENSE_KEY(ioasc) > 0) { |
| 5143 | scsi_cmd->result |= (DID_ERROR << 16); | 5149 | scsi_cmd->result |= (DID_ERROR << 16); |
| @@ -5168,7 +5174,7 @@ static void ipr_erp_done(struct ipr_cmnd *ipr_cmd) | |||
| 5168 | static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd) | 5174 | static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd) |
| 5169 | { | 5175 | { |
| 5170 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 5176 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
| 5171 | struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; | 5177 | struct ipr_ioasa *ioasa = &ipr_cmd->s.ioasa; |
| 5172 | dma_addr_t dma_addr = ipr_cmd->dma_addr; | 5178 | dma_addr_t dma_addr = ipr_cmd->dma_addr; |
| 5173 | 5179 | ||
| 5174 | memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); | 5180 | memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); |
| @@ -5176,8 +5182,8 @@ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd) | |||
| 5176 | ioarcb->read_data_transfer_length = 0; | 5182 | ioarcb->read_data_transfer_length = 0; |
| 5177 | ioarcb->ioadl_len = 0; | 5183 | ioarcb->ioadl_len = 0; |
| 5178 | ioarcb->read_ioadl_len = 0; | 5184 | ioarcb->read_ioadl_len = 0; |
| 5179 | ioasa->ioasc = 0; | 5185 | ioasa->hdr.ioasc = 0; |
| 5180 | ioasa->residual_data_len = 0; | 5186 | ioasa->hdr.residual_data_len = 0; |
| 5181 | 5187 | ||
| 5182 | if (ipr_cmd->ioa_cfg->sis64) | 5188 | if (ipr_cmd->ioa_cfg->sis64) |
| 5183 | ioarcb->u.sis64_addr_data.data_ioadl_addr = | 5189 | ioarcb->u.sis64_addr_data.data_ioadl_addr = |
| @@ -5202,7 +5208,7 @@ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd) | |||
| 5202 | static void ipr_erp_request_sense(struct ipr_cmnd *ipr_cmd) | 5208 | static void ipr_erp_request_sense(struct ipr_cmnd *ipr_cmd) |
| 5203 | { | 5209 | { |
| 5204 | struct ipr_cmd_pkt *cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt; | 5210 | struct ipr_cmd_pkt *cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt; |
| 5205 | u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); | 5211 | u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); |
| 5206 | 5212 | ||
| 5207 | if (IPR_IOASC_SENSE_KEY(ioasc) > 0) { | 5213 | if (IPR_IOASC_SENSE_KEY(ioasc) > 0) { |
| 5208 | ipr_erp_done(ipr_cmd); | 5214 | ipr_erp_done(ipr_cmd); |
| @@ -5279,12 +5285,12 @@ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg, | |||
| 5279 | int i; | 5285 | int i; |
| 5280 | u16 data_len; | 5286 | u16 data_len; |
| 5281 | u32 ioasc, fd_ioasc; | 5287 | u32 ioasc, fd_ioasc; |
| 5282 | struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; | 5288 | struct ipr_ioasa *ioasa = &ipr_cmd->s.ioasa; |
| 5283 | __be32 *ioasa_data = (__be32 *)ioasa; | 5289 | __be32 *ioasa_data = (__be32 *)ioasa; |
| 5284 | int error_index; | 5290 | int error_index; |
| 5285 | 5291 | ||
| 5286 | ioasc = be32_to_cpu(ioasa->ioasc) & IPR_IOASC_IOASC_MASK; | 5292 | ioasc = be32_to_cpu(ioasa->hdr.ioasc) & IPR_IOASC_IOASC_MASK; |
| 5287 | fd_ioasc = be32_to_cpu(ioasa->fd_ioasc) & IPR_IOASC_IOASC_MASK; | 5293 | fd_ioasc = be32_to_cpu(ioasa->hdr.fd_ioasc) & IPR_IOASC_IOASC_MASK; |
| 5288 | 5294 | ||
| 5289 | if (0 == ioasc) | 5295 | if (0 == ioasc) |
| 5290 | return; | 5296 | return; |
| @@ -5299,7 +5305,7 @@ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg, | |||
| 5299 | 5305 | ||
| 5300 | if (ioa_cfg->log_level < IPR_MAX_LOG_LEVEL) { | 5306 | if (ioa_cfg->log_level < IPR_MAX_LOG_LEVEL) { |
| 5301 | /* Don't log an error if the IOA already logged one */ | 5307 | /* Don't log an error if the IOA already logged one */ |
| 5302 | if (ioasa->ilid != 0) | 5308 | if (ioasa->hdr.ilid != 0) |
| 5303 | return; | 5309 | return; |
| 5304 | 5310 | ||
| 5305 | if (!ipr_is_gscsi(res)) | 5311 | if (!ipr_is_gscsi(res)) |
| @@ -5311,10 +5317,11 @@ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg, | |||
| 5311 | 5317 | ||
| 5312 | ipr_res_err(ioa_cfg, res, "%s\n", ipr_error_table[error_index].error); | 5318 | ipr_res_err(ioa_cfg, res, "%s\n", ipr_error_table[error_index].error); |
| 5313 | 5319 | ||
| 5314 | if (sizeof(struct ipr_ioasa) < be16_to_cpu(ioasa->ret_stat_len)) | 5320 | data_len = be16_to_cpu(ioasa->hdr.ret_stat_len); |
| 5321 | if (ioa_cfg->sis64 && sizeof(struct ipr_ioasa64) < data_len) | ||
| 5322 | data_len = sizeof(struct ipr_ioasa64); | ||
| 5323 | else if (!ioa_cfg->sis64 && sizeof(struct ipr_ioasa) < data_len) | ||
| 5315 | data_len = sizeof(struct ipr_ioasa); | 5324 | data_len = sizeof(struct ipr_ioasa); |
| 5316 | else | ||
| 5317 | data_len = be16_to_cpu(ioasa->ret_stat_len); | ||
| 5318 | 5325 | ||
| 5319 | ipr_err("IOASA Dump:\n"); | 5326 | ipr_err("IOASA Dump:\n"); |
| 5320 | 5327 | ||
| @@ -5340,8 +5347,8 @@ static void ipr_gen_sense(struct ipr_cmnd *ipr_cmd) | |||
| 5340 | u32 failing_lba; | 5347 | u32 failing_lba; |
| 5341 | u8 *sense_buf = ipr_cmd->scsi_cmd->sense_buffer; | 5348 | u8 *sense_buf = ipr_cmd->scsi_cmd->sense_buffer; |
| 5342 | struct ipr_resource_entry *res = ipr_cmd->scsi_cmd->device->hostdata; | 5349 | struct ipr_resource_entry *res = ipr_cmd->scsi_cmd->device->hostdata; |
| 5343 | struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; | 5350 | struct ipr_ioasa *ioasa = &ipr_cmd->s.ioasa; |
| 5344 | u32 ioasc = be32_to_cpu(ioasa->ioasc); | 5351 | u32 ioasc = be32_to_cpu(ioasa->hdr.ioasc); |
| 5345 | 5352 | ||
| 5346 | memset(sense_buf, 0, SCSI_SENSE_BUFFERSIZE); | 5353 | memset(sense_buf, 0, SCSI_SENSE_BUFFERSIZE); |
| 5347 | 5354 | ||
| @@ -5384,7 +5391,7 @@ static void ipr_gen_sense(struct ipr_cmnd *ipr_cmd) | |||
| 5384 | 5391 | ||
| 5385 | /* Illegal request */ | 5392 | /* Illegal request */ |
| 5386 | if ((IPR_IOASC_SENSE_KEY(ioasc) == 0x05) && | 5393 | if ((IPR_IOASC_SENSE_KEY(ioasc) == 0x05) && |
| 5387 | (be32_to_cpu(ioasa->ioasc_specific) & IPR_FIELD_POINTER_VALID)) { | 5394 | (be32_to_cpu(ioasa->hdr.ioasc_specific) & IPR_FIELD_POINTER_VALID)) { |
| 5388 | sense_buf[7] = 10; /* additional length */ | 5395 | sense_buf[7] = 10; /* additional length */ |
| 5389 | 5396 | ||
| 5390 | /* IOARCB was in error */ | 5397 | /* IOARCB was in error */ |
| @@ -5395,10 +5402,10 @@ static void ipr_gen_sense(struct ipr_cmnd *ipr_cmd) | |||
| 5395 | 5402 | ||
| 5396 | sense_buf[16] = | 5403 | sense_buf[16] = |
| 5397 | ((IPR_FIELD_POINTER_MASK & | 5404 | ((IPR_FIELD_POINTER_MASK & |
| 5398 | be32_to_cpu(ioasa->ioasc_specific)) >> 8) & 0xff; | 5405 | be32_to_cpu(ioasa->hdr.ioasc_specific)) >> 8) & 0xff; |
| 5399 | sense_buf[17] = | 5406 | sense_buf[17] = |
| 5400 | (IPR_FIELD_POINTER_MASK & | 5407 | (IPR_FIELD_POINTER_MASK & |
| 5401 | be32_to_cpu(ioasa->ioasc_specific)) & 0xff; | 5408 | be32_to_cpu(ioasa->hdr.ioasc_specific)) & 0xff; |
| 5402 | } else { | 5409 | } else { |
| 5403 | if (ioasc == IPR_IOASC_MED_DO_NOT_REALLOC) { | 5410 | if (ioasc == IPR_IOASC_MED_DO_NOT_REALLOC) { |
| 5404 | if (ipr_is_vset_device(res)) | 5411 | if (ipr_is_vset_device(res)) |
| @@ -5430,14 +5437,20 @@ static void ipr_gen_sense(struct ipr_cmnd *ipr_cmd) | |||
| 5430 | **/ | 5437 | **/ |
| 5431 | static int ipr_get_autosense(struct ipr_cmnd *ipr_cmd) | 5438 | static int ipr_get_autosense(struct ipr_cmnd *ipr_cmd) |
| 5432 | { | 5439 | { |
| 5433 | struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; | 5440 | struct ipr_ioasa *ioasa = &ipr_cmd->s.ioasa; |
| 5441 | struct ipr_ioasa64 *ioasa64 = &ipr_cmd->s.ioasa64; | ||
| 5434 | 5442 | ||
| 5435 | if ((be32_to_cpu(ioasa->ioasc_specific) & IPR_AUTOSENSE_VALID) == 0) | 5443 | if ((be32_to_cpu(ioasa->hdr.ioasc_specific) & IPR_AUTOSENSE_VALID) == 0) |
| 5436 | return 0; | 5444 | return 0; |
| 5437 | 5445 | ||
| 5438 | memcpy(ipr_cmd->scsi_cmd->sense_buffer, ioasa->auto_sense.data, | 5446 | if (ipr_cmd->ioa_cfg->sis64) |
| 5439 | min_t(u16, be16_to_cpu(ioasa->auto_sense.auto_sense_len), | 5447 | memcpy(ipr_cmd->scsi_cmd->sense_buffer, ioasa64->auto_sense.data, |
| 5440 | SCSI_SENSE_BUFFERSIZE)); | 5448 | min_t(u16, be16_to_cpu(ioasa64->auto_sense.auto_sense_len), |
| 5449 | SCSI_SENSE_BUFFERSIZE)); | ||
| 5450 | else | ||
| 5451 | memcpy(ipr_cmd->scsi_cmd->sense_buffer, ioasa->auto_sense.data, | ||
| 5452 | min_t(u16, be16_to_cpu(ioasa->auto_sense.auto_sense_len), | ||
| 5453 | SCSI_SENSE_BUFFERSIZE)); | ||
| 5441 | return 1; | 5454 | return 1; |
| 5442 | } | 5455 | } |
| 5443 | 5456 | ||
| @@ -5457,7 +5470,7 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg, | |||
| 5457 | { | 5470 | { |
| 5458 | struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; | 5471 | struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; |
| 5459 | struct ipr_resource_entry *res = scsi_cmd->device->hostdata; | 5472 | struct ipr_resource_entry *res = scsi_cmd->device->hostdata; |
| 5460 | u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); | 5473 | u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); |
| 5461 | u32 masked_ioasc = ioasc & IPR_IOASC_IOASC_MASK; | 5474 | u32 masked_ioasc = ioasc & IPR_IOASC_IOASC_MASK; |
| 5462 | 5475 | ||
| 5463 | if (!res) { | 5476 | if (!res) { |
| @@ -5549,9 +5562,9 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd) | |||
| 5549 | { | 5562 | { |
| 5550 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 5563 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
| 5551 | struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; | 5564 | struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; |
| 5552 | u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); | 5565 | u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); |
| 5553 | 5566 | ||
| 5554 | scsi_set_resid(scsi_cmd, be32_to_cpu(ipr_cmd->ioasa.residual_data_len)); | 5567 | scsi_set_resid(scsi_cmd, be32_to_cpu(ipr_cmd->s.ioasa.hdr.residual_data_len)); |
| 5555 | 5568 | ||
| 5556 | if (likely(IPR_IOASC_SENSE_KEY(ioasc) == 0)) { | 5569 | if (likely(IPR_IOASC_SENSE_KEY(ioasc) == 0)) { |
| 5557 | scsi_dma_unmap(ipr_cmd->scsi_cmd); | 5570 | scsi_dma_unmap(ipr_cmd->scsi_cmd); |
| @@ -5841,19 +5854,23 @@ static void ipr_sata_done(struct ipr_cmnd *ipr_cmd) | |||
| 5841 | struct ata_queued_cmd *qc = ipr_cmd->qc; | 5854 | struct ata_queued_cmd *qc = ipr_cmd->qc; |
| 5842 | struct ipr_sata_port *sata_port = qc->ap->private_data; | 5855 | struct ipr_sata_port *sata_port = qc->ap->private_data; |
| 5843 | struct ipr_resource_entry *res = sata_port->res; | 5856 | struct ipr_resource_entry *res = sata_port->res; |
| 5844 | u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); | 5857 | u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); |
| 5845 | 5858 | ||
| 5846 | memcpy(&sata_port->ioasa, &ipr_cmd->ioasa.u.gata, | 5859 | if (ipr_cmd->ioa_cfg->sis64) |
| 5847 | sizeof(struct ipr_ioasa_gata)); | 5860 | memcpy(&sata_port->ioasa, &ipr_cmd->s.ioasa64.u.gata, |
| 5861 | sizeof(struct ipr_ioasa_gata)); | ||
| 5862 | else | ||
| 5863 | memcpy(&sata_port->ioasa, &ipr_cmd->s.ioasa.u.gata, | ||
| 5864 | sizeof(struct ipr_ioasa_gata)); | ||
| 5848 | ipr_dump_ioasa(ioa_cfg, ipr_cmd, res); | 5865 | ipr_dump_ioasa(ioa_cfg, ipr_cmd, res); |
| 5849 | 5866 | ||
| 5850 | if (be32_to_cpu(ipr_cmd->ioasa.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET) | 5867 | if (be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET) |
| 5851 | scsi_report_device_reset(ioa_cfg->host, res->bus, res->target); | 5868 | scsi_report_device_reset(ioa_cfg->host, res->bus, res->target); |
| 5852 | 5869 | ||
| 5853 | if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR) | 5870 | if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR) |
| 5854 | qc->err_mask |= __ac_err_mask(ipr_cmd->ioasa.u.gata.status); | 5871 | qc->err_mask |= __ac_err_mask(sata_port->ioasa.status); |
| 5855 | else | 5872 | else |
| 5856 | qc->err_mask |= ac_err_mask(ipr_cmd->ioasa.u.gata.status); | 5873 | qc->err_mask |= ac_err_mask(sata_port->ioasa.status); |
| 5857 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); | 5874 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); |
| 5858 | ata_qc_complete(qc); | 5875 | ata_qc_complete(qc); |
| 5859 | } | 5876 | } |
| @@ -6522,7 +6539,7 @@ static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd, | |||
| 6522 | static int ipr_reset_cmd_failed(struct ipr_cmnd *ipr_cmd) | 6539 | static int ipr_reset_cmd_failed(struct ipr_cmnd *ipr_cmd) |
| 6523 | { | 6540 | { |
| 6524 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 6541 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
| 6525 | u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); | 6542 | u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); |
| 6526 | 6543 | ||
| 6527 | dev_err(&ioa_cfg->pdev->dev, | 6544 | dev_err(&ioa_cfg->pdev->dev, |
| 6528 | "0x%02X failed with IOASC: 0x%08X\n", | 6545 | "0x%02X failed with IOASC: 0x%08X\n", |
| @@ -6546,7 +6563,7 @@ static int ipr_reset_cmd_failed(struct ipr_cmnd *ipr_cmd) | |||
| 6546 | static int ipr_reset_mode_sense_failed(struct ipr_cmnd *ipr_cmd) | 6563 | static int ipr_reset_mode_sense_failed(struct ipr_cmnd *ipr_cmd) |
| 6547 | { | 6564 | { |
| 6548 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 6565 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
| 6549 | u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); | 6566 | u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); |
| 6550 | 6567 | ||
| 6551 | if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) { | 6568 | if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) { |
| 6552 | ipr_cmd->job_step = ipr_set_supported_devs; | 6569 | ipr_cmd->job_step = ipr_set_supported_devs; |
| @@ -6636,7 +6653,7 @@ static int ipr_ioafp_mode_select_page24(struct ipr_cmnd *ipr_cmd) | |||
| 6636 | **/ | 6653 | **/ |
| 6637 | static int ipr_reset_mode_sense_page24_failed(struct ipr_cmnd *ipr_cmd) | 6654 | static int ipr_reset_mode_sense_page24_failed(struct ipr_cmnd *ipr_cmd) |
| 6638 | { | 6655 | { |
| 6639 | u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); | 6656 | u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); |
| 6640 | 6657 | ||
| 6641 | if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) { | 6658 | if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) { |
| 6642 | ipr_cmd->job_step = ipr_ioafp_mode_sense_page28; | 6659 | ipr_cmd->job_step = ipr_ioafp_mode_sense_page28; |
| @@ -7337,12 +7354,12 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd) | |||
| 7337 | rc = pci_restore_state(ioa_cfg->pdev); | 7354 | rc = pci_restore_state(ioa_cfg->pdev); |
| 7338 | 7355 | ||
| 7339 | if (rc != PCIBIOS_SUCCESSFUL) { | 7356 | if (rc != PCIBIOS_SUCCESSFUL) { |
| 7340 | ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); | 7357 | ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); |
| 7341 | return IPR_RC_JOB_CONTINUE; | 7358 | return IPR_RC_JOB_CONTINUE; |
| 7342 | } | 7359 | } |
| 7343 | 7360 | ||
| 7344 | if (ipr_set_pcix_cmd_reg(ioa_cfg)) { | 7361 | if (ipr_set_pcix_cmd_reg(ioa_cfg)) { |
| 7345 | ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); | 7362 | ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); |
| 7346 | return IPR_RC_JOB_CONTINUE; | 7363 | return IPR_RC_JOB_CONTINUE; |
| 7347 | } | 7364 | } |
| 7348 | 7365 | ||
| @@ -7411,7 +7428,7 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd) | |||
| 7411 | 7428 | ||
| 7412 | if (rc != PCIBIOS_SUCCESSFUL) { | 7429 | if (rc != PCIBIOS_SUCCESSFUL) { |
| 7413 | pci_unblock_user_cfg_access(ipr_cmd->ioa_cfg->pdev); | 7430 | pci_unblock_user_cfg_access(ipr_cmd->ioa_cfg->pdev); |
| 7414 | ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); | 7431 | ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); |
| 7415 | rc = IPR_RC_JOB_CONTINUE; | 7432 | rc = IPR_RC_JOB_CONTINUE; |
| 7416 | } else { | 7433 | } else { |
| 7417 | ipr_cmd->job_step = ipr_reset_bist_done; | 7434 | ipr_cmd->job_step = ipr_reset_bist_done; |
| @@ -7670,7 +7687,7 @@ static void ipr_reset_ioa_job(struct ipr_cmnd *ipr_cmd) | |||
| 7670 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 7687 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
| 7671 | 7688 | ||
| 7672 | do { | 7689 | do { |
| 7673 | ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); | 7690 | ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); |
| 7674 | 7691 | ||
| 7675 | if (ioa_cfg->reset_cmd != ipr_cmd) { | 7692 | if (ioa_cfg->reset_cmd != ipr_cmd) { |
| 7676 | /* | 7693 | /* |
| @@ -8053,13 +8070,13 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg) | |||
| 8053 | ioarcb->u.sis64_addr_data.data_ioadl_addr = | 8070 | ioarcb->u.sis64_addr_data.data_ioadl_addr = |
| 8054 | cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64)); | 8071 | cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64)); |
| 8055 | ioarcb->u.sis64_addr_data.ioasa_host_pci_addr = | 8072 | ioarcb->u.sis64_addr_data.ioasa_host_pci_addr = |
| 8056 | cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, ioasa)); | 8073 | cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, s.ioasa64)); |
| 8057 | } else { | 8074 | } else { |
| 8058 | ioarcb->write_ioadl_addr = | 8075 | ioarcb->write_ioadl_addr = |
| 8059 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl)); | 8076 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl)); |
| 8060 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; | 8077 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; |
| 8061 | ioarcb->ioasa_host_pci_addr = | 8078 | ioarcb->ioasa_host_pci_addr = |
| 8062 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioasa)); | 8079 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, s.ioasa)); |
| 8063 | } | 8080 | } |
| 8064 | ioarcb->ioasa_len = cpu_to_be16(sizeof(struct ipr_ioasa)); | 8081 | ioarcb->ioasa_len = cpu_to_be16(sizeof(struct ipr_ioasa)); |
| 8065 | ipr_cmd->cmd_index = i; | 8082 | ipr_cmd->cmd_index = i; |
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 4e7f81494ea4..f8a17d88db84 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h | |||
| @@ -614,7 +614,7 @@ struct ipr_auto_sense { | |||
| 614 | __be32 data[SCSI_SENSE_BUFFERSIZE/sizeof(__be32)]; | 614 | __be32 data[SCSI_SENSE_BUFFERSIZE/sizeof(__be32)]; |
| 615 | }; | 615 | }; |
| 616 | 616 | ||
| 617 | struct ipr_ioasa { | 617 | struct ipr_ioasa_hdr { |
| 618 | __be32 ioasc; | 618 | __be32 ioasc; |
| 619 | #define IPR_IOASC_SENSE_KEY(ioasc) ((ioasc) >> 24) | 619 | #define IPR_IOASC_SENSE_KEY(ioasc) ((ioasc) >> 24) |
| 620 | #define IPR_IOASC_SENSE_CODE(ioasc) (((ioasc) & 0x00ff0000) >> 16) | 620 | #define IPR_IOASC_SENSE_CODE(ioasc) (((ioasc) & 0x00ff0000) >> 16) |
| @@ -646,6 +646,25 @@ struct ipr_ioasa { | |||
| 646 | #define IPR_FIELD_POINTER_VALID (0x80000000 >> 8) | 646 | #define IPR_FIELD_POINTER_VALID (0x80000000 >> 8) |
| 647 | #define IPR_FIELD_POINTER_MASK 0x0000ffff | 647 | #define IPR_FIELD_POINTER_MASK 0x0000ffff |
| 648 | 648 | ||
| 649 | }__attribute__((packed, aligned (4))); | ||
| 650 | |||
| 651 | struct ipr_ioasa { | ||
| 652 | struct ipr_ioasa_hdr hdr; | ||
| 653 | |||
| 654 | union { | ||
| 655 | struct ipr_ioasa_vset vset; | ||
| 656 | struct ipr_ioasa_af_dasd dasd; | ||
| 657 | struct ipr_ioasa_gpdd gpdd; | ||
| 658 | struct ipr_ioasa_gata gata; | ||
| 659 | } u; | ||
| 660 | |||
| 661 | struct ipr_auto_sense auto_sense; | ||
| 662 | }__attribute__((packed, aligned (4))); | ||
| 663 | |||
| 664 | struct ipr_ioasa64 { | ||
| 665 | struct ipr_ioasa_hdr hdr; | ||
| 666 | u8 fd_res_path[8]; | ||
| 667 | |||
| 649 | union { | 668 | union { |
| 650 | struct ipr_ioasa_vset vset; | 669 | struct ipr_ioasa_vset vset; |
| 651 | struct ipr_ioasa_af_dasd dasd; | 670 | struct ipr_ioasa_af_dasd dasd; |
| @@ -1465,7 +1484,10 @@ struct ipr_cmnd { | |||
| 1465 | struct ipr_ioadl64_desc ioadl64[IPR_NUM_IOADL_ENTRIES]; | 1484 | struct ipr_ioadl64_desc ioadl64[IPR_NUM_IOADL_ENTRIES]; |
| 1466 | struct ipr_ata64_ioadl ata_ioadl; | 1485 | struct ipr_ata64_ioadl ata_ioadl; |
| 1467 | } i; | 1486 | } i; |
| 1468 | struct ipr_ioasa ioasa; | 1487 | union { |
| 1488 | struct ipr_ioasa ioasa; | ||
| 1489 | struct ipr_ioasa64 ioasa64; | ||
| 1490 | } s; | ||
| 1469 | struct list_head queue; | 1491 | struct list_head queue; |
| 1470 | struct scsi_cmnd *scsi_cmd; | 1492 | struct scsi_cmnd *scsi_cmd; |
| 1471 | struct ata_queued_cmd *qc; | 1493 | struct ata_queued_cmd *qc; |
