aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/pmcraid.c886
-rw-r--r--drivers/scsi/pmcraid.h305
2 files changed, 843 insertions, 348 deletions
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index c44e4ab4e938..9ebcea3643b2 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -113,6 +113,7 @@ static struct pmcraid_chip_details pmcraid_chip_cfg[] = {
113 .global_intr_mask = 0x00034, 113 .global_intr_mask = 0x00034,
114 .ioa_host_intr = 0x0009C, 114 .ioa_host_intr = 0x0009C,
115 .ioa_host_intr_clr = 0x000A0, 115 .ioa_host_intr_clr = 0x000A0,
116 .ioa_host_msix_intr = 0x7FC40,
116 .ioa_host_mask = 0x7FC28, 117 .ioa_host_mask = 0x7FC28,
117 .ioa_host_mask_clr = 0x7FC28, 118 .ioa_host_mask_clr = 0x7FC28,
118 .host_ioa_intr = 0x00020, 119 .host_ioa_intr = 0x00020,
@@ -154,8 +155,12 @@ static int pmcraid_slave_alloc(struct scsi_device *scsi_dev)
154 u8 target, bus, lun; 155 u8 target, bus, lun;
155 unsigned long lock_flags; 156 unsigned long lock_flags;
156 int rc = -ENXIO; 157 int rc = -ENXIO;
158 u16 fw_version;
159
157 pinstance = shost_priv(scsi_dev->host); 160 pinstance = shost_priv(scsi_dev->host);
158 161
162 fw_version = be16_to_cpu(pinstance->inq_data->fw_version);
163
159 /* Driver exposes VSET and GSCSI resources only; all other device types 164 /* Driver exposes VSET and GSCSI resources only; all other device types
160 * are not exposed. Resource list is synchronized using resource lock 165 * are not exposed. Resource list is synchronized using resource lock
161 * so any traversal or modifications to the list should be done inside 166 * so any traversal or modifications to the list should be done inside
@@ -166,7 +171,11 @@ static int pmcraid_slave_alloc(struct scsi_device *scsi_dev)
166 171
167 /* do not expose VSETs with order-ids > MAX_VSET_TARGETS */ 172 /* do not expose VSETs with order-ids > MAX_VSET_TARGETS */
168 if (RES_IS_VSET(temp->cfg_entry)) { 173 if (RES_IS_VSET(temp->cfg_entry)) {
169 target = temp->cfg_entry.unique_flags1; 174 if (fw_version <= PMCRAID_FW_VERSION_1)
175 target = temp->cfg_entry.unique_flags1;
176 else
177 target = temp->cfg_entry.array_id & 0xFF;
178
170 if (target > PMCRAID_MAX_VSET_TARGETS) 179 if (target > PMCRAID_MAX_VSET_TARGETS)
171 continue; 180 continue;
172 bus = PMCRAID_VSET_BUS_ID; 181 bus = PMCRAID_VSET_BUS_ID;
@@ -283,7 +292,7 @@ static void pmcraid_slave_destroy(struct scsi_device *scsi_dev)
283 * @reason: calling context 292 * @reason: calling context
284 * 293 *
285 * Return value 294 * Return value
286 * actual depth set 295 * actual depth set
287 */ 296 */
288static int pmcraid_change_queue_depth(struct scsi_device *scsi_dev, int depth, 297static int pmcraid_change_queue_depth(struct scsi_device *scsi_dev, int depth,
289 int reason) 298 int reason)
@@ -305,7 +314,7 @@ static int pmcraid_change_queue_depth(struct scsi_device *scsi_dev, int depth,
305 * @tag: type of tags to use 314 * @tag: type of tags to use
306 * 315 *
307 * Return value: 316 * Return value:
308 * actual queue type set 317 * actual queue type set
309 */ 318 */
310static int pmcraid_change_queue_type(struct scsi_device *scsi_dev, int tag) 319static int pmcraid_change_queue_type(struct scsi_device *scsi_dev, int tag)
311{ 320{
@@ -357,6 +366,7 @@ void pmcraid_init_cmdblk(struct pmcraid_cmd *cmd, int index)
357 * processed by IOA 366 * processed by IOA
358 */ 367 */
359 memset(&cmd->ioa_cb->ioarcb.cdb, 0, PMCRAID_MAX_CDB_LEN); 368 memset(&cmd->ioa_cb->ioarcb.cdb, 0, PMCRAID_MAX_CDB_LEN);
369 ioarcb->hrrq_id = 0;
360 ioarcb->request_flags0 = 0; 370 ioarcb->request_flags0 = 0;
361 ioarcb->request_flags1 = 0; 371 ioarcb->request_flags1 = 0;
362 ioarcb->cmd_timeout = 0; 372 ioarcb->cmd_timeout = 0;
@@ -368,13 +378,15 @@ void pmcraid_init_cmdblk(struct pmcraid_cmd *cmd, int index)
368 ioarcb->add_cmd_param_offset = 0; 378 ioarcb->add_cmd_param_offset = 0;
369 cmd->ioa_cb->ioasa.ioasc = 0; 379 cmd->ioa_cb->ioasa.ioasc = 0;
370 cmd->ioa_cb->ioasa.residual_data_length = 0; 380 cmd->ioa_cb->ioasa.residual_data_length = 0;
371 cmd->u.time_left = 0; 381 cmd->time_left = 0;
372 } 382 }
373 383
374 cmd->cmd_done = NULL; 384 cmd->cmd_done = NULL;
375 cmd->scsi_cmd = NULL; 385 cmd->scsi_cmd = NULL;
376 cmd->release = 0; 386 cmd->release = 0;
377 cmd->completion_req = 0; 387 cmd->completion_req = 0;
388 cmd->sense_buffer = 0;
389 cmd->sense_buffer_dma = 0;
378 cmd->dma_handle = 0; 390 cmd->dma_handle = 0;
379 init_timer(&cmd->timer); 391 init_timer(&cmd->timer);
380} 392}
@@ -449,7 +461,9 @@ void pmcraid_return_cmd(struct pmcraid_cmd *cmd)
449 */ 461 */
450static u32 pmcraid_read_interrupts(struct pmcraid_instance *pinstance) 462static u32 pmcraid_read_interrupts(struct pmcraid_instance *pinstance)
451{ 463{
452 return ioread32(pinstance->int_regs.ioa_host_interrupt_reg); 464 return (pinstance->interrupt_mode) ?
465 ioread32(pinstance->int_regs.ioa_host_msix_interrupt_reg) :
466 ioread32(pinstance->int_regs.ioa_host_interrupt_reg);
453} 467}
454 468
455/** 469/**
@@ -469,10 +483,15 @@ static void pmcraid_disable_interrupts(
469 u32 gmask = ioread32(pinstance->int_regs.global_interrupt_mask_reg); 483 u32 gmask = ioread32(pinstance->int_regs.global_interrupt_mask_reg);
470 u32 nmask = gmask | GLOBAL_INTERRUPT_MASK; 484 u32 nmask = gmask | GLOBAL_INTERRUPT_MASK;
471 485
472 iowrite32(nmask, pinstance->int_regs.global_interrupt_mask_reg);
473 iowrite32(intrs, pinstance->int_regs.ioa_host_interrupt_clr_reg); 486 iowrite32(intrs, pinstance->int_regs.ioa_host_interrupt_clr_reg);
474 iowrite32(intrs, pinstance->int_regs.ioa_host_interrupt_mask_reg); 487 iowrite32(nmask, pinstance->int_regs.global_interrupt_mask_reg);
475 ioread32(pinstance->int_regs.ioa_host_interrupt_mask_reg); 488 ioread32(pinstance->int_regs.global_interrupt_mask_reg);
489
490 if (!pinstance->interrupt_mode) {
491 iowrite32(intrs,
492 pinstance->int_regs.ioa_host_interrupt_mask_reg);
493 ioread32(pinstance->int_regs.ioa_host_interrupt_mask_reg);
494 }
476} 495}
477 496
478/** 497/**
@@ -493,8 +512,12 @@ static void pmcraid_enable_interrupts(
493 u32 nmask = gmask & (~GLOBAL_INTERRUPT_MASK); 512 u32 nmask = gmask & (~GLOBAL_INTERRUPT_MASK);
494 513
495 iowrite32(nmask, pinstance->int_regs.global_interrupt_mask_reg); 514 iowrite32(nmask, pinstance->int_regs.global_interrupt_mask_reg);
496 iowrite32(~intrs, pinstance->int_regs.ioa_host_interrupt_mask_reg); 515
497 ioread32(pinstance->int_regs.ioa_host_interrupt_mask_reg); 516 if (!pinstance->interrupt_mode) {
517 iowrite32(~intrs,
518 pinstance->int_regs.ioa_host_interrupt_mask_reg);
519 ioread32(pinstance->int_regs.ioa_host_interrupt_mask_reg);
520 }
498 521
499 pmcraid_info("enabled interrupts global mask = %x intr_mask = %x\n", 522 pmcraid_info("enabled interrupts global mask = %x intr_mask = %x\n",
500 ioread32(pinstance->int_regs.global_interrupt_mask_reg), 523 ioread32(pinstance->int_regs.global_interrupt_mask_reg),
@@ -502,6 +525,39 @@ static void pmcraid_enable_interrupts(
502} 525}
503 526
504/** 527/**
528 * pmcraid_clr_trans_op - clear trans to op interrupt
529 *
530 * @pinstance: pointer to per adapter instance structure
531 *
532 * Return Value
533 * None
534 */
535static void pmcraid_clr_trans_op(
536 struct pmcraid_instance *pinstance
537)
538{
539 unsigned long lock_flags;
540
541 if (!pinstance->interrupt_mode) {
542 iowrite32(INTRS_TRANSITION_TO_OPERATIONAL,
543 pinstance->int_regs.ioa_host_interrupt_mask_reg);
544 ioread32(pinstance->int_regs.ioa_host_interrupt_mask_reg);
545 iowrite32(INTRS_TRANSITION_TO_OPERATIONAL,
546 pinstance->int_regs.ioa_host_interrupt_clr_reg);
547 ioread32(pinstance->int_regs.ioa_host_interrupt_clr_reg);
548 }
549
550 if (pinstance->reset_cmd != NULL) {
551 del_timer(&pinstance->reset_cmd->timer);
552 spin_lock_irqsave(
553 pinstance->host->host_lock, lock_flags);
554 pinstance->reset_cmd->cmd_done(pinstance->reset_cmd);
555 spin_unlock_irqrestore(
556 pinstance->host->host_lock, lock_flags);
557 }
558}
559
560/**
505 * pmcraid_reset_type - Determine the required reset type 561 * pmcraid_reset_type - Determine the required reset type
506 * @pinstance: pointer to adapter instance structure 562 * @pinstance: pointer to adapter instance structure
507 * 563 *
@@ -536,7 +592,7 @@ static void pmcraid_reset_type(struct pmcraid_instance *pinstance)
536 * pmcraid_bist_done - completion function for PCI BIST 592 * pmcraid_bist_done - completion function for PCI BIST
537 * @cmd: pointer to reset command 593 * @cmd: pointer to reset command
538 * Return Value 594 * Return Value
539 * none 595 * none
540 */ 596 */
541 597
542static void pmcraid_ioa_reset(struct pmcraid_cmd *); 598static void pmcraid_ioa_reset(struct pmcraid_cmd *);
@@ -552,16 +608,16 @@ static void pmcraid_bist_done(struct pmcraid_cmd *cmd)
552 608
553 /* If PCI config space can't be accessed wait for another two secs */ 609 /* If PCI config space can't be accessed wait for another two secs */
554 if ((rc != PCIBIOS_SUCCESSFUL || (!(pci_reg & PCI_COMMAND_MEMORY))) && 610 if ((rc != PCIBIOS_SUCCESSFUL || (!(pci_reg & PCI_COMMAND_MEMORY))) &&
555 cmd->u.time_left > 0) { 611 cmd->time_left > 0) {
556 pmcraid_info("BIST not complete, waiting another 2 secs\n"); 612 pmcraid_info("BIST not complete, waiting another 2 secs\n");
557 cmd->timer.expires = jiffies + cmd->u.time_left; 613 cmd->timer.expires = jiffies + cmd->time_left;
558 cmd->u.time_left = 0; 614 cmd->time_left = 0;
559 cmd->timer.data = (unsigned long)cmd; 615 cmd->timer.data = (unsigned long)cmd;
560 cmd->timer.function = 616 cmd->timer.function =
561 (void (*)(unsigned long))pmcraid_bist_done; 617 (void (*)(unsigned long))pmcraid_bist_done;
562 add_timer(&cmd->timer); 618 add_timer(&cmd->timer);
563 } else { 619 } else {
564 cmd->u.time_left = 0; 620 cmd->time_left = 0;
565 pmcraid_info("BIST is complete, proceeding with reset\n"); 621 pmcraid_info("BIST is complete, proceeding with reset\n");
566 spin_lock_irqsave(pinstance->host->host_lock, lock_flags); 622 spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
567 pmcraid_ioa_reset(cmd); 623 pmcraid_ioa_reset(cmd);
@@ -585,10 +641,10 @@ static void pmcraid_start_bist(struct pmcraid_cmd *cmd)
585 pinstance->int_regs.host_ioa_interrupt_reg); 641 pinstance->int_regs.host_ioa_interrupt_reg);
586 doorbells = ioread32(pinstance->int_regs.host_ioa_interrupt_reg); 642 doorbells = ioread32(pinstance->int_regs.host_ioa_interrupt_reg);
587 intrs = ioread32(pinstance->int_regs.ioa_host_interrupt_reg); 643 intrs = ioread32(pinstance->int_regs.ioa_host_interrupt_reg);
588 pmcraid_info("doorbells after start bist: %x intrs: %x \n", 644 pmcraid_info("doorbells after start bist: %x intrs: %x\n",
589 doorbells, intrs); 645 doorbells, intrs);
590 646
591 cmd->u.time_left = msecs_to_jiffies(PMCRAID_BIST_TIMEOUT); 647 cmd->time_left = msecs_to_jiffies(PMCRAID_BIST_TIMEOUT);
592 cmd->timer.data = (unsigned long)cmd; 648 cmd->timer.data = (unsigned long)cmd;
593 cmd->timer.expires = jiffies + msecs_to_jiffies(PMCRAID_BIST_TIMEOUT); 649 cmd->timer.expires = jiffies + msecs_to_jiffies(PMCRAID_BIST_TIMEOUT);
594 cmd->timer.function = (void (*)(unsigned long))pmcraid_bist_done; 650 cmd->timer.function = (void (*)(unsigned long))pmcraid_bist_done;
@@ -612,7 +668,7 @@ static void pmcraid_reset_alert_done(struct pmcraid_cmd *cmd)
612 * some more time to wait, restart the timer 668 * some more time to wait, restart the timer
613 */ 669 */
614 if (((status & INTRS_CRITICAL_OP_IN_PROGRESS) == 0) || 670 if (((status & INTRS_CRITICAL_OP_IN_PROGRESS) == 0) ||
615 cmd->u.time_left <= 0) { 671 cmd->time_left <= 0) {
616 pmcraid_info("critical op is reset proceeding with reset\n"); 672 pmcraid_info("critical op is reset proceeding with reset\n");
617 spin_lock_irqsave(pinstance->host->host_lock, lock_flags); 673 spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
618 pmcraid_ioa_reset(cmd); 674 pmcraid_ioa_reset(cmd);
@@ -620,7 +676,7 @@ static void pmcraid_reset_alert_done(struct pmcraid_cmd *cmd)
620 } else { 676 } else {
621 pmcraid_info("critical op is not yet reset waiting again\n"); 677 pmcraid_info("critical op is not yet reset waiting again\n");
622 /* restart timer if some more time is available to wait */ 678 /* restart timer if some more time is available to wait */
623 cmd->u.time_left -= PMCRAID_CHECK_FOR_RESET_TIMEOUT; 679 cmd->time_left -= PMCRAID_CHECK_FOR_RESET_TIMEOUT;
624 cmd->timer.data = (unsigned long)cmd; 680 cmd->timer.data = (unsigned long)cmd;
625 cmd->timer.expires = jiffies + PMCRAID_CHECK_FOR_RESET_TIMEOUT; 681 cmd->timer.expires = jiffies + PMCRAID_CHECK_FOR_RESET_TIMEOUT;
626 cmd->timer.function = 682 cmd->timer.function =
@@ -638,6 +694,7 @@ static void pmcraid_reset_alert_done(struct pmcraid_cmd *cmd)
638 * successfully written to IOA. Returns non-zero in case pci_config_space 694 * successfully written to IOA. Returns non-zero in case pci_config_space
639 * is not accessible 695 * is not accessible
640 */ 696 */
697static void pmcraid_notify_ioastate(struct pmcraid_instance *, u32);
641static void pmcraid_reset_alert(struct pmcraid_cmd *cmd) 698static void pmcraid_reset_alert(struct pmcraid_cmd *cmd)
642{ 699{
643 struct pmcraid_instance *pinstance = cmd->drv_inst; 700 struct pmcraid_instance *pinstance = cmd->drv_inst;
@@ -658,7 +715,7 @@ static void pmcraid_reset_alert(struct pmcraid_cmd *cmd)
658 * OPERATION bit is reset. A timer is started to wait for this 715 * OPERATION bit is reset. A timer is started to wait for this
659 * bit to be reset. 716 * bit to be reset.
660 */ 717 */
661 cmd->u.time_left = PMCRAID_RESET_TIMEOUT; 718 cmd->time_left = PMCRAID_RESET_TIMEOUT;
662 cmd->timer.data = (unsigned long)cmd; 719 cmd->timer.data = (unsigned long)cmd;
663 cmd->timer.expires = jiffies + PMCRAID_CHECK_FOR_RESET_TIMEOUT; 720 cmd->timer.expires = jiffies + PMCRAID_CHECK_FOR_RESET_TIMEOUT;
664 cmd->timer.function = 721 cmd->timer.function =
@@ -693,7 +750,8 @@ static void pmcraid_timeout_handler(struct pmcraid_cmd *cmd)
693 unsigned long lock_flags; 750 unsigned long lock_flags;
694 751
695 dev_info(&pinstance->pdev->dev, 752 dev_info(&pinstance->pdev->dev,
696 "Adapter being reset due to command timeout.\n"); 753 "Adapter being reset due to cmd(CDB[0] = %x) timeout\n",
754 cmd->ioa_cb->ioarcb.cdb[0]);
697 755
698 /* Command timeouts result in hard reset sequence. The command that got 756 /* Command timeouts result in hard reset sequence. The command that got
699 * timed out may be the one used as part of reset sequence. In this 757 * timed out may be the one used as part of reset sequence. In this
@@ -736,9 +794,14 @@ static void pmcraid_timeout_handler(struct pmcraid_cmd *cmd)
736 */ 794 */
737 if (cmd == pinstance->reset_cmd) 795 if (cmd == pinstance->reset_cmd)
738 cmd->cmd_done = pmcraid_ioa_reset; 796 cmd->cmd_done = pmcraid_ioa_reset;
739
740 } 797 }
741 798
799 /* Notify apps of important IOA bringup/bringdown sequences */
800 if (pinstance->scn.ioa_state != PMC_DEVICE_EVENT_RESET_START &&
801 pinstance->scn.ioa_state != PMC_DEVICE_EVENT_SHUTDOWN_START)
802 pmcraid_notify_ioastate(pinstance,
803 PMC_DEVICE_EVENT_RESET_START);
804
742 pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT; 805 pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT;
743 scsi_block_requests(pinstance->host); 806 scsi_block_requests(pinstance->host);
744 pmcraid_reset_alert(cmd); 807 pmcraid_reset_alert(cmd);
@@ -866,7 +929,7 @@ static void _pmcraid_fire_command(struct pmcraid_cmd *cmd)
866 /* Add this command block to pending cmd pool. We do this prior to 929 /* Add this command block to pending cmd pool. We do this prior to
867 * writting IOARCB to ioarrin because IOA might complete the command 930 * writting IOARCB to ioarrin because IOA might complete the command
868 * by the time we are about to add it to the list. Response handler 931 * by the time we are about to add it to the list. Response handler
869 * (isr/tasklet) looks for cmb block in the pending pending list. 932 * (isr/tasklet) looks for cmd block in the pending pending list.
870 */ 933 */
871 spin_lock_irqsave(&pinstance->pending_pool_lock, lock_flags); 934 spin_lock_irqsave(&pinstance->pending_pool_lock, lock_flags);
872 list_add_tail(&cmd->free_list, &pinstance->pending_cmd_pool); 935 list_add_tail(&cmd->free_list, &pinstance->pending_cmd_pool);
@@ -916,6 +979,23 @@ static void pmcraid_send_cmd(
916} 979}
917 980
918/** 981/**
982 * pmcraid_ioa_shutdown_done - completion function for IOA shutdown command
983 * @cmd: pointer to the command block used for sending IOA shutdown command
984 *
985 * Return value
986 * None
987 */
988static void pmcraid_ioa_shutdown_done(struct pmcraid_cmd *cmd)
989{
990 struct pmcraid_instance *pinstance = cmd->drv_inst;
991 unsigned long lock_flags;
992
993 spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
994 pmcraid_ioa_reset(cmd);
995 spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
996}
997
998/**
919 * pmcraid_ioa_shutdown - sends SHUTDOWN command to ioa 999 * pmcraid_ioa_shutdown - sends SHUTDOWN command to ioa
920 * 1000 *
921 * @cmd: pointer to the command block used as part of reset sequence 1001 * @cmd: pointer to the command block used as part of reset sequence
@@ -943,30 +1023,112 @@ static void pmcraid_ioa_shutdown(struct pmcraid_cmd *cmd)
943 pmcraid_info("firing normal shutdown command (%d) to IOA\n", 1023 pmcraid_info("firing normal shutdown command (%d) to IOA\n",
944 le32_to_cpu(cmd->ioa_cb->ioarcb.response_handle)); 1024 le32_to_cpu(cmd->ioa_cb->ioarcb.response_handle));
945 1025
946 pmcraid_send_cmd(cmd, pmcraid_ioa_reset, 1026 pmcraid_notify_ioastate(cmd->drv_inst, PMC_DEVICE_EVENT_SHUTDOWN_START);
1027
1028 pmcraid_send_cmd(cmd, pmcraid_ioa_shutdown_done,
947 PMCRAID_SHUTDOWN_TIMEOUT, 1029 PMCRAID_SHUTDOWN_TIMEOUT,
948 pmcraid_timeout_handler); 1030 pmcraid_timeout_handler);
949} 1031}
950 1032
951/** 1033/**
952 * pmcraid_identify_hrrq - registers host rrq buffers with IOA 1034 * pmcraid_get_fwversion_done - completion function for get_fwversion
953 * @cmd: pointer to command block to be used for identify hrrq 1035 *
1036 * @cmd: pointer to command block used to send INQUIRY command
954 * 1037 *
955 * Return Value 1038 * Return Value
956 * 0 in case of success, otherwise non-zero failure code 1039 * none
957 */ 1040 */
958
959static void pmcraid_querycfg(struct pmcraid_cmd *); 1041static void pmcraid_querycfg(struct pmcraid_cmd *);
960 1042
1043static void pmcraid_get_fwversion_done(struct pmcraid_cmd *cmd)
1044{
1045 struct pmcraid_instance *pinstance = cmd->drv_inst;
1046 u32 ioasc = le32_to_cpu(cmd->ioa_cb->ioasa.ioasc);
1047 unsigned long lock_flags;
1048
1049 /* configuration table entry size depends on firmware version. If fw
1050 * version is not known, it is not possible to interpret IOA config
1051 * table
1052 */
1053 if (ioasc) {
1054 pmcraid_err("IOA Inquiry failed with %x\n", ioasc);
1055 spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
1056 pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT;
1057 pmcraid_reset_alert(cmd);
1058 spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
1059 } else {
1060 pmcraid_querycfg(cmd);
1061 }
1062}
1063
1064/**
1065 * pmcraid_get_fwversion - reads firmware version information
1066 *
1067 * @cmd: pointer to command block used to send INQUIRY command
1068 *
1069 * Return Value
1070 * none
1071 */
1072static void pmcraid_get_fwversion(struct pmcraid_cmd *cmd)
1073{
1074 struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
1075 struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl;
1076 struct pmcraid_instance *pinstance = cmd->drv_inst;
1077 u16 data_size = sizeof(struct pmcraid_inquiry_data);
1078
1079 pmcraid_reinit_cmdblk(cmd);
1080 ioarcb->request_type = REQ_TYPE_SCSI;
1081 ioarcb->resource_handle = cpu_to_le32(PMCRAID_IOA_RES_HANDLE);
1082 ioarcb->cdb[0] = INQUIRY;
1083 ioarcb->cdb[1] = 1;
1084 ioarcb->cdb[2] = 0xD0;
1085 ioarcb->cdb[3] = (data_size >> 8) & 0xFF;
1086 ioarcb->cdb[4] = data_size & 0xFF;
1087
1088 /* Since entire inquiry data it can be part of IOARCB itself
1089 */
1090 ioarcb->ioadl_bus_addr = cpu_to_le64((cmd->ioa_cb_bus_addr) +
1091 offsetof(struct pmcraid_ioarcb,
1092 add_data.u.ioadl[0]));
1093 ioarcb->ioadl_length = cpu_to_le32(sizeof(struct pmcraid_ioadl_desc));
1094 ioarcb->ioarcb_bus_addr &= ~(0x1FULL);
1095
1096 ioarcb->request_flags0 |= NO_LINK_DESCS;
1097 ioarcb->data_transfer_length = cpu_to_le32(data_size);
1098 ioadl = &(ioarcb->add_data.u.ioadl[0]);
1099 ioadl->flags = IOADL_FLAGS_LAST_DESC;
1100 ioadl->address = cpu_to_le64(pinstance->inq_data_baddr);
1101 ioadl->data_len = cpu_to_le32(data_size);
1102
1103 pmcraid_send_cmd(cmd, pmcraid_get_fwversion_done,
1104 PMCRAID_INTERNAL_TIMEOUT, pmcraid_timeout_handler);
1105}
1106
1107/**
1108 * pmcraid_identify_hrrq - registers host rrq buffers with IOA
1109 * @cmd: pointer to command block to be used for identify hrrq
1110 *
1111 * Return Value
1112 * none
1113 */
961static void pmcraid_identify_hrrq(struct pmcraid_cmd *cmd) 1114static void pmcraid_identify_hrrq(struct pmcraid_cmd *cmd)
962{ 1115{
963 struct pmcraid_instance *pinstance = cmd->drv_inst; 1116 struct pmcraid_instance *pinstance = cmd->drv_inst;
964 struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb; 1117 struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
965 int index = 0; 1118 int index = cmd->hrrq_index;
966 __be64 hrrq_addr = cpu_to_be64(pinstance->hrrq_start_bus_addr[index]); 1119 __be64 hrrq_addr = cpu_to_be64(pinstance->hrrq_start_bus_addr[index]);
967 u32 hrrq_size = cpu_to_be32(sizeof(u32) * PMCRAID_MAX_CMD); 1120 u32 hrrq_size = cpu_to_be32(sizeof(u32) * PMCRAID_MAX_CMD);
1121 void (*done_function)(struct pmcraid_cmd *);
968 1122
969 pmcraid_reinit_cmdblk(cmd); 1123 pmcraid_reinit_cmdblk(cmd);
1124 cmd->hrrq_index = index + 1;
1125
1126 if (cmd->hrrq_index < pinstance->num_hrrq) {
1127 done_function = pmcraid_identify_hrrq;
1128 } else {
1129 cmd->hrrq_index = 0;
1130 done_function = pmcraid_get_fwversion;
1131 }
970 1132
971 /* Initialize ioarcb */ 1133 /* Initialize ioarcb */
972 ioarcb->request_type = REQ_TYPE_IOACMD; 1134 ioarcb->request_type = REQ_TYPE_IOACMD;
@@ -980,8 +1142,8 @@ static void pmcraid_identify_hrrq(struct pmcraid_cmd *cmd)
980 /* IOA expects 64-bit pci address to be written in B.E format 1142 /* IOA expects 64-bit pci address to be written in B.E format
981 * (i.e cdb[2]=MSByte..cdb[9]=LSB. 1143 * (i.e cdb[2]=MSByte..cdb[9]=LSB.
982 */ 1144 */
983 pmcraid_info("HRRQ_IDENTIFY with hrrq:ioarcb => %llx:%llx\n", 1145 pmcraid_info("HRRQ_IDENTIFY with hrrq:ioarcb:index => %llx:%llx:%x\n",
984 hrrq_addr, ioarcb->ioarcb_bus_addr); 1146 hrrq_addr, ioarcb->ioarcb_bus_addr, index);
985 1147
986 memcpy(&(ioarcb->cdb[2]), &hrrq_addr, sizeof(hrrq_addr)); 1148 memcpy(&(ioarcb->cdb[2]), &hrrq_addr, sizeof(hrrq_addr));
987 memcpy(&(ioarcb->cdb[10]), &hrrq_size, sizeof(hrrq_size)); 1149 memcpy(&(ioarcb->cdb[10]), &hrrq_size, sizeof(hrrq_size));
@@ -990,7 +1152,7 @@ static void pmcraid_identify_hrrq(struct pmcraid_cmd *cmd)
990 * Note that this gets called even during reset from SCSI mid-layer 1152 * Note that this gets called even during reset from SCSI mid-layer
991 * or tasklet 1153 * or tasklet
992 */ 1154 */
993 pmcraid_send_cmd(cmd, pmcraid_querycfg, 1155 pmcraid_send_cmd(cmd, done_function,
994 PMCRAID_INTERNAL_TIMEOUT, 1156 PMCRAID_INTERNAL_TIMEOUT,
995 pmcraid_timeout_handler); 1157 pmcraid_timeout_handler);
996} 1158}
@@ -1047,7 +1209,7 @@ static struct pmcraid_cmd *pmcraid_init_hcam
1047 } 1209 }
1048 1210
1049 if (type == PMCRAID_HCAM_CODE_CONFIG_CHANGE) { 1211 if (type == PMCRAID_HCAM_CODE_CONFIG_CHANGE) {
1050 rcb_size = sizeof(struct pmcraid_hcam_ccn); 1212 rcb_size = sizeof(struct pmcraid_hcam_ccn_ext);
1051 cmd_done = pmcraid_process_ccn; 1213 cmd_done = pmcraid_process_ccn;
1052 dma = pinstance->ccn.baddr + PMCRAID_AEN_HDR_SIZE; 1214 dma = pinstance->ccn.baddr + PMCRAID_AEN_HDR_SIZE;
1053 hcam = &pinstance->ccn; 1215 hcam = &pinstance->ccn;
@@ -1094,7 +1256,7 @@ static struct pmcraid_cmd *pmcraid_init_hcam
1094 * This function will send a Host Controlled Async command to IOA. 1256 * This function will send a Host Controlled Async command to IOA.
1095 * 1257 *
1096 * Return value: 1258 * Return value:
1097 * none 1259 * none
1098 */ 1260 */
1099static void pmcraid_send_hcam(struct pmcraid_instance *pinstance, u8 type) 1261static void pmcraid_send_hcam(struct pmcraid_instance *pinstance, u8 type)
1100{ 1262{
@@ -1202,18 +1364,25 @@ static void pmcraid_cancel_ldn(struct pmcraid_cmd *cmd)
1202/** 1364/**
1203 * pmcraid_expose_resource - check if the resource can be exposed to OS 1365 * pmcraid_expose_resource - check if the resource can be exposed to OS
1204 * 1366 *
1367 * @fw_version: firmware version code
1205 * @cfgte: pointer to configuration table entry of the resource 1368 * @cfgte: pointer to configuration table entry of the resource
1206 * 1369 *
1207 * Return value: 1370 * Return value:
1208 * true if resource can be added to midlayer, false(0) otherwise 1371 * true if resource can be added to midlayer, false(0) otherwise
1209 */ 1372 */
1210static int pmcraid_expose_resource(struct pmcraid_config_table_entry *cfgte) 1373static int pmcraid_expose_resource(u16 fw_version,
1374 struct pmcraid_config_table_entry *cfgte)
1211{ 1375{
1212 int retval = 0; 1376 int retval = 0;
1213 1377
1214 if (cfgte->resource_type == RES_TYPE_VSET) 1378 if (cfgte->resource_type == RES_TYPE_VSET) {
1215 retval = ((cfgte->unique_flags1 & 0x80) == 0); 1379 if (fw_version <= PMCRAID_FW_VERSION_1)
1216 else if (cfgte->resource_type == RES_TYPE_GSCSI) 1380 retval = ((cfgte->unique_flags1 & 0x80) == 0);
1381 else
1382 retval = ((cfgte->unique_flags0 & 0x80) == 0 &&
1383 (cfgte->unique_flags1 & 0x80) == 0);
1384
1385 } else if (cfgte->resource_type == RES_TYPE_GSCSI)
1217 retval = (RES_BUS(cfgte->resource_address) != 1386 retval = (RES_BUS(cfgte->resource_address) !=
1218 PMCRAID_VIRTUAL_ENCL_BUS_ID); 1387 PMCRAID_VIRTUAL_ENCL_BUS_ID);
1219 return retval; 1388 return retval;
@@ -1246,8 +1415,8 @@ static struct genl_family pmcraid_event_family = {
1246 * pmcraid_netlink_init - registers pmcraid_event_family 1415 * pmcraid_netlink_init - registers pmcraid_event_family
1247 * 1416 *
1248 * Return value: 1417 * Return value:
1249 * 0 if the pmcraid_event_family is successfully registered 1418 * 0 if the pmcraid_event_family is successfully registered
1250 * with netlink generic, non-zero otherwise 1419 * with netlink generic, non-zero otherwise
1251 */ 1420 */
1252static int pmcraid_netlink_init(void) 1421static int pmcraid_netlink_init(void)
1253{ 1422{
@@ -1268,7 +1437,7 @@ static int pmcraid_netlink_init(void)
1268 * pmcraid_netlink_release - unregisters pmcraid_event_family 1437 * pmcraid_netlink_release - unregisters pmcraid_event_family
1269 * 1438 *
1270 * Return value: 1439 * Return value:
1271 * none 1440 * none
1272 */ 1441 */
1273static void pmcraid_netlink_release(void) 1442static void pmcraid_netlink_release(void)
1274{ 1443{
@@ -1283,31 +1452,30 @@ static void pmcraid_netlink_release(void)
1283 * Return value: 1452 * Return value:
1284 * 0 if success, error value in case of any failure. 1453 * 0 if success, error value in case of any failure.
1285 */ 1454 */
1286static int pmcraid_notify_aen(struct pmcraid_instance *pinstance, u8 type) 1455static int pmcraid_notify_aen(
1456 struct pmcraid_instance *pinstance,
1457 struct pmcraid_aen_msg *aen_msg,
1458 u32 data_size
1459)
1287{ 1460{
1288 struct sk_buff *skb; 1461 struct sk_buff *skb;
1289 struct pmcraid_aen_msg *aen_msg;
1290 void *msg_header; 1462 void *msg_header;
1291 int data_size, total_size; 1463 u32 total_size, nla_genl_hdr_total_size;
1292 int result; 1464 int result;
1293 1465
1294
1295 if (type == PMCRAID_HCAM_CODE_LOG_DATA) {
1296 aen_msg = pinstance->ldn.msg;
1297 data_size = pinstance->ldn.hcam->data_len;
1298 } else {
1299 aen_msg = pinstance->ccn.msg;
1300 data_size = pinstance->ccn.hcam->data_len;
1301 }
1302
1303 data_size += sizeof(struct pmcraid_hcam_hdr);
1304 aen_msg->hostno = (pinstance->host->unique_id << 16 | 1466 aen_msg->hostno = (pinstance->host->unique_id << 16 |
1305 MINOR(pinstance->cdev.dev)); 1467 MINOR(pinstance->cdev.dev));
1306 aen_msg->length = data_size; 1468 aen_msg->length = data_size;
1469
1307 data_size += sizeof(*aen_msg); 1470 data_size += sizeof(*aen_msg);
1308 1471
1309 total_size = nla_total_size(data_size); 1472 total_size = nla_total_size(data_size);
1310 skb = genlmsg_new(total_size, GFP_ATOMIC); 1473 /* Add GENL_HDR to total_size */
1474 nla_genl_hdr_total_size =
1475 (total_size + (GENL_HDRLEN +
1476 ((struct genl_family *)&pmcraid_event_family)->hdrsize)
1477 + NLMSG_HDRLEN);
1478 skb = genlmsg_new(nla_genl_hdr_total_size, GFP_ATOMIC);
1311 1479
1312 1480
1313 if (!skb) { 1481 if (!skb) {
@@ -1329,7 +1497,7 @@ static int pmcraid_notify_aen(struct pmcraid_instance *pinstance, u8 type)
1329 result = nla_put(skb, PMCRAID_AEN_ATTR_EVENT, data_size, aen_msg); 1497 result = nla_put(skb, PMCRAID_AEN_ATTR_EVENT, data_size, aen_msg);
1330 1498
1331 if (result) { 1499 if (result) {
1332 pmcraid_err("failed to copy AEN attribute data \n"); 1500 pmcraid_err("failed to copy AEN attribute data\n");
1333 nlmsg_free(skb); 1501 nlmsg_free(skb);
1334 return -EINVAL; 1502 return -EINVAL;
1335 } 1503 }
@@ -1350,13 +1518,57 @@ static int pmcraid_notify_aen(struct pmcraid_instance *pinstance, u8 type)
1350 * value. 1518 * value.
1351 */ 1519 */
1352 if (result) 1520 if (result)
1353 pmcraid_info("failed to send %s event message %x!\n", 1521 pmcraid_info("error (%x) sending aen event message\n", result);
1354 type == PMCRAID_HCAM_CODE_LOG_DATA ? "LDN" : "CCN",
1355 result);
1356 return result; 1522 return result;
1357} 1523}
1358 1524
1359/** 1525/**
1526 * pmcraid_notify_ccn - notifies about CCN event msg to user space
1527 * @pinstance: pointer adapter instance structure
1528 *
1529 * Return value:
1530 * 0 if success, error value in case of any failure
1531 */
1532static int pmcraid_notify_ccn(struct pmcraid_instance *pinstance)
1533{
1534 return pmcraid_notify_aen(pinstance,
1535 pinstance->ccn.msg,
1536 pinstance->ccn.hcam->data_len +
1537 sizeof(struct pmcraid_hcam_hdr));
1538}
1539
1540/**
1541 * pmcraid_notify_ldn - notifies about CCN event msg to user space
1542 * @pinstance: pointer adapter instance structure
1543 *
1544 * Return value:
1545 * 0 if success, error value in case of any failure
1546 */
1547static int pmcraid_notify_ldn(struct pmcraid_instance *pinstance)
1548{
1549 return pmcraid_notify_aen(pinstance,
1550 pinstance->ldn.msg,
1551 pinstance->ldn.hcam->data_len +
1552 sizeof(struct pmcraid_hcam_hdr));
1553}
1554
1555/**
1556 * pmcraid_notify_ioastate - sends IOA state event msg to user space
1557 * @pinstance: pointer adapter instance structure
1558 * @evt: controller state event to be sent
1559 *
1560 * Return value:
1561 * 0 if success, error value in case of any failure
1562 */
1563static void pmcraid_notify_ioastate(struct pmcraid_instance *pinstance, u32 evt)
1564{
1565 pinstance->scn.ioa_state = evt;
1566 pmcraid_notify_aen(pinstance,
1567 &pinstance->scn.msg,
1568 sizeof(u32));
1569}
1570
1571/**
1360 * pmcraid_handle_config_change - Handle a config change from the adapter 1572 * pmcraid_handle_config_change - Handle a config change from the adapter
1361 * @pinstance: pointer to per adapter instance structure 1573 * @pinstance: pointer to per adapter instance structure
1362 * 1574 *
@@ -1375,10 +1587,12 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance)
1375 unsigned long host_lock_flags; 1587 unsigned long host_lock_flags;
1376 u32 new_entry = 1; 1588 u32 new_entry = 1;
1377 u32 hidden_entry = 0; 1589 u32 hidden_entry = 0;
1590 u16 fw_version;
1378 int rc; 1591 int rc;
1379 1592
1380 ccn_hcam = (struct pmcraid_hcam_ccn *)pinstance->ccn.hcam; 1593 ccn_hcam = (struct pmcraid_hcam_ccn *)pinstance->ccn.hcam;
1381 cfg_entry = &ccn_hcam->cfg_entry; 1594 cfg_entry = &ccn_hcam->cfg_entry;
1595 fw_version = be16_to_cpu(pinstance->inq_data->fw_version);
1382 1596
1383 pmcraid_info 1597 pmcraid_info
1384 ("CCN(%x): %x type: %x lost: %x flags: %x res: %x:%x:%x:%x\n", 1598 ("CCN(%x): %x type: %x lost: %x flags: %x res: %x:%x:%x:%x\n",
@@ -1391,7 +1605,10 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance)
1391 RES_IS_VSET(*cfg_entry) ? PMCRAID_VSET_BUS_ID : 1605 RES_IS_VSET(*cfg_entry) ? PMCRAID_VSET_BUS_ID :
1392 (RES_IS_GSCSI(*cfg_entry) ? PMCRAID_PHYS_BUS_ID : 1606 (RES_IS_GSCSI(*cfg_entry) ? PMCRAID_PHYS_BUS_ID :
1393 RES_BUS(cfg_entry->resource_address)), 1607 RES_BUS(cfg_entry->resource_address)),
1394 RES_IS_VSET(*cfg_entry) ? cfg_entry->unique_flags1 : 1608 RES_IS_VSET(*cfg_entry) ?
1609 (fw_version <= PMCRAID_FW_VERSION_1 ?
1610 cfg_entry->unique_flags1 :
1611 cfg_entry->array_id & 0xFF) :
1395 RES_TARGET(cfg_entry->resource_address), 1612 RES_TARGET(cfg_entry->resource_address),
1396 RES_LUN(cfg_entry->resource_address)); 1613 RES_LUN(cfg_entry->resource_address));
1397 1614
@@ -1415,11 +1632,16 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance)
1415 */ 1632 */
1416 if (pinstance->ccn.hcam->notification_type == 1633 if (pinstance->ccn.hcam->notification_type ==
1417 NOTIFICATION_TYPE_ENTRY_CHANGED && 1634 NOTIFICATION_TYPE_ENTRY_CHANGED &&
1418 cfg_entry->resource_type == RES_TYPE_VSET && 1635 cfg_entry->resource_type == RES_TYPE_VSET) {
1419 cfg_entry->unique_flags1 & 0x80) { 1636
1420 hidden_entry = 1; 1637 if (fw_version <= PMCRAID_FW_VERSION_1)
1421 } else if (!pmcraid_expose_resource(cfg_entry)) 1638 hidden_entry = (cfg_entry->unique_flags1 & 0x80) != 0;
1639 else
1640 hidden_entry = (cfg_entry->unique_flags1 & 0x80) != 0;
1641
1642 } else if (!pmcraid_expose_resource(fw_version, cfg_entry)) {
1422 goto out_notify_apps; 1643 goto out_notify_apps;
1644 }
1423 1645
1424 spin_lock_irqsave(&pinstance->resource_lock, lock_flags); 1646 spin_lock_irqsave(&pinstance->resource_lock, lock_flags);
1425 list_for_each_entry(res, &pinstance->used_res_q, queue) { 1647 list_for_each_entry(res, &pinstance->used_res_q, queue) {
@@ -1466,13 +1688,15 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance)
1466 list_add_tail(&res->queue, &pinstance->used_res_q); 1688 list_add_tail(&res->queue, &pinstance->used_res_q);
1467 } 1689 }
1468 1690
1469 memcpy(&res->cfg_entry, cfg_entry, 1691 memcpy(&res->cfg_entry, cfg_entry, pinstance->config_table_entry_size);
1470 sizeof(struct pmcraid_config_table_entry));
1471 1692
1472 if (pinstance->ccn.hcam->notification_type == 1693 if (pinstance->ccn.hcam->notification_type ==
1473 NOTIFICATION_TYPE_ENTRY_DELETED || hidden_entry) { 1694 NOTIFICATION_TYPE_ENTRY_DELETED || hidden_entry) {
1474 if (res->scsi_dev) { 1695 if (res->scsi_dev) {
1475 res->cfg_entry.unique_flags1 &= 0x7F; 1696 if (fw_version <= PMCRAID_FW_VERSION_1)
1697 res->cfg_entry.unique_flags1 &= 0x7F;
1698 else
1699 res->cfg_entry.array_id &= 0xFF;
1476 res->change_detected = RES_CHANGE_DEL; 1700 res->change_detected = RES_CHANGE_DEL;
1477 res->cfg_entry.resource_handle = 1701 res->cfg_entry.resource_handle =
1478 PMCRAID_INVALID_RES_HANDLE; 1702 PMCRAID_INVALID_RES_HANDLE;
@@ -1491,7 +1715,7 @@ out_notify_apps:
1491 1715
1492 /* Notify configuration changes to registered applications.*/ 1716 /* Notify configuration changes to registered applications.*/
1493 if (!pmcraid_disable_aen) 1717 if (!pmcraid_disable_aen)
1494 pmcraid_notify_aen(pinstance, PMCRAID_HCAM_CODE_CONFIG_CHANGE); 1718 pmcraid_notify_ccn(pinstance);
1495 1719
1496 cmd = pmcraid_init_hcam(pinstance, PMCRAID_HCAM_CODE_CONFIG_CHANGE); 1720 cmd = pmcraid_init_hcam(pinstance, PMCRAID_HCAM_CODE_CONFIG_CHANGE);
1497 if (cmd) 1721 if (cmd)
@@ -1528,7 +1752,7 @@ void pmcraid_ioasc_logger(u32 ioasc, struct pmcraid_cmd *cmd)
1528 return; 1752 return;
1529 1753
1530 /* log the error string */ 1754 /* log the error string */
1531 pmcraid_err("cmd [%d] for resource %x failed with %x(%s)\n", 1755 pmcraid_err("cmd [%x] for resource %x failed with %x(%s)\n",
1532 cmd->ioa_cb->ioarcb.cdb[0], 1756 cmd->ioa_cb->ioarcb.cdb[0],
1533 cmd->ioa_cb->ioarcb.resource_handle, 1757 cmd->ioa_cb->ioarcb.resource_handle,
1534 le32_to_cpu(ioasc), error_info->error_string); 1758 le32_to_cpu(ioasc), error_info->error_string);
@@ -1663,7 +1887,7 @@ static void pmcraid_process_ldn(struct pmcraid_cmd *cmd)
1663 } 1887 }
1664 /* send netlink message for HCAM notification if enabled */ 1888 /* send netlink message for HCAM notification if enabled */
1665 if (!pmcraid_disable_aen) 1889 if (!pmcraid_disable_aen)
1666 pmcraid_notify_aen(pinstance, PMCRAID_HCAM_CODE_LOG_DATA); 1890 pmcraid_notify_ldn(pinstance);
1667 1891
1668 cmd = pmcraid_init_hcam(pinstance, PMCRAID_HCAM_CODE_LOG_DATA); 1892 cmd = pmcraid_init_hcam(pinstance, PMCRAID_HCAM_CODE_LOG_DATA);
1669 if (cmd) 1893 if (cmd)
@@ -1701,10 +1925,13 @@ static void pmcraid_unregister_hcams(struct pmcraid_cmd *cmd)
1701 atomic_set(&pinstance->ldn.ignore, 1); 1925 atomic_set(&pinstance->ldn.ignore, 1);
1702 1926
1703 /* If adapter reset was forced as part of runtime reset sequence, 1927 /* If adapter reset was forced as part of runtime reset sequence,
1704 * start the reset sequence. 1928 * start the reset sequence. Reset will be triggered even in case
1929 * IOA unit_check.
1705 */ 1930 */
1706 if (pinstance->force_ioa_reset && !pinstance->ioa_bringdown) { 1931 if ((pinstance->force_ioa_reset && !pinstance->ioa_bringdown) ||
1932 pinstance->ioa_unit_check) {
1707 pinstance->force_ioa_reset = 0; 1933 pinstance->force_ioa_reset = 0;
1934 pinstance->ioa_unit_check = 0;
1708 pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT; 1935 pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT;
1709 pmcraid_reset_alert(cmd); 1936 pmcraid_reset_alert(cmd);
1710 return; 1937 return;
@@ -1735,10 +1962,13 @@ static int pmcraid_reset_enable_ioa(struct pmcraid_instance *pinstance)
1735 pmcraid_enable_interrupts(pinstance, PMCRAID_PCI_INTERRUPTS); 1962 pmcraid_enable_interrupts(pinstance, PMCRAID_PCI_INTERRUPTS);
1736 1963
1737 if (intrs & INTRS_TRANSITION_TO_OPERATIONAL) { 1964 if (intrs & INTRS_TRANSITION_TO_OPERATIONAL) {
1738 iowrite32(INTRS_TRANSITION_TO_OPERATIONAL, 1965 if (!pinstance->interrupt_mode) {
1739 pinstance->int_regs.ioa_host_interrupt_mask_reg); 1966 iowrite32(INTRS_TRANSITION_TO_OPERATIONAL,
1740 iowrite32(INTRS_TRANSITION_TO_OPERATIONAL, 1967 pinstance->int_regs.
1741 pinstance->int_regs.ioa_host_interrupt_clr_reg); 1968 ioa_host_interrupt_mask_reg);
1969 iowrite32(INTRS_TRANSITION_TO_OPERATIONAL,
1970 pinstance->int_regs.ioa_host_interrupt_clr_reg);
1971 }
1742 return 1; 1972 return 1;
1743 } else { 1973 } else {
1744 return 0; 1974 return 0;
@@ -1777,8 +2007,19 @@ static void pmcraid_soft_reset(struct pmcraid_cmd *cmd)
1777 doorbell = DOORBELL_RUNTIME_RESET | 2007 doorbell = DOORBELL_RUNTIME_RESET |
1778 DOORBELL_ENABLE_DESTRUCTIVE_DIAGS; 2008 DOORBELL_ENABLE_DESTRUCTIVE_DIAGS;
1779 2009
2010 /* Since we do RESET_ALERT and Start BIST we have to again write
2011 * MSIX Doorbell to indicate the interrupt mode
2012 */
2013 if (pinstance->interrupt_mode) {
2014 iowrite32(DOORBELL_INTR_MODE_MSIX,
2015 pinstance->int_regs.host_ioa_interrupt_reg);
2016 ioread32(pinstance->int_regs.host_ioa_interrupt_reg);
2017 }
2018
1780 iowrite32(doorbell, pinstance->int_regs.host_ioa_interrupt_reg); 2019 iowrite32(doorbell, pinstance->int_regs.host_ioa_interrupt_reg);
2020 ioread32(pinstance->int_regs.host_ioa_interrupt_reg),
1781 int_reg = ioread32(pinstance->int_regs.ioa_host_interrupt_reg); 2021 int_reg = ioread32(pinstance->int_regs.ioa_host_interrupt_reg);
2022
1782 pmcraid_info("Waiting for IOA to become operational %x:%x\n", 2023 pmcraid_info("Waiting for IOA to become operational %x:%x\n",
1783 ioread32(pinstance->int_regs.host_ioa_interrupt_reg), 2024 ioread32(pinstance->int_regs.host_ioa_interrupt_reg),
1784 int_reg); 2025 int_reg);
@@ -1854,7 +2095,8 @@ static void pmcraid_fail_outstanding_cmds(struct pmcraid_instance *pinstance)
1854 } else if (cmd->cmd_done == pmcraid_internal_done || 2095 } else if (cmd->cmd_done == pmcraid_internal_done ||
1855 cmd->cmd_done == pmcraid_erp_done) { 2096 cmd->cmd_done == pmcraid_erp_done) {
1856 cmd->cmd_done(cmd); 2097 cmd->cmd_done(cmd);
1857 } else if (cmd->cmd_done != pmcraid_ioa_reset) { 2098 } else if (cmd->cmd_done != pmcraid_ioa_reset &&
2099 cmd->cmd_done != pmcraid_ioa_shutdown_done) {
1858 pmcraid_return_cmd(cmd); 2100 pmcraid_return_cmd(cmd);
1859 } 2101 }
1860 2102
@@ -1964,6 +2206,13 @@ static void pmcraid_ioa_reset(struct pmcraid_cmd *cmd)
1964 pinstance->ioa_reset_attempts = 0; 2206 pinstance->ioa_reset_attempts = 0;
1965 pmcraid_err("IOA didn't respond marking it as dead\n"); 2207 pmcraid_err("IOA didn't respond marking it as dead\n");
1966 pinstance->ioa_state = IOA_STATE_DEAD; 2208 pinstance->ioa_state = IOA_STATE_DEAD;
2209
2210 if (pinstance->ioa_bringdown)
2211 pmcraid_notify_ioastate(pinstance,
2212 PMC_DEVICE_EVENT_SHUTDOWN_FAILED);
2213 else
2214 pmcraid_notify_ioastate(pinstance,
2215 PMC_DEVICE_EVENT_RESET_FAILED);
1967 reset_complete = 1; 2216 reset_complete = 1;
1968 break; 2217 break;
1969 } 2218 }
@@ -1971,7 +2220,6 @@ static void pmcraid_ioa_reset(struct pmcraid_cmd *cmd)
1971 /* Once either bist or pci reset is done, restore PCI config 2220 /* Once either bist or pci reset is done, restore PCI config
1972 * space. If this fails, proceed with hard reset again 2221 * space. If this fails, proceed with hard reset again
1973 */ 2222 */
1974
1975 if (pci_restore_state(pinstance->pdev)) { 2223 if (pci_restore_state(pinstance->pdev)) {
1976 pmcraid_info("config-space error resetting again\n"); 2224 pmcraid_info("config-space error resetting again\n");
1977 pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT; 2225 pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT;
@@ -2002,6 +2250,8 @@ static void pmcraid_ioa_reset(struct pmcraid_cmd *cmd)
2002 pinstance->ioa_shutdown_type = SHUTDOWN_NONE; 2250 pinstance->ioa_shutdown_type = SHUTDOWN_NONE;
2003 pinstance->ioa_bringdown = 0; 2251 pinstance->ioa_bringdown = 0;
2004 pinstance->ioa_state = IOA_STATE_UNKNOWN; 2252 pinstance->ioa_state = IOA_STATE_UNKNOWN;
2253 pmcraid_notify_ioastate(pinstance,
2254 PMC_DEVICE_EVENT_SHUTDOWN_SUCCESS);
2005 reset_complete = 1; 2255 reset_complete = 1;
2006 } else { 2256 } else {
2007 /* bring-up IOA, so proceed with soft reset 2257 /* bring-up IOA, so proceed with soft reset
@@ -2051,6 +2301,8 @@ static void pmcraid_ioa_reset(struct pmcraid_cmd *cmd)
2051 */ 2301 */
2052 if (pinstance->ioa_shutdown_type == SHUTDOWN_NONE && 2302 if (pinstance->ioa_shutdown_type == SHUTDOWN_NONE &&
2053 pinstance->force_ioa_reset == 0) { 2303 pinstance->force_ioa_reset == 0) {
2304 pmcraid_notify_ioastate(pinstance,
2305 PMC_DEVICE_EVENT_RESET_SUCCESS);
2054 reset_complete = 1; 2306 reset_complete = 1;
2055 } else { 2307 } else {
2056 if (pinstance->ioa_shutdown_type != SHUTDOWN_NONE) 2308 if (pinstance->ioa_shutdown_type != SHUTDOWN_NONE)
@@ -2116,6 +2368,8 @@ static void pmcraid_initiate_reset(struct pmcraid_instance *pinstance)
2116 pinstance->ioa_shutdown_type = SHUTDOWN_NONE; 2368 pinstance->ioa_shutdown_type = SHUTDOWN_NONE;
2117 pinstance->reset_cmd = cmd; 2369 pinstance->reset_cmd = cmd;
2118 pinstance->force_ioa_reset = 1; 2370 pinstance->force_ioa_reset = 1;
2371 pmcraid_notify_ioastate(pinstance,
2372 PMC_DEVICE_EVENT_RESET_START);
2119 pmcraid_ioa_reset(cmd); 2373 pmcraid_ioa_reset(cmd);
2120 } 2374 }
2121} 2375}
@@ -2191,7 +2445,7 @@ static int pmcraid_reset_reload(
2191 wait_event(pinstance->reset_wait_q, 2445 wait_event(pinstance->reset_wait_q,
2192 !pinstance->ioa_reset_in_progress); 2446 !pinstance->ioa_reset_in_progress);
2193 2447
2194 pmcraid_info("reset_reload: reset is complete !! \n"); 2448 pmcraid_info("reset_reload: reset is complete !!\n");
2195 scsi_unblock_requests(pinstance->host); 2449 scsi_unblock_requests(pinstance->host);
2196 if (pinstance->ioa_state == target_state) 2450 if (pinstance->ioa_state == target_state)
2197 reset = 0; 2451 reset = 0;
@@ -2225,6 +2479,8 @@ static int pmcraid_reset_bringdown(struct pmcraid_instance *pinstance)
2225 */ 2479 */
2226static int pmcraid_reset_bringup(struct pmcraid_instance *pinstance) 2480static int pmcraid_reset_bringup(struct pmcraid_instance *pinstance)
2227{ 2481{
2482 pmcraid_notify_ioastate(pinstance, PMC_DEVICE_EVENT_RESET_START);
2483
2228 return pmcraid_reset_reload(pinstance, 2484 return pmcraid_reset_reload(pinstance,
2229 SHUTDOWN_NONE, 2485 SHUTDOWN_NONE,
2230 IOA_STATE_OPERATIONAL); 2486 IOA_STATE_OPERATIONAL);
@@ -2704,7 +2960,7 @@ static struct pmcraid_cmd *pmcraid_abort_cmd(struct pmcraid_cmd *cmd)
2704 2960
2705 pmcraid_info("command (%d) CDB[0] = %x for %x\n", 2961 pmcraid_info("command (%d) CDB[0] = %x for %x\n",
2706 le32_to_cpu(cancel_cmd->ioa_cb->ioarcb.response_handle) >> 2, 2962 le32_to_cpu(cancel_cmd->ioa_cb->ioarcb.response_handle) >> 2,
2707 cmd->ioa_cb->ioarcb.cdb[0], 2963 cancel_cmd->ioa_cb->ioarcb.cdb[0],
2708 le32_to_cpu(cancel_cmd->ioa_cb->ioarcb.resource_handle)); 2964 le32_to_cpu(cancel_cmd->ioa_cb->ioarcb.resource_handle));
2709 2965
2710 pmcraid_send_cmd(cancel_cmd, 2966 pmcraid_send_cmd(cancel_cmd,
@@ -2729,8 +2985,8 @@ static int pmcraid_abort_complete(struct pmcraid_cmd *cancel_cmd)
2729 u32 ioasc; 2985 u32 ioasc;
2730 2986
2731 wait_for_completion(&cancel_cmd->wait_for_completion); 2987 wait_for_completion(&cancel_cmd->wait_for_completion);
2732 res = cancel_cmd->u.res; 2988 res = cancel_cmd->res;
2733 cancel_cmd->u.res = NULL; 2989 cancel_cmd->res = NULL;
2734 ioasc = le32_to_cpu(cancel_cmd->ioa_cb->ioasa.ioasc); 2990 ioasc = le32_to_cpu(cancel_cmd->ioa_cb->ioasa.ioasc);
2735 2991
2736 /* If the abort task is not timed out we will get a Good completion 2992 /* If the abort task is not timed out we will get a Good completion
@@ -2823,7 +3079,7 @@ static int pmcraid_eh_abort_handler(struct scsi_cmnd *scsi_cmd)
2823 host_lock_flags); 3079 host_lock_flags);
2824 3080
2825 if (cancel_cmd) { 3081 if (cancel_cmd) {
2826 cancel_cmd->u.res = cmd->scsi_cmd->device->hostdata; 3082 cancel_cmd->res = cmd->scsi_cmd->device->hostdata;
2827 rc = pmcraid_abort_complete(cancel_cmd); 3083 rc = pmcraid_abort_complete(cancel_cmd);
2828 } 3084 }
2829 3085
@@ -2842,7 +3098,7 @@ static int pmcraid_eh_abort_handler(struct scsi_cmnd *scsi_cmd)
2842 * takes care by locking/unlocking host_lock. 3098 * takes care by locking/unlocking host_lock.
2843 * 3099 *
2844 * Return value 3100 * Return value
2845 * SUCCESS or FAILED 3101 * SUCCESS or FAILED
2846 */ 3102 */
2847static int pmcraid_eh_device_reset_handler(struct scsi_cmnd *scmd) 3103static int pmcraid_eh_device_reset_handler(struct scsi_cmnd *scmd)
2848{ 3104{
@@ -2879,7 +3135,7 @@ static int pmcraid_eh_target_reset_handler(struct scsi_cmnd *scmd)
2879 * Initiates adapter reset to bring it up to operational state 3135 * Initiates adapter reset to bring it up to operational state
2880 * 3136 *
2881 * Return value 3137 * Return value
2882 * SUCCESS or FAILED 3138 * SUCCESS or FAILED
2883 */ 3139 */
2884static int pmcraid_eh_host_reset_handler(struct scsi_cmnd *scmd) 3140static int pmcraid_eh_host_reset_handler(struct scsi_cmnd *scmd)
2885{ 3141{
@@ -2991,7 +3247,7 @@ pmcraid_init_ioadls(struct pmcraid_cmd *cmd, int sgcount)
2991 * to firmware. This builds ioadl descriptors and sets up ioarcb fields. 3247 * to firmware. This builds ioadl descriptors and sets up ioarcb fields.
2992 * 3248 *
2993 * Return value: 3249 * Return value:
2994 * 0 on success or -1 on failure 3250 * 0 on success or -1 on failure
2995 */ 3251 */
2996static int pmcraid_build_ioadl( 3252static int pmcraid_build_ioadl(
2997 struct pmcraid_instance *pinstance, 3253 struct pmcraid_instance *pinstance,
@@ -3049,7 +3305,7 @@ static int pmcraid_build_ioadl(
3049 * Free a DMA'able memory previously allocated with pmcraid_alloc_sglist 3305 * Free a DMA'able memory previously allocated with pmcraid_alloc_sglist
3050 * 3306 *
3051 * Return value: 3307 * Return value:
3052 * none 3308 * none
3053 */ 3309 */
3054static void pmcraid_free_sglist(struct pmcraid_sglist *sglist) 3310static void pmcraid_free_sglist(struct pmcraid_sglist *sglist)
3055{ 3311{
@@ -3070,7 +3326,7 @@ static void pmcraid_free_sglist(struct pmcraid_sglist *sglist)
3070 * list. 3326 * list.
3071 * 3327 *
3072 * Return value 3328 * Return value
3073 * pointer to sglist / NULL on failure 3329 * pointer to sglist / NULL on failure
3074 */ 3330 */
3075static struct pmcraid_sglist *pmcraid_alloc_sglist(int buflen) 3331static struct pmcraid_sglist *pmcraid_alloc_sglist(int buflen)
3076{ 3332{
@@ -3224,11 +3480,12 @@ static int pmcraid_queuecommand(
3224 struct pmcraid_resource_entry *res; 3480 struct pmcraid_resource_entry *res;
3225 struct pmcraid_ioarcb *ioarcb; 3481 struct pmcraid_ioarcb *ioarcb;
3226 struct pmcraid_cmd *cmd; 3482 struct pmcraid_cmd *cmd;
3483 u32 fw_version;
3227 int rc = 0; 3484 int rc = 0;
3228 3485
3229 pinstance = 3486 pinstance =
3230 (struct pmcraid_instance *)scsi_cmd->device->host->hostdata; 3487 (struct pmcraid_instance *)scsi_cmd->device->host->hostdata;
3231 3488 fw_version = be16_to_cpu(pinstance->inq_data->fw_version);
3232 scsi_cmd->scsi_done = done; 3489 scsi_cmd->scsi_done = done;
3233 res = scsi_cmd->device->hostdata; 3490 res = scsi_cmd->device->hostdata;
3234 scsi_cmd->result = (DID_OK << 16); 3491 scsi_cmd->result = (DID_OK << 16);
@@ -3247,6 +3504,15 @@ static int pmcraid_queuecommand(
3247 if (pinstance->ioa_reset_in_progress) 3504 if (pinstance->ioa_reset_in_progress)
3248 return SCSI_MLQUEUE_HOST_BUSY; 3505 return SCSI_MLQUEUE_HOST_BUSY;
3249 3506
3507 /* Firmware doesn't support SYNCHRONIZE_CACHE command (0x35), complete
3508 * the command here itself with success return
3509 */
3510 if (scsi_cmd->cmnd[0] == SYNCHRONIZE_CACHE) {
3511 pmcraid_info("SYNC_CACHE(0x35), completing in driver itself\n");
3512 scsi_cmd->scsi_done(scsi_cmd);
3513 return 0;
3514 }
3515
3250 /* initialize the command and IOARCB to be sent to IOA */ 3516 /* initialize the command and IOARCB to be sent to IOA */
3251 cmd = pmcraid_get_free_cmd(pinstance); 3517 cmd = pmcraid_get_free_cmd(pinstance);
3252 3518
@@ -3261,6 +3527,13 @@ static int pmcraid_queuecommand(
3261 ioarcb->resource_handle = res->cfg_entry.resource_handle; 3527 ioarcb->resource_handle = res->cfg_entry.resource_handle;
3262 ioarcb->request_type = REQ_TYPE_SCSI; 3528 ioarcb->request_type = REQ_TYPE_SCSI;
3263 3529
3530 /* set hrrq number where the IOA should respond to. Note that all cmds
3531 * generated internally uses hrrq_id 0, exception to this is the cmd
3532 * block of scsi_cmd which is re-used (e.g. cancel/abort), which uses
3533 * hrrq_id assigned here in queuecommand
3534 */
3535 ioarcb->hrrq_id = atomic_add_return(1, &(pinstance->last_message_id)) %
3536 pinstance->num_hrrq;
3264 cmd->cmd_done = pmcraid_io_done; 3537 cmd->cmd_done = pmcraid_io_done;
3265 3538
3266 if (RES_IS_GSCSI(res->cfg_entry) || RES_IS_VSET(res->cfg_entry)) { 3539 if (RES_IS_GSCSI(res->cfg_entry) || RES_IS_VSET(res->cfg_entry)) {
@@ -3287,7 +3560,9 @@ static int pmcraid_queuecommand(
3287 RES_IS_VSET(res->cfg_entry) ? PMCRAID_VSET_BUS_ID : 3560 RES_IS_VSET(res->cfg_entry) ? PMCRAID_VSET_BUS_ID :
3288 PMCRAID_PHYS_BUS_ID, 3561 PMCRAID_PHYS_BUS_ID,
3289 RES_IS_VSET(res->cfg_entry) ? 3562 RES_IS_VSET(res->cfg_entry) ?
3290 res->cfg_entry.unique_flags1 : 3563 (fw_version <= PMCRAID_FW_VERSION_1 ?
3564 res->cfg_entry.unique_flags1 :
3565 res->cfg_entry.array_id & 0xFF) :
3291 RES_TARGET(res->cfg_entry.resource_address), 3566 RES_TARGET(res->cfg_entry.resource_address),
3292 RES_LUN(res->cfg_entry.resource_address)); 3567 RES_LUN(res->cfg_entry.resource_address));
3293 3568
@@ -3465,6 +3740,7 @@ static long pmcraid_ioctl_passthrough(
3465 unsigned long request_buffer; 3740 unsigned long request_buffer;
3466 unsigned long request_offset; 3741 unsigned long request_offset;
3467 unsigned long lock_flags; 3742 unsigned long lock_flags;
3743 u32 ioasc;
3468 int request_size; 3744 int request_size;
3469 int buffer_size; 3745 int buffer_size;
3470 u8 access, direction; 3746 u8 access, direction;
@@ -3566,6 +3842,14 @@ static long pmcraid_ioctl_passthrough(
3566 buffer->ioarcb.add_cmd_param_length); 3842 buffer->ioarcb.add_cmd_param_length);
3567 } 3843 }
3568 3844
3845 /* set hrrq number where the IOA should respond to. Note that all cmds
3846 * generated internally uses hrrq_id 0, exception to this is the cmd
3847 * block of scsi_cmd which is re-used (e.g. cancel/abort), which uses
3848 * hrrq_id assigned here in queuecommand
3849 */
3850 ioarcb->hrrq_id = atomic_add_return(1, &(pinstance->last_message_id)) %
3851 pinstance->num_hrrq;
3852
3569 if (request_size) { 3853 if (request_size) {
3570 rc = pmcraid_build_passthrough_ioadls(cmd, 3854 rc = pmcraid_build_passthrough_ioadls(cmd,
3571 request_size, 3855 request_size,
@@ -3606,6 +3890,14 @@ static long pmcraid_ioctl_passthrough(
3606 _pmcraid_fire_command(cmd); 3890 _pmcraid_fire_command(cmd);
3607 spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags); 3891 spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
3608 3892
3893 /* NOTE ! Remove the below line once abort_task is implemented
3894 * in firmware. This line disables ioctl command timeout handling logic
3895 * similar to IO command timeout handling, making ioctl commands to wait
3896 * until the command completion regardless of timeout value specified in
3897 * ioarcb
3898 */
3899 buffer->ioarcb.cmd_timeout = 0;
3900
3609 /* If command timeout is specified put caller to wait till that time, 3901 /* If command timeout is specified put caller to wait till that time,
3610 * otherwise it would be blocking wait. If command gets timed out, it 3902 * otherwise it would be blocking wait. If command gets timed out, it
3611 * will be aborted. 3903 * will be aborted.
@@ -3620,25 +3912,47 @@ static long pmcraid_ioctl_passthrough(
3620 le32_to_cpu(cmd->ioa_cb->ioarcb.response_handle >> 2), 3912 le32_to_cpu(cmd->ioa_cb->ioarcb.response_handle >> 2),
3621 cmd->ioa_cb->ioarcb.cdb[0]); 3913 cmd->ioa_cb->ioarcb.cdb[0]);
3622 3914
3623 rc = -ETIMEDOUT;
3624 spin_lock_irqsave(pinstance->host->host_lock, lock_flags); 3915 spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
3625 cancel_cmd = pmcraid_abort_cmd(cmd); 3916 cancel_cmd = pmcraid_abort_cmd(cmd);
3626 spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags); 3917 spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
3627 3918
3628 if (cancel_cmd) { 3919 if (cancel_cmd) {
3629 wait_for_completion(&cancel_cmd->wait_for_completion); 3920 wait_for_completion(&cancel_cmd->wait_for_completion);
3921 ioasc = cancel_cmd->ioa_cb->ioasa.ioasc;
3630 pmcraid_return_cmd(cancel_cmd); 3922 pmcraid_return_cmd(cancel_cmd);
3923
3924 /* if abort task couldn't find the command i.e it got
3925 * completed prior to aborting, return good completion.
3926 * if command got aborted succesfully or there was IOA
3927 * reset due to abort task itself getting timedout then
3928 * return -ETIMEDOUT
3929 */
3930 if (ioasc == PMCRAID_IOASC_IOA_WAS_RESET ||
3931 PMCRAID_IOASC_SENSE_KEY(ioasc) == 0x00) {
3932 if (ioasc != PMCRAID_IOASC_GC_IOARCB_NOTFOUND)
3933 rc = -ETIMEDOUT;
3934 goto out_handle_response;
3935 }
3631 } 3936 }
3632 3937
3633 goto out_free_sglist; 3938 /* no command block for abort task or abort task failed to abort
3939 * the IOARCB, then wait for 150 more seconds and initiate reset
3940 * sequence after timeout
3941 */
3942 if (!wait_for_completion_timeout(
3943 &cmd->wait_for_completion,
3944 msecs_to_jiffies(150 * 1000))) {
3945 pmcraid_reset_bringup(cmd->drv_inst);
3946 rc = -ETIMEDOUT;
3947 }
3634 } 3948 }
3635 3949
3950out_handle_response:
3636 /* If the command failed for any reason, copy entire IOASA buffer and 3951 /* If the command failed for any reason, copy entire IOASA buffer and
3637 * return IOCTL success. If copying IOASA to user-buffer fails, return 3952 * return IOCTL success. If copying IOASA to user-buffer fails, return
3638 * EFAULT 3953 * EFAULT
3639 */ 3954 */
3640 if (le32_to_cpu(cmd->ioa_cb->ioasa.ioasc)) { 3955 if (PMCRAID_IOASC_SENSE_KEY(le32_to_cpu(cmd->ioa_cb->ioasa.ioasc))) {
3641
3642 void *ioasa = 3956 void *ioasa =
3643 (void *)(arg + 3957 (void *)(arg +
3644 offsetof(struct pmcraid_passthrough_ioctl_buffer, ioasa)); 3958 offsetof(struct pmcraid_passthrough_ioctl_buffer, ioasa));
@@ -3651,6 +3965,7 @@ static long pmcraid_ioctl_passthrough(
3651 rc = -EFAULT; 3965 rc = -EFAULT;
3652 } 3966 }
3653 } 3967 }
3968
3654 /* If the data transfer was from device, copy the data onto user 3969 /* If the data transfer was from device, copy the data onto user
3655 * buffers 3970 * buffers
3656 */ 3971 */
@@ -3699,7 +4014,7 @@ static long pmcraid_ioctl_driver(
3699 int rc = -ENOSYS; 4014 int rc = -ENOSYS;
3700 4015
3701 if (!access_ok(VERIFY_READ, user_buffer, _IOC_SIZE(cmd))) { 4016 if (!access_ok(VERIFY_READ, user_buffer, _IOC_SIZE(cmd))) {
3702 pmcraid_err("ioctl_driver: access fault in request buffer \n"); 4017 pmcraid_err("ioctl_driver: access fault in request buffer\n");
3703 return -EFAULT; 4018 return -EFAULT;
3704 } 4019 }
3705 4020
@@ -4011,36 +4326,77 @@ static struct scsi_host_template pmcraid_host_template = {
4011 .proc_name = PMCRAID_DRIVER_NAME 4326 .proc_name = PMCRAID_DRIVER_NAME
4012}; 4327};
4013 4328
4014/** 4329/*
4015 * pmcraid_isr_common - Common interrupt handler routine 4330 * pmcraid_isr_msix - implements MSI-X interrupt handling routine
4016 * 4331 * @irq: interrupt vector number
4017 * @pinstance: pointer to adapter instance 4332 * @dev_id: pointer hrrq_vector
4018 * @intrs: active interrupts (contents of ioa_host_interrupt register)
4019 * @hrrq_id: Host RRQ index
4020 * 4333 *
4021 * Return Value 4334 * Return Value
4022 * none 4335 * IRQ_HANDLED if interrupt is handled or IRQ_NONE if ignored
4023 */ 4336 */
4024static void pmcraid_isr_common( 4337
4025 struct pmcraid_instance *pinstance, 4338static irqreturn_t pmcraid_isr_msix(int irq, void *dev_id)
4026 u32 intrs,
4027 int hrrq_id
4028)
4029{ 4339{
4030 u32 intrs_clear = 4340 struct pmcraid_isr_param *hrrq_vector;
4031 (intrs & INTRS_CRITICAL_OP_IN_PROGRESS) ? intrs 4341 struct pmcraid_instance *pinstance;
4032 : INTRS_HRRQ_VALID; 4342 unsigned long lock_flags;
4033 iowrite32(intrs_clear, 4343 u32 intrs_val;
4034 pinstance->int_regs.ioa_host_interrupt_clr_reg); 4344 int hrrq_id;
4035 intrs = ioread32(pinstance->int_regs.ioa_host_interrupt_reg); 4345
4346 hrrq_vector = (struct pmcraid_isr_param *)dev_id;
4347 hrrq_id = hrrq_vector->hrrq_id;
4348 pinstance = hrrq_vector->drv_inst;
4349
4350 if (!hrrq_id) {
4351 /* Read the interrupt */
4352 intrs_val = pmcraid_read_interrupts(pinstance);
4353 if (intrs_val &&
4354 ((ioread32(pinstance->int_regs.host_ioa_interrupt_reg)
4355 & DOORBELL_INTR_MSIX_CLR) == 0)) {
4356 /* Any error interrupts including unit_check,
4357 * initiate IOA reset.In case of unit check indicate
4358 * to reset_sequence that IOA unit checked and prepare
4359 * for a dump during reset sequence
4360 */
4361 if (intrs_val & PMCRAID_ERROR_INTERRUPTS) {
4362 if (intrs_val & INTRS_IOA_UNIT_CHECK)
4363 pinstance->ioa_unit_check = 1;
4364
4365 pmcraid_err("ISR: error interrupts: %x \
4366 initiating reset\n", intrs_val);
4367 spin_lock_irqsave(pinstance->host->host_lock,
4368 lock_flags);
4369 pmcraid_initiate_reset(pinstance);
4370 spin_unlock_irqrestore(
4371 pinstance->host->host_lock,
4372 lock_flags);
4373 }
4374 /* If interrupt was as part of the ioa initialization,
4375 * clear it. Delete the timer and wakeup the
4376 * reset engine to proceed with reset sequence
4377 */
4378 if (intrs_val & INTRS_TRANSITION_TO_OPERATIONAL)
4379 pmcraid_clr_trans_op(pinstance);
4380
4381 /* Clear the interrupt register by writing
4382 * to host to ioa doorbell. Once done
4383 * FW will clear the interrupt.
4384 */
4385 iowrite32(DOORBELL_INTR_MSIX_CLR,
4386 pinstance->int_regs.host_ioa_interrupt_reg);
4387 ioread32(pinstance->int_regs.host_ioa_interrupt_reg);
4388
4036 4389
4037 /* hrrq valid bit was set, schedule tasklet to handle the response */ 4390 }
4038 if (intrs_clear == INTRS_HRRQ_VALID) 4391 }
4039 tasklet_schedule(&(pinstance->isr_tasklet[hrrq_id])); 4392
4393 tasklet_schedule(&(pinstance->isr_tasklet[hrrq_id]));
4394
4395 return IRQ_HANDLED;
4040} 4396}
4041 4397
4042/** 4398/**
4043 * pmcraid_isr - implements interrupt handling routine 4399 * pmcraid_isr - implements legacy interrupt handling routine
4044 * 4400 *
4045 * @irq: interrupt vector number 4401 * @irq: interrupt vector number
4046 * @dev_id: pointer hrrq_vector 4402 * @dev_id: pointer hrrq_vector
@@ -4052,8 +4408,9 @@ static irqreturn_t pmcraid_isr(int irq, void *dev_id)
4052{ 4408{
4053 struct pmcraid_isr_param *hrrq_vector; 4409 struct pmcraid_isr_param *hrrq_vector;
4054 struct pmcraid_instance *pinstance; 4410 struct pmcraid_instance *pinstance;
4055 unsigned long lock_flags;
4056 u32 intrs; 4411 u32 intrs;
4412 unsigned long lock_flags;
4413 int hrrq_id = 0;
4057 4414
4058 /* In case of legacy interrupt mode where interrupts are shared across 4415 /* In case of legacy interrupt mode where interrupts are shared across
4059 * isrs, it may be possible that the current interrupt is not from IOA 4416 * isrs, it may be possible that the current interrupt is not from IOA
@@ -4062,21 +4419,13 @@ static irqreturn_t pmcraid_isr(int irq, void *dev_id)
4062 printk(KERN_INFO "%s(): NULL host pointer\n", __func__); 4419 printk(KERN_INFO "%s(): NULL host pointer\n", __func__);
4063 return IRQ_NONE; 4420 return IRQ_NONE;
4064 } 4421 }
4065
4066 hrrq_vector = (struct pmcraid_isr_param *)dev_id; 4422 hrrq_vector = (struct pmcraid_isr_param *)dev_id;
4067 pinstance = hrrq_vector->drv_inst; 4423 pinstance = hrrq_vector->drv_inst;
4068 4424
4069 /* Acquire the lock (currently host_lock) while processing interrupts.
4070 * This interval is small as most of the response processing is done by
4071 * tasklet without the lock.
4072 */
4073 spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
4074 intrs = pmcraid_read_interrupts(pinstance); 4425 intrs = pmcraid_read_interrupts(pinstance);
4075 4426
4076 if (unlikely((intrs & PMCRAID_PCI_INTERRUPTS) == 0)) { 4427 if (unlikely((intrs & PMCRAID_PCI_INTERRUPTS) == 0))
4077 spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
4078 return IRQ_NONE; 4428 return IRQ_NONE;
4079 }
4080 4429
4081 /* Any error interrupts including unit_check, initiate IOA reset. 4430 /* Any error interrupts including unit_check, initiate IOA reset.
4082 * In case of unit check indicate to reset_sequence that IOA unit 4431 * In case of unit check indicate to reset_sequence that IOA unit
@@ -4091,13 +4440,28 @@ static irqreturn_t pmcraid_isr(int irq, void *dev_id)
4091 pinstance->int_regs.ioa_host_interrupt_clr_reg); 4440 pinstance->int_regs.ioa_host_interrupt_clr_reg);
4092 pmcraid_err("ISR: error interrupts: %x initiating reset\n", 4441 pmcraid_err("ISR: error interrupts: %x initiating reset\n",
4093 intrs); 4442 intrs);
4094 intrs = ioread32(pinstance->int_regs.ioa_host_interrupt_reg); 4443 intrs = ioread32(
4444 pinstance->int_regs.ioa_host_interrupt_clr_reg);
4445 spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
4095 pmcraid_initiate_reset(pinstance); 4446 pmcraid_initiate_reset(pinstance);
4447 spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
4096 } else { 4448 } else {
4097 pmcraid_isr_common(pinstance, intrs, hrrq_vector->hrrq_id); 4449 /* If interrupt was as part of the ioa initialization,
4098 } 4450 * clear. Delete the timer and wakeup the
4451 * reset engine to proceed with reset sequence
4452 */
4453 if (intrs & INTRS_TRANSITION_TO_OPERATIONAL) {
4454 pmcraid_clr_trans_op(pinstance);
4455 } else {
4456 iowrite32(intrs,
4457 pinstance->int_regs.ioa_host_interrupt_clr_reg);
4458 ioread32(
4459 pinstance->int_regs.ioa_host_interrupt_clr_reg);
4099 4460
4100 spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags); 4461 tasklet_schedule(
4462 &(pinstance->isr_tasklet[hrrq_id]));
4463 }
4464 }
4101 4465
4102 return IRQ_HANDLED; 4466 return IRQ_HANDLED;
4103} 4467}
@@ -4120,6 +4484,7 @@ static void pmcraid_worker_function(struct work_struct *workp)
4120 struct scsi_device *sdev; 4484 struct scsi_device *sdev;
4121 unsigned long lock_flags; 4485 unsigned long lock_flags;
4122 unsigned long host_lock_flags; 4486 unsigned long host_lock_flags;
4487 u16 fw_version;
4123 u8 bus, target, lun; 4488 u8 bus, target, lun;
4124 4489
4125 pinstance = container_of(workp, struct pmcraid_instance, worker_q); 4490 pinstance = container_of(workp, struct pmcraid_instance, worker_q);
@@ -4127,6 +4492,8 @@ static void pmcraid_worker_function(struct work_struct *workp)
4127 if (!atomic_read(&pinstance->expose_resources)) 4492 if (!atomic_read(&pinstance->expose_resources))
4128 return; 4493 return;
4129 4494
4495 fw_version = be16_to_cpu(pinstance->inq_data->fw_version);
4496
4130 spin_lock_irqsave(&pinstance->resource_lock, lock_flags); 4497 spin_lock_irqsave(&pinstance->resource_lock, lock_flags);
4131 list_for_each_entry_safe(res, temp, &pinstance->used_res_q, queue) { 4498 list_for_each_entry_safe(res, temp, &pinstance->used_res_q, queue) {
4132 4499
@@ -4166,12 +4533,16 @@ static void pmcraid_worker_function(struct work_struct *workp)
4166 4533
4167 if (res->change_detected == RES_CHANGE_ADD) { 4534 if (res->change_detected == RES_CHANGE_ADD) {
4168 4535
4169 if (!pmcraid_expose_resource(&res->cfg_entry)) 4536 if (!pmcraid_expose_resource(fw_version,
4537 &res->cfg_entry))
4170 continue; 4538 continue;
4171 4539
4172 if (RES_IS_VSET(res->cfg_entry)) { 4540 if (RES_IS_VSET(res->cfg_entry)) {
4173 bus = PMCRAID_VSET_BUS_ID; 4541 bus = PMCRAID_VSET_BUS_ID;
4174 target = res->cfg_entry.unique_flags1; 4542 if (fw_version <= PMCRAID_FW_VERSION_1)
4543 target = res->cfg_entry.unique_flags1;
4544 else
4545 target = res->cfg_entry.array_id & 0xFF;
4175 lun = PMCRAID_VSET_LUN_ID; 4546 lun = PMCRAID_VSET_LUN_ID;
4176 } else { 4547 } else {
4177 bus = PMCRAID_PHYS_BUS_ID; 4548 bus = PMCRAID_PHYS_BUS_ID;
@@ -4201,7 +4572,7 @@ static void pmcraid_worker_function(struct work_struct *workp)
4201 * Return Value 4572 * Return Value
4202 * None 4573 * None
4203 */ 4574 */
4204void pmcraid_tasklet_function(unsigned long instance) 4575static void pmcraid_tasklet_function(unsigned long instance)
4205{ 4576{
4206 struct pmcraid_isr_param *hrrq_vector; 4577 struct pmcraid_isr_param *hrrq_vector;
4207 struct pmcraid_instance *pinstance; 4578 struct pmcraid_instance *pinstance;
@@ -4210,35 +4581,12 @@ void pmcraid_tasklet_function(unsigned long instance)
4210 unsigned long host_lock_flags; 4581 unsigned long host_lock_flags;
4211 spinlock_t *lockp; /* hrrq buffer lock */ 4582 spinlock_t *lockp; /* hrrq buffer lock */
4212 int id; 4583 int id;
4213 u32 intrs;
4214 __le32 resp; 4584 __le32 resp;
4215 4585
4216 hrrq_vector = (struct pmcraid_isr_param *)instance; 4586 hrrq_vector = (struct pmcraid_isr_param *)instance;
4217 pinstance = hrrq_vector->drv_inst; 4587 pinstance = hrrq_vector->drv_inst;
4218 id = hrrq_vector->hrrq_id; 4588 id = hrrq_vector->hrrq_id;
4219 lockp = &(pinstance->hrrq_lock[id]); 4589 lockp = &(pinstance->hrrq_lock[id]);
4220 intrs = pmcraid_read_interrupts(pinstance);
4221
4222 /* If interrupts was as part of the ioa initialization, clear and mask
4223 * it. Delete the timer and wakeup the reset engine to proceed with
4224 * reset sequence
4225 */
4226 if (intrs & INTRS_TRANSITION_TO_OPERATIONAL) {
4227 iowrite32(INTRS_TRANSITION_TO_OPERATIONAL,
4228 pinstance->int_regs.ioa_host_interrupt_mask_reg);
4229 iowrite32(INTRS_TRANSITION_TO_OPERATIONAL,
4230 pinstance->int_regs.ioa_host_interrupt_clr_reg);
4231
4232 if (pinstance->reset_cmd != NULL) {
4233 del_timer(&pinstance->reset_cmd->timer);
4234 spin_lock_irqsave(pinstance->host->host_lock,
4235 host_lock_flags);
4236 pinstance->reset_cmd->cmd_done(pinstance->reset_cmd);
4237 spin_unlock_irqrestore(pinstance->host->host_lock,
4238 host_lock_flags);
4239 }
4240 return;
4241 }
4242 4590
4243 /* loop through each of the commands responded by IOA. Each HRRQ buf is 4591 /* loop through each of the commands responded by IOA. Each HRRQ buf is
4244 * protected by its own lock. Traversals must be done within this lock 4592 * protected by its own lock. Traversals must be done within this lock
@@ -4256,27 +4604,6 @@ void pmcraid_tasklet_function(unsigned long instance)
4256 int cmd_index = resp >> 2; 4604 int cmd_index = resp >> 2;
4257 struct pmcraid_cmd *cmd = NULL; 4605 struct pmcraid_cmd *cmd = NULL;
4258 4606
4259 if (cmd_index < PMCRAID_MAX_CMD) {
4260 cmd = pinstance->cmd_list[cmd_index];
4261 } else {
4262 /* In case of invalid response handle, initiate IOA
4263 * reset sequence.
4264 */
4265 spin_unlock_irqrestore(lockp, hrrq_lock_flags);
4266
4267 pmcraid_err("Invalid response %d initiating reset\n",
4268 cmd_index);
4269
4270 spin_lock_irqsave(pinstance->host->host_lock,
4271 host_lock_flags);
4272 pmcraid_initiate_reset(pinstance);
4273 spin_unlock_irqrestore(pinstance->host->host_lock,
4274 host_lock_flags);
4275
4276 spin_lock_irqsave(lockp, hrrq_lock_flags);
4277 break;
4278 }
4279
4280 if (pinstance->hrrq_curr[id] < pinstance->hrrq_end[id]) { 4607 if (pinstance->hrrq_curr[id] < pinstance->hrrq_end[id]) {
4281 pinstance->hrrq_curr[id]++; 4608 pinstance->hrrq_curr[id]++;
4282 } else { 4609 } else {
@@ -4284,6 +4611,14 @@ void pmcraid_tasklet_function(unsigned long instance)
4284 pinstance->host_toggle_bit[id] ^= 1u; 4611 pinstance->host_toggle_bit[id] ^= 1u;
4285 } 4612 }
4286 4613
4614 if (cmd_index >= PMCRAID_MAX_CMD) {
4615 /* In case of invalid response handle, log message */
4616 pmcraid_err("Invalid response handle %d\n", cmd_index);
4617 resp = le32_to_cpu(*(pinstance->hrrq_curr[id]));
4618 continue;
4619 }
4620
4621 cmd = pinstance->cmd_list[cmd_index];
4287 spin_unlock_irqrestore(lockp, hrrq_lock_flags); 4622 spin_unlock_irqrestore(lockp, hrrq_lock_flags);
4288 4623
4289 spin_lock_irqsave(&pinstance->pending_pool_lock, 4624 spin_lock_irqsave(&pinstance->pending_pool_lock,
@@ -4324,7 +4659,16 @@ void pmcraid_tasklet_function(unsigned long instance)
4324static 4659static
4325void pmcraid_unregister_interrupt_handler(struct pmcraid_instance *pinstance) 4660void pmcraid_unregister_interrupt_handler(struct pmcraid_instance *pinstance)
4326{ 4661{
4327 free_irq(pinstance->pdev->irq, &(pinstance->hrrq_vector[0])); 4662 int i;
4663
4664 for (i = 0; i < pinstance->num_hrrq; i++)
4665 free_irq(pinstance->hrrq_vector[i].vector,
4666 &(pinstance->hrrq_vector[i]));
4667
4668 if (pinstance->interrupt_mode) {
4669 pci_disable_msix(pinstance->pdev);
4670 pinstance->interrupt_mode = 0;
4671 }
4328} 4672}
4329 4673
4330/** 4674/**
@@ -4337,14 +4681,70 @@ void pmcraid_unregister_interrupt_handler(struct pmcraid_instance *pinstance)
4337static int 4681static int
4338pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance) 4682pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance)
4339{ 4683{
4684 int rc;
4340 struct pci_dev *pdev = pinstance->pdev; 4685 struct pci_dev *pdev = pinstance->pdev;
4341 4686
4687 if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) {
4688 int num_hrrq = PMCRAID_NUM_MSIX_VECTORS;
4689 struct msix_entry entries[PMCRAID_NUM_MSIX_VECTORS];
4690 int i;
4691 for (i = 0; i < PMCRAID_NUM_MSIX_VECTORS; i++)
4692 entries[i].entry = i;
4693
4694 rc = pci_enable_msix(pdev, entries, num_hrrq);
4695 if (rc < 0)
4696 goto pmcraid_isr_legacy;
4697
4698 /* Check how many MSIX vectors are allocated and register
4699 * msi-x handlers for each of them giving appropriate buffer
4700 */
4701 if (rc > 0) {
4702 num_hrrq = rc;
4703 if (pci_enable_msix(pdev, entries, num_hrrq))
4704 goto pmcraid_isr_legacy;
4705 }
4706
4707 for (i = 0; i < num_hrrq; i++) {
4708 pinstance->hrrq_vector[i].hrrq_id = i;
4709 pinstance->hrrq_vector[i].drv_inst = pinstance;
4710 pinstance->hrrq_vector[i].vector = entries[i].vector;
4711 rc = request_irq(pinstance->hrrq_vector[i].vector,
4712 pmcraid_isr_msix, 0,
4713 PMCRAID_DRIVER_NAME,
4714 &(pinstance->hrrq_vector[i]));
4715
4716 if (rc) {
4717 int j;
4718 for (j = 0; j < i; j++)
4719 free_irq(entries[j].vector,
4720 &(pinstance->hrrq_vector[j]));
4721 pci_disable_msix(pdev);
4722 goto pmcraid_isr_legacy;
4723 }
4724 }
4725
4726 pinstance->num_hrrq = num_hrrq;
4727 pinstance->interrupt_mode = 1;
4728 iowrite32(DOORBELL_INTR_MODE_MSIX,
4729 pinstance->int_regs.host_ioa_interrupt_reg);
4730 ioread32(pinstance->int_regs.host_ioa_interrupt_reg);
4731 goto pmcraid_isr_out;
4732 }
4733
4734pmcraid_isr_legacy:
4735 /* If MSI-X registration failed fallback to legacy mode, where
4736 * only one hrrq entry will be used
4737 */
4342 pinstance->hrrq_vector[0].hrrq_id = 0; 4738 pinstance->hrrq_vector[0].hrrq_id = 0;
4343 pinstance->hrrq_vector[0].drv_inst = pinstance; 4739 pinstance->hrrq_vector[0].drv_inst = pinstance;
4344 pinstance->hrrq_vector[0].vector = 0; 4740 pinstance->hrrq_vector[0].vector = pdev->irq;
4345 pinstance->num_hrrq = 1; 4741 pinstance->num_hrrq = 1;
4346 return request_irq(pdev->irq, pmcraid_isr, IRQF_SHARED, 4742 rc = 0;
4347 PMCRAID_DRIVER_NAME, &pinstance->hrrq_vector[0]); 4743
4744 rc = request_irq(pdev->irq, pmcraid_isr, IRQF_SHARED,
4745 PMCRAID_DRIVER_NAME, &pinstance->hrrq_vector[0]);
4746pmcraid_isr_out:
4747 return rc;
4348} 4748}
4349 4749
4350/** 4750/**
@@ -4516,12 +4916,11 @@ pmcraid_release_host_rrqs(struct pmcraid_instance *pinstance, int maxindex)
4516static int __devinit 4916static int __devinit
4517pmcraid_allocate_host_rrqs(struct pmcraid_instance *pinstance) 4917pmcraid_allocate_host_rrqs(struct pmcraid_instance *pinstance)
4518{ 4918{
4519 int i; 4919 int i, buffer_size;
4520 int buf_count = PMCRAID_MAX_CMD / pinstance->num_hrrq;
4521 4920
4522 for (i = 0; i < pinstance->num_hrrq; i++) { 4921 buffer_size = HRRQ_ENTRY_SIZE * PMCRAID_MAX_CMD;
4523 int buffer_size = HRRQ_ENTRY_SIZE * buf_count;
4524 4922
4923 for (i = 0; i < pinstance->num_hrrq; i++) {
4525 pinstance->hrrq_start[i] = 4924 pinstance->hrrq_start[i] =
4526 pci_alloc_consistent( 4925 pci_alloc_consistent(
4527 pinstance->pdev, 4926 pinstance->pdev,
@@ -4529,7 +4928,8 @@ pmcraid_allocate_host_rrqs(struct pmcraid_instance *pinstance)
4529 &(pinstance->hrrq_start_bus_addr[i])); 4928 &(pinstance->hrrq_start_bus_addr[i]));
4530 4929
4531 if (pinstance->hrrq_start[i] == 0) { 4930 if (pinstance->hrrq_start[i] == 0) {
4532 pmcraid_err("could not allocate host rrq: %d\n", i); 4931 pmcraid_err("pci_alloc failed for hrrq vector : %d\n",
4932 i);
4533 pmcraid_release_host_rrqs(pinstance, i); 4933 pmcraid_release_host_rrqs(pinstance, i);
4534 return -ENOMEM; 4934 return -ENOMEM;
4535 } 4935 }
@@ -4537,7 +4937,7 @@ pmcraid_allocate_host_rrqs(struct pmcraid_instance *pinstance)
4537 memset(pinstance->hrrq_start[i], 0, buffer_size); 4937 memset(pinstance->hrrq_start[i], 0, buffer_size);
4538 pinstance->hrrq_curr[i] = pinstance->hrrq_start[i]; 4938 pinstance->hrrq_curr[i] = pinstance->hrrq_start[i];
4539 pinstance->hrrq_end[i] = 4939 pinstance->hrrq_end[i] =
4540 pinstance->hrrq_start[i] + buf_count - 1; 4940 pinstance->hrrq_start[i] + PMCRAID_MAX_CMD - 1;
4541 pinstance->host_toggle_bit[i] = 1; 4941 pinstance->host_toggle_bit[i] = 1;
4542 spin_lock_init(&pinstance->hrrq_lock[i]); 4942 spin_lock_init(&pinstance->hrrq_lock[i]);
4543 } 4943 }
@@ -4557,7 +4957,7 @@ static void pmcraid_release_hcams(struct pmcraid_instance *pinstance)
4557 if (pinstance->ccn.msg != NULL) { 4957 if (pinstance->ccn.msg != NULL) {
4558 pci_free_consistent(pinstance->pdev, 4958 pci_free_consistent(pinstance->pdev,
4559 PMCRAID_AEN_HDR_SIZE + 4959 PMCRAID_AEN_HDR_SIZE +
4560 sizeof(struct pmcraid_hcam_ccn), 4960 sizeof(struct pmcraid_hcam_ccn_ext),
4561 pinstance->ccn.msg, 4961 pinstance->ccn.msg,
4562 pinstance->ccn.baddr); 4962 pinstance->ccn.baddr);
4563 4963
@@ -4591,7 +4991,7 @@ static int pmcraid_allocate_hcams(struct pmcraid_instance *pinstance)
4591 pinstance->ccn.msg = pci_alloc_consistent( 4991 pinstance->ccn.msg = pci_alloc_consistent(
4592 pinstance->pdev, 4992 pinstance->pdev,
4593 PMCRAID_AEN_HDR_SIZE + 4993 PMCRAID_AEN_HDR_SIZE +
4594 sizeof(struct pmcraid_hcam_ccn), 4994 sizeof(struct pmcraid_hcam_ccn_ext),
4595 &(pinstance->ccn.baddr)); 4995 &(pinstance->ccn.baddr));
4596 4996
4597 pinstance->ldn.msg = pci_alloc_consistent( 4997 pinstance->ldn.msg = pci_alloc_consistent(
@@ -4724,6 +5124,32 @@ static void pmcraid_kill_tasklets(struct pmcraid_instance *pinstance)
4724} 5124}
4725 5125
4726/** 5126/**
5127 * pmcraid_release_buffers - release per-adapter buffers allocated
5128 *
5129 * @pinstance: pointer to adapter soft state
5130 *
5131 * Return Value
5132 * none
5133 */
5134static void pmcraid_release_buffers(struct pmcraid_instance *pinstance)
5135{
5136 pmcraid_release_config_buffers(pinstance);
5137 pmcraid_release_control_blocks(pinstance, PMCRAID_MAX_CMD);
5138 pmcraid_release_cmd_blocks(pinstance, PMCRAID_MAX_CMD);
5139 pmcraid_release_host_rrqs(pinstance, pinstance->num_hrrq);
5140
5141 if (pinstance->inq_data != NULL) {
5142 pci_free_consistent(pinstance->pdev,
5143 sizeof(struct pmcraid_inquiry_data),
5144 pinstance->inq_data,
5145 pinstance->inq_data_baddr);
5146
5147 pinstance->inq_data = NULL;
5148 pinstance->inq_data_baddr = 0;
5149 }
5150}
5151
5152/**
4727 * pmcraid_init_buffers - allocates memory and initializes various structures 5153 * pmcraid_init_buffers - allocates memory and initializes various structures
4728 * @pinstance: pointer to per adapter instance structure 5154 * @pinstance: pointer to per adapter instance structure
4729 * 5155 *
@@ -4753,20 +5179,32 @@ static int __devinit pmcraid_init_buffers(struct pmcraid_instance *pinstance)
4753 } 5179 }
4754 5180
4755 if (pmcraid_allocate_cmd_blocks(pinstance)) { 5181 if (pmcraid_allocate_cmd_blocks(pinstance)) {
4756 pmcraid_err("couldn't allocate memory for cmd blocks \n"); 5182 pmcraid_err("couldn't allocate memory for cmd blocks\n");
4757 pmcraid_release_config_buffers(pinstance); 5183 pmcraid_release_config_buffers(pinstance);
4758 pmcraid_release_host_rrqs(pinstance, pinstance->num_hrrq); 5184 pmcraid_release_host_rrqs(pinstance, pinstance->num_hrrq);
4759 return -ENOMEM; 5185 return -ENOMEM;
4760 } 5186 }
4761 5187
4762 if (pmcraid_allocate_control_blocks(pinstance)) { 5188 if (pmcraid_allocate_control_blocks(pinstance)) {
4763 pmcraid_err("couldn't allocate memory control blocks \n"); 5189 pmcraid_err("couldn't allocate memory control blocks\n");
4764 pmcraid_release_config_buffers(pinstance); 5190 pmcraid_release_config_buffers(pinstance);
4765 pmcraid_release_cmd_blocks(pinstance, PMCRAID_MAX_CMD); 5191 pmcraid_release_cmd_blocks(pinstance, PMCRAID_MAX_CMD);
4766 pmcraid_release_host_rrqs(pinstance, pinstance->num_hrrq); 5192 pmcraid_release_host_rrqs(pinstance, pinstance->num_hrrq);
4767 return -ENOMEM; 5193 return -ENOMEM;
4768 } 5194 }
4769 5195
5196 /* allocate DMAable memory for page D0 INQUIRY buffer */
5197 pinstance->inq_data = pci_alloc_consistent(
5198 pinstance->pdev,
5199 sizeof(struct pmcraid_inquiry_data),
5200 &pinstance->inq_data_baddr);
5201
5202 if (pinstance->inq_data == NULL) {
5203 pmcraid_err("couldn't allocate DMA memory for INQUIRY\n");
5204 pmcraid_release_buffers(pinstance);
5205 return -ENOMEM;
5206 }
5207
4770 /* Initialize all the command blocks and add them to free pool. No 5208 /* Initialize all the command blocks and add them to free pool. No
4771 * need to lock (free_pool_lock) as this is done in initialization 5209 * need to lock (free_pool_lock) as this is done in initialization
4772 * itself 5210 * itself
@@ -4785,7 +5223,7 @@ static int __devinit pmcraid_init_buffers(struct pmcraid_instance *pinstance)
4785 * pmcraid_reinit_buffers - resets various buffer pointers 5223 * pmcraid_reinit_buffers - resets various buffer pointers
4786 * @pinstance: pointer to adapter instance 5224 * @pinstance: pointer to adapter instance
4787 * Return value 5225 * Return value
4788 * none 5226 * none
4789 */ 5227 */
4790static void pmcraid_reinit_buffers(struct pmcraid_instance *pinstance) 5228static void pmcraid_reinit_buffers(struct pmcraid_instance *pinstance)
4791{ 5229{
@@ -4836,6 +5274,8 @@ static int __devinit pmcraid_init_instance(
4836 mapped_pci_addr + chip_cfg->ioa_host_intr; 5274 mapped_pci_addr + chip_cfg->ioa_host_intr;
4837 pint_regs->ioa_host_interrupt_clr_reg = 5275 pint_regs->ioa_host_interrupt_clr_reg =
4838 mapped_pci_addr + chip_cfg->ioa_host_intr_clr; 5276 mapped_pci_addr + chip_cfg->ioa_host_intr_clr;
5277 pint_regs->ioa_host_msix_interrupt_reg =
5278 mapped_pci_addr + chip_cfg->ioa_host_msix_intr;
4839 pint_regs->host_ioa_interrupt_reg = 5279 pint_regs->host_ioa_interrupt_reg =
4840 mapped_pci_addr + chip_cfg->host_ioa_intr; 5280 mapped_pci_addr + chip_cfg->host_ioa_intr;
4841 pint_regs->host_ioa_interrupt_clr_reg = 5281 pint_regs->host_ioa_interrupt_clr_reg =
@@ -4858,6 +5298,7 @@ static int __devinit pmcraid_init_instance(
4858 init_waitqueue_head(&pinstance->reset_wait_q); 5298 init_waitqueue_head(&pinstance->reset_wait_q);
4859 5299
4860 atomic_set(&pinstance->outstanding_cmds, 0); 5300 atomic_set(&pinstance->outstanding_cmds, 0);
5301 atomic_set(&pinstance->last_message_id, 0);
4861 atomic_set(&pinstance->expose_resources, 0); 5302 atomic_set(&pinstance->expose_resources, 0);
4862 5303
4863 INIT_LIST_HEAD(&pinstance->free_res_q); 5304 INIT_LIST_HEAD(&pinstance->free_res_q);
@@ -4883,23 +5324,6 @@ static int __devinit pmcraid_init_instance(
4883} 5324}
4884 5325
4885/** 5326/**
4886 * pmcraid_release_buffers - release per-adapter buffers allocated
4887 *
4888 * @pinstance: pointer to adapter soft state
4889 *
4890 * Return Value
4891 * none
4892 */
4893static void pmcraid_release_buffers(struct pmcraid_instance *pinstance)
4894{
4895 pmcraid_release_config_buffers(pinstance);
4896 pmcraid_release_control_blocks(pinstance, PMCRAID_MAX_CMD);
4897 pmcraid_release_cmd_blocks(pinstance, PMCRAID_MAX_CMD);
4898 pmcraid_release_host_rrqs(pinstance, pinstance->num_hrrq);
4899
4900}
4901
4902/**
4903 * pmcraid_shutdown - shutdown adapter controller. 5327 * pmcraid_shutdown - shutdown adapter controller.
4904 * @pdev: pci device struct 5328 * @pdev: pci device struct
4905 * 5329 *
@@ -4958,7 +5382,7 @@ static int pmcraid_setup_chrdev(struct pmcraid_instance *pinstance)
4958 pmcraid_release_minor(minor); 5382 pmcraid_release_minor(minor);
4959 else 5383 else
4960 device_create(pmcraid_class, NULL, MKDEV(pmcraid_major, minor), 5384 device_create(pmcraid_class, NULL, MKDEV(pmcraid_major, minor),
4961 NULL, "pmcsas%u", minor); 5385 NULL, "%s%u", PMCRAID_DEVFILE, minor);
4962 return error; 5386 return error;
4963} 5387}
4964 5388
@@ -5050,7 +5474,6 @@ static int pmcraid_resume(struct pci_dev *pdev)
5050 struct pmcraid_instance *pinstance = pci_get_drvdata(pdev); 5474 struct pmcraid_instance *pinstance = pci_get_drvdata(pdev);
5051 struct Scsi_Host *host = pinstance->host; 5475 struct Scsi_Host *host = pinstance->host;
5052 int rc; 5476 int rc;
5053 int hrrqs;
5054 5477
5055 pci_set_power_state(pdev, PCI_D0); 5478 pci_set_power_state(pdev, PCI_D0);
5056 pci_enable_wake(pdev, PCI_D0, 0); 5479 pci_enable_wake(pdev, PCI_D0, 0);
@@ -5077,8 +5500,8 @@ static int pmcraid_resume(struct pci_dev *pdev)
5077 goto disable_device; 5500 goto disable_device;
5078 } 5501 }
5079 5502
5503 pmcraid_disable_interrupts(pinstance, ~0);
5080 atomic_set(&pinstance->outstanding_cmds, 0); 5504 atomic_set(&pinstance->outstanding_cmds, 0);
5081 hrrqs = pinstance->num_hrrq;
5082 rc = pmcraid_register_interrupt_handler(pinstance); 5505 rc = pmcraid_register_interrupt_handler(pinstance);
5083 5506
5084 if (rc) { 5507 if (rc) {
@@ -5100,7 +5523,7 @@ static int pmcraid_resume(struct pci_dev *pdev)
5100 * state. 5523 * state.
5101 */ 5524 */
5102 if (pmcraid_reset_bringup(pinstance)) { 5525 if (pmcraid_reset_bringup(pinstance)) {
5103 dev_err(&pdev->dev, "couldn't initialize IOA \n"); 5526 dev_err(&pdev->dev, "couldn't initialize IOA\n");
5104 rc = -ENODEV; 5527 rc = -ENODEV;
5105 goto release_tasklets; 5528 goto release_tasklets;
5106 } 5529 }
@@ -5108,6 +5531,7 @@ static int pmcraid_resume(struct pci_dev *pdev)
5108 return 0; 5531 return 0;
5109 5532
5110release_tasklets: 5533release_tasklets:
5534 pmcraid_disable_interrupts(pinstance, ~0);
5111 pmcraid_kill_tasklets(pinstance); 5535 pmcraid_kill_tasklets(pinstance);
5112 pmcraid_unregister_interrupt_handler(pinstance); 5536 pmcraid_unregister_interrupt_handler(pinstance);
5113 5537
@@ -5129,7 +5553,7 @@ disable_device:
5129 5553
5130/** 5554/**
5131 * pmcraid_complete_ioa_reset - Called by either timer or tasklet during 5555 * pmcraid_complete_ioa_reset - Called by either timer or tasklet during
5132 * completion of the ioa reset 5556 * completion of the ioa reset
5133 * @cmd: pointer to reset command block 5557 * @cmd: pointer to reset command block
5134 */ 5558 */
5135static void pmcraid_complete_ioa_reset(struct pmcraid_cmd *cmd) 5559static void pmcraid_complete_ioa_reset(struct pmcraid_cmd *cmd)
@@ -5204,11 +5628,14 @@ static void pmcraid_init_res_table(struct pmcraid_cmd *cmd)
5204 struct pmcraid_config_table_entry *cfgte; 5628 struct pmcraid_config_table_entry *cfgte;
5205 unsigned long lock_flags; 5629 unsigned long lock_flags;
5206 int found, rc, i; 5630 int found, rc, i;
5631 u16 fw_version;
5207 LIST_HEAD(old_res); 5632 LIST_HEAD(old_res);
5208 5633
5209 if (pinstance->cfg_table->flags & MICROCODE_UPDATE_REQUIRED) 5634 if (pinstance->cfg_table->flags & MICROCODE_UPDATE_REQUIRED)
5210 pmcraid_err("IOA requires microcode download\n"); 5635 pmcraid_err("IOA requires microcode download\n");
5211 5636
5637 fw_version = be16_to_cpu(pinstance->inq_data->fw_version);
5638
5212 /* resource list is protected by pinstance->resource_lock. 5639 /* resource list is protected by pinstance->resource_lock.
5213 * init_res_table can be called from probe (user-thread) or runtime 5640 * init_res_table can be called from probe (user-thread) or runtime
5214 * reset (timer/tasklet) 5641 * reset (timer/tasklet)
@@ -5219,9 +5646,14 @@ static void pmcraid_init_res_table(struct pmcraid_cmd *cmd)
5219 list_move_tail(&res->queue, &old_res); 5646 list_move_tail(&res->queue, &old_res);
5220 5647
5221 for (i = 0; i < pinstance->cfg_table->num_entries; i++) { 5648 for (i = 0; i < pinstance->cfg_table->num_entries; i++) {
5222 cfgte = &pinstance->cfg_table->entries[i]; 5649 if (be16_to_cpu(pinstance->inq_data->fw_version) <=
5650 PMCRAID_FW_VERSION_1)
5651 cfgte = &pinstance->cfg_table->entries[i];
5652 else
5653 cfgte = (struct pmcraid_config_table_entry *)
5654 &pinstance->cfg_table->entries_ext[i];
5223 5655
5224 if (!pmcraid_expose_resource(cfgte)) 5656 if (!pmcraid_expose_resource(fw_version, cfgte))
5225 continue; 5657 continue;
5226 5658
5227 found = 0; 5659 found = 0;
@@ -5263,10 +5695,12 @@ static void pmcraid_init_res_table(struct pmcraid_cmd *cmd)
5263 */ 5695 */
5264 if (found) { 5696 if (found) {
5265 memcpy(&res->cfg_entry, cfgte, 5697 memcpy(&res->cfg_entry, cfgte,
5266 sizeof(struct pmcraid_config_table_entry)); 5698 pinstance->config_table_entry_size);
5267 pmcraid_info("New res type:%x, vset:%x, addr:%x:\n", 5699 pmcraid_info("New res type:%x, vset:%x, addr:%x:\n",
5268 res->cfg_entry.resource_type, 5700 res->cfg_entry.resource_type,
5269 res->cfg_entry.unique_flags1, 5701 (fw_version <= PMCRAID_FW_VERSION_1 ?
5702 res->cfg_entry.unique_flags1 :
5703 res->cfg_entry.array_id & 0xFF),
5270 le32_to_cpu(res->cfg_entry.resource_address)); 5704 le32_to_cpu(res->cfg_entry.resource_address));
5271 } 5705 }
5272 } 5706 }
@@ -5306,6 +5740,14 @@ static void pmcraid_querycfg(struct pmcraid_cmd *cmd)
5306 struct pmcraid_instance *pinstance = cmd->drv_inst; 5740 struct pmcraid_instance *pinstance = cmd->drv_inst;
5307 int cfg_table_size = cpu_to_be32(sizeof(struct pmcraid_config_table)); 5741 int cfg_table_size = cpu_to_be32(sizeof(struct pmcraid_config_table));
5308 5742
5743 if (be16_to_cpu(pinstance->inq_data->fw_version) <=
5744 PMCRAID_FW_VERSION_1)
5745 pinstance->config_table_entry_size =
5746 sizeof(struct pmcraid_config_table_entry);
5747 else
5748 pinstance->config_table_entry_size =
5749 sizeof(struct pmcraid_config_table_entry_ext);
5750
5309 ioarcb->request_type = REQ_TYPE_IOACMD; 5751 ioarcb->request_type = REQ_TYPE_IOACMD;
5310 ioarcb->resource_handle = cpu_to_le32(PMCRAID_IOA_RES_HANDLE); 5752 ioarcb->resource_handle = cpu_to_le32(PMCRAID_IOA_RES_HANDLE);
5311 5753
@@ -5338,7 +5780,7 @@ static void pmcraid_querycfg(struct pmcraid_cmd *cmd)
5338 5780
5339 5781
5340/** 5782/**
5341 * pmcraid_probe - PCI probe entry pointer for PMC MaxRaid controller driver 5783 * pmcraid_probe - PCI probe entry pointer for PMC MaxRAID controller driver
5342 * @pdev: pointer to pci device structure 5784 * @pdev: pointer to pci device structure
5343 * @dev_id: pointer to device ids structure 5785 * @dev_id: pointer to device ids structure
5344 * 5786 *
@@ -5485,7 +5927,7 @@ static int __devinit pmcraid_probe(
5485 */ 5927 */
5486 pmcraid_info("starting IOA initialization sequence\n"); 5928 pmcraid_info("starting IOA initialization sequence\n");
5487 if (pmcraid_reset_bringup(pinstance)) { 5929 if (pmcraid_reset_bringup(pinstance)) {
5488 dev_err(&pdev->dev, "couldn't initialize IOA \n"); 5930 dev_err(&pdev->dev, "couldn't initialize IOA\n");
5489 rc = 1; 5931 rc = 1;
5490 goto out_release_bufs; 5932 goto out_release_bufs;
5491 } 5933 }
diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h
index b8ad07c3449e..6cfa0145a1d7 100644
--- a/drivers/scsi/pmcraid.h
+++ b/drivers/scsi/pmcraid.h
@@ -40,10 +40,12 @@
40 * Driver version: version string in major_version.minor_version.patch format 40 * Driver version: version string in major_version.minor_version.patch format
41 * Driver date : date information in "Mon dd yyyy" format 41 * Driver date : date information in "Mon dd yyyy" format
42 */ 42 */
43#define PMCRAID_DRIVER_NAME "PMC MaxRAID" 43#define PMCRAID_DRIVER_NAME "PMC MaxRAID"
44#define PMCRAID_DEVFILE "pmcsas" 44#define PMCRAID_DEVFILE "pmcsas"
45#define PMCRAID_DRIVER_VERSION "1.0.2" 45#define PMCRAID_DRIVER_VERSION "2.0.2"
46#define PMCRAID_DRIVER_DATE __DATE__ 46#define PMCRAID_DRIVER_DATE __DATE__
47
48#define PMCRAID_FW_VERSION_1 0x002
47 49
48/* Maximum number of adapters supported by current version of the driver */ 50/* Maximum number of adapters supported by current version of the driver */
49#define PMCRAID_MAX_ADAPTERS 1024 51#define PMCRAID_MAX_ADAPTERS 1024
@@ -85,17 +87,17 @@
85#define PMCRAID_IOARCB_ALIGNMENT 32 87#define PMCRAID_IOARCB_ALIGNMENT 32
86#define PMCRAID_IOADL_ALIGNMENT 16 88#define PMCRAID_IOADL_ALIGNMENT 16
87#define PMCRAID_IOASA_ALIGNMENT 4 89#define PMCRAID_IOASA_ALIGNMENT 4
88#define PMCRAID_NUM_MSIX_VECTORS 1 90#define PMCRAID_NUM_MSIX_VECTORS 16
89 91
90/* various other limits */ 92/* various other limits */
91#define PMCRAID_VENDOR_ID_LEN 8 93#define PMCRAID_VENDOR_ID_LEN 8
92#define PMCRAID_PRODUCT_ID_LEN 16 94#define PMCRAID_PRODUCT_ID_LEN 16
93#define PMCRAID_SERIAL_NUM_LEN 8 95#define PMCRAID_SERIAL_NUM_LEN 8
94#define PMCRAID_LUN_LEN 8 96#define PMCRAID_LUN_LEN 8
95#define PMCRAID_MAX_CDB_LEN 16 97#define PMCRAID_MAX_CDB_LEN 16
96#define PMCRAID_DEVICE_ID_LEN 8 98#define PMCRAID_DEVICE_ID_LEN 8
97#define PMCRAID_SENSE_DATA_LEN 256 99#define PMCRAID_SENSE_DATA_LEN 256
98#define PMCRAID_ADD_CMD_PARAM_LEN 48 100#define PMCRAID_ADD_CMD_PARAM_LEN 48
99 101
100#define PMCRAID_MAX_BUS_TO_SCAN 1 102#define PMCRAID_MAX_BUS_TO_SCAN 1
101#define PMCRAID_MAX_NUM_TARGETS_PER_BUS 256 103#define PMCRAID_MAX_NUM_TARGETS_PER_BUS 256
@@ -116,17 +118,10 @@
116#define PMCRAID_VSET_MAX_SECTORS 512 118#define PMCRAID_VSET_MAX_SECTORS 512
117#define PMCRAID_MAX_CMD_PER_LUN 254 119#define PMCRAID_MAX_CMD_PER_LUN 254
118 120
119/* Number of configuration table entries (resources) */ 121/* Number of configuration table entries (resources), includes 1 FP,
120#define PMCRAID_MAX_NUM_OF_VSETS 240 122 * 1 Enclosure device
121 123 */
122/* Todo : Check max limit for Phase 1 */ 124#define PMCRAID_MAX_RESOURCES 256
123#define PMCRAID_MAX_NUM_OF_PHY_DEVS 256
124
125/* MAX_NUM_OF_DEVS includes 1 FP, 1 Dummy Enclosure device */
126#define PMCRAID_MAX_NUM_OF_DEVS \
127 (PMCRAID_MAX_NUM_OF_VSETS + PMCRAID_MAX_NUM_OF_PHY_DEVS + 2)
128
129#define PMCRAID_MAX_RESOURCES PMCRAID_MAX_NUM_OF_DEVS
130 125
131/* Adapter Commands used by driver */ 126/* Adapter Commands used by driver */
132#define PMCRAID_QUERY_RESOURCE_STATE 0xC2 127#define PMCRAID_QUERY_RESOURCE_STATE 0xC2
@@ -177,6 +172,7 @@
177#define PMCRAID_IOASC_SENSE_STATUS(ioasc) ((ioasc) & 0x000000ff) 172#define PMCRAID_IOASC_SENSE_STATUS(ioasc) ((ioasc) & 0x000000ff)
178 173
179#define PMCRAID_IOASC_GOOD_COMPLETION 0x00000000 174#define PMCRAID_IOASC_GOOD_COMPLETION 0x00000000
175#define PMCRAID_IOASC_GC_IOARCB_NOTFOUND 0x005A0000
180#define PMCRAID_IOASC_NR_INIT_CMD_REQUIRED 0x02040200 176#define PMCRAID_IOASC_NR_INIT_CMD_REQUIRED 0x02040200
181#define PMCRAID_IOASC_NR_IOA_RESET_REQUIRED 0x02048000 177#define PMCRAID_IOASC_NR_IOA_RESET_REQUIRED 0x02048000
182#define PMCRAID_IOASC_NR_SYNC_REQUIRED 0x023F0000 178#define PMCRAID_IOASC_NR_SYNC_REQUIRED 0x023F0000
@@ -187,12 +183,12 @@
187#define PMCRAID_IOASC_HW_IOA_RESET_REQUIRED 0x04448600 183#define PMCRAID_IOASC_HW_IOA_RESET_REQUIRED 0x04448600
188#define PMCRAID_IOASC_IR_INVALID_RESOURCE_HANDLE 0x05250000 184#define PMCRAID_IOASC_IR_INVALID_RESOURCE_HANDLE 0x05250000
189#define PMCRAID_IOASC_AC_TERMINATED_BY_HOST 0x0B5A0000 185#define PMCRAID_IOASC_AC_TERMINATED_BY_HOST 0x0B5A0000
190#define PMCRAID_IOASC_UA_BUS_WAS_RESET 0x06290000 186#define PMCRAID_IOASC_UA_BUS_WAS_RESET 0x06290000
191#define PMCRAID_IOASC_UA_BUS_WAS_RESET_BY_OTHER 0x06298000 187#define PMCRAID_IOASC_UA_BUS_WAS_RESET_BY_OTHER 0x06298000
192 188
193/* Driver defined IOASCs */ 189/* Driver defined IOASCs */
194#define PMCRAID_IOASC_IOA_WAS_RESET 0x10000001 190#define PMCRAID_IOASC_IOA_WAS_RESET 0x10000001
195#define PMCRAID_IOASC_PCI_ACCESS_ERROR 0x10000002 191#define PMCRAID_IOASC_PCI_ACCESS_ERROR 0x10000002
196 192
197/* Various timeout values (in milliseconds) used. If any of these are chip 193/* Various timeout values (in milliseconds) used. If any of these are chip
198 * specific, move them to pmcraid_chip_details structure. 194 * specific, move them to pmcraid_chip_details structure.
@@ -336,6 +332,13 @@ struct pmcraid_config_table_entry {
336 __u8 lun[PMCRAID_LUN_LEN]; 332 __u8 lun[PMCRAID_LUN_LEN];
337} __attribute__((packed, aligned(4))); 333} __attribute__((packed, aligned(4)));
338 334
335/* extended configuration table sizes are of 64 bytes in size */
336#define PMCRAID_CFGTE_EXT_SIZE 32
337struct pmcraid_config_table_entry_ext {
338 struct pmcraid_config_table_entry cfgte;
339 __u8 cfgte_ext[PMCRAID_CFGTE_EXT_SIZE];
340};
341
339/* resource types (config_table_entry.resource_type values) */ 342/* resource types (config_table_entry.resource_type values) */
340#define RES_TYPE_AF_DASD 0x00 343#define RES_TYPE_AF_DASD 0x00
341#define RES_TYPE_GSCSI 0x01 344#define RES_TYPE_GSCSI 0x01
@@ -376,7 +379,12 @@ struct pmcraid_config_table {
376 __u8 reserved1; 379 __u8 reserved1;
377 __u8 flags; 380 __u8 flags;
378 __u8 reserved2[11]; 381 __u8 reserved2[11];
379 struct pmcraid_config_table_entry entries[PMCRAID_MAX_RESOURCES]; 382 union {
383 struct pmcraid_config_table_entry
384 entries[PMCRAID_MAX_RESOURCES];
385 struct pmcraid_config_table_entry_ext
386 entries_ext[PMCRAID_MAX_RESOURCES];
387 };
380} __attribute__((packed, aligned(4))); 388} __attribute__((packed, aligned(4)));
381 389
382/* config_table.flags value */ 390/* config_table.flags value */
@@ -385,7 +393,7 @@ struct pmcraid_config_table {
385/* 393/*
386 * HCAM format 394 * HCAM format
387 */ 395 */
388#define PMCRAID_HOSTRCB_LDNSIZE 4056 396#define PMCRAID_HOSTRCB_LDNSIZE 4056
389 397
390/* Error log notification format */ 398/* Error log notification format */
391struct pmcraid_hostrcb_error { 399struct pmcraid_hostrcb_error {
@@ -416,6 +424,15 @@ struct pmcraid_hcam_hdr {
416struct pmcraid_hcam_ccn { 424struct pmcraid_hcam_ccn {
417 struct pmcraid_hcam_hdr header; 425 struct pmcraid_hcam_hdr header;
418 struct pmcraid_config_table_entry cfg_entry; 426 struct pmcraid_config_table_entry cfg_entry;
427 struct pmcraid_config_table_entry cfg_entry_old;
428} __attribute__((packed, aligned(4)));
429
430#define PMCRAID_CCN_EXT_SIZE 3944
431struct pmcraid_hcam_ccn_ext {
432 struct pmcraid_hcam_hdr header;
433 struct pmcraid_config_table_entry_ext cfg_entry;
434 struct pmcraid_config_table_entry_ext cfg_entry_old;
435 __u8 reserved[PMCRAID_CCN_EXT_SIZE];
419} __attribute__((packed, aligned(4))); 436} __attribute__((packed, aligned(4)));
420 437
421struct pmcraid_hcam_ldn { 438struct pmcraid_hcam_ldn {
@@ -431,6 +448,8 @@ struct pmcraid_hcam_ldn {
431#define NOTIFICATION_TYPE_ENTRY_CHANGED 0x0 448#define NOTIFICATION_TYPE_ENTRY_CHANGED 0x0
432#define NOTIFICATION_TYPE_ENTRY_NEW 0x1 449#define NOTIFICATION_TYPE_ENTRY_NEW 0x1
433#define NOTIFICATION_TYPE_ENTRY_DELETED 0x2 450#define NOTIFICATION_TYPE_ENTRY_DELETED 0x2
451#define NOTIFICATION_TYPE_STATE_CHANGE 0x3
452#define NOTIFICATION_TYPE_ENTRY_STATECHANGED 0x4
434#define NOTIFICATION_TYPE_ERROR_LOG 0x10 453#define NOTIFICATION_TYPE_ERROR_LOG 0x10
435#define NOTIFICATION_TYPE_INFORMATION_LOG 0x11 454#define NOTIFICATION_TYPE_INFORMATION_LOG 0x11
436 455
@@ -460,6 +479,7 @@ struct pmcraid_chip_details {
460 unsigned long mailbox; 479 unsigned long mailbox;
461 unsigned long global_intr_mask; 480 unsigned long global_intr_mask;
462 unsigned long ioa_host_intr; 481 unsigned long ioa_host_intr;
482 unsigned long ioa_host_msix_intr;
463 unsigned long ioa_host_intr_clr; 483 unsigned long ioa_host_intr_clr;
464 unsigned long ioa_host_mask; 484 unsigned long ioa_host_mask;
465 unsigned long ioa_host_mask_clr; 485 unsigned long ioa_host_mask_clr;
@@ -482,6 +502,7 @@ struct pmcraid_chip_details {
482#define INTRS_IOA_PROCESSOR_ERROR PMC_BIT32(29) 502#define INTRS_IOA_PROCESSOR_ERROR PMC_BIT32(29)
483#define INTRS_HRRQ_VALID PMC_BIT32(30) 503#define INTRS_HRRQ_VALID PMC_BIT32(30)
484#define INTRS_OPERATIONAL_STATUS PMC_BIT32(0) 504#define INTRS_OPERATIONAL_STATUS PMC_BIT32(0)
505#define INTRS_ALLOW_MSIX_VECTOR0 PMC_BIT32(31)
485 506
486/* Host to IOA Doorbells */ 507/* Host to IOA Doorbells */
487#define DOORBELL_RUNTIME_RESET PMC_BIT32(1) 508#define DOORBELL_RUNTIME_RESET PMC_BIT32(1)
@@ -489,10 +510,12 @@ struct pmcraid_chip_details {
489#define DOORBELL_IOA_DEBUG_ALERT PMC_BIT32(9) 510#define DOORBELL_IOA_DEBUG_ALERT PMC_BIT32(9)
490#define DOORBELL_ENABLE_DESTRUCTIVE_DIAGS PMC_BIT32(8) 511#define DOORBELL_ENABLE_DESTRUCTIVE_DIAGS PMC_BIT32(8)
491#define DOORBELL_IOA_START_BIST PMC_BIT32(23) 512#define DOORBELL_IOA_START_BIST PMC_BIT32(23)
513#define DOORBELL_INTR_MODE_MSIX PMC_BIT32(25)
514#define DOORBELL_INTR_MSIX_CLR PMC_BIT32(26)
492#define DOORBELL_RESET_IOA PMC_BIT32(31) 515#define DOORBELL_RESET_IOA PMC_BIT32(31)
493 516
494/* Global interrupt mask register value */ 517/* Global interrupt mask register value */
495#define GLOBAL_INTERRUPT_MASK 0x4ULL 518#define GLOBAL_INTERRUPT_MASK 0x5ULL
496 519
497#define PMCRAID_ERROR_INTERRUPTS (INTRS_IOARCB_TRANSFER_FAILED | \ 520#define PMCRAID_ERROR_INTERRUPTS (INTRS_IOARCB_TRANSFER_FAILED | \
498 INTRS_IOA_UNIT_CHECK | \ 521 INTRS_IOA_UNIT_CHECK | \
@@ -503,8 +526,8 @@ struct pmcraid_chip_details {
503 526
504#define PMCRAID_PCI_INTERRUPTS (PMCRAID_ERROR_INTERRUPTS | \ 527#define PMCRAID_PCI_INTERRUPTS (PMCRAID_ERROR_INTERRUPTS | \
505 INTRS_HRRQ_VALID | \ 528 INTRS_HRRQ_VALID | \
506 INTRS_CRITICAL_OP_IN_PROGRESS |\ 529 INTRS_TRANSITION_TO_OPERATIONAL |\
507 INTRS_TRANSITION_TO_OPERATIONAL) 530 INTRS_ALLOW_MSIX_VECTOR0)
508 531
509/* control_block, associated with each of the commands contains IOARCB, IOADLs 532/* control_block, associated with each of the commands contains IOARCB, IOADLs
510 * memory for IOASA. Additional 3 * 16 bytes are allocated in order to support 533 * memory for IOASA. Additional 3 * 16 bytes are allocated in order to support
@@ -526,17 +549,24 @@ struct pmcraid_sglist {
526 struct scatterlist scatterlist[1]; 549 struct scatterlist scatterlist[1];
527}; 550};
528 551
552/* page D0 inquiry data of focal point resource */
553struct pmcraid_inquiry_data {
554 __u8 ph_dev_type;
555 __u8 page_code;
556 __u8 reserved1;
557 __u8 add_page_len;
558 __u8 length;
559 __u8 reserved2;
560 __le16 fw_version;
561 __u8 reserved3[16];
562};
563
529/* pmcraid_cmd - LLD representation of SCSI command */ 564/* pmcraid_cmd - LLD representation of SCSI command */
530struct pmcraid_cmd { 565struct pmcraid_cmd {
531 566
532 /* Ptr and bus address of DMA.able control block for this command */ 567 /* Ptr and bus address of DMA.able control block for this command */
533 struct pmcraid_control_block *ioa_cb; 568 struct pmcraid_control_block *ioa_cb;
534 dma_addr_t ioa_cb_bus_addr; 569 dma_addr_t ioa_cb_bus_addr;
535
536 /* sense buffer for REQUEST SENSE command if firmware is not sending
537 * auto sense data
538 */
539 dma_addr_t sense_buffer_dma;
540 dma_addr_t dma_handle; 570 dma_addr_t dma_handle;
541 u8 *sense_buffer; 571 u8 *sense_buffer;
542 572
@@ -556,11 +586,22 @@ struct pmcraid_cmd {
556 586
557 struct pmcraid_sglist *sglist; /* used for passthrough IOCTLs */ 587 struct pmcraid_sglist *sglist; /* used for passthrough IOCTLs */
558 588
559 /* scratch used during reset sequence */ 589 /* scratch used */
560 union { 590 union {
591 /* during reset sequence */
561 unsigned long time_left; 592 unsigned long time_left;
562 struct pmcraid_resource_entry *res; 593 struct pmcraid_resource_entry *res;
563 } u; 594 int hrrq_index;
595
596 /* used during IO command error handling. Sense buffer
597 * for REQUEST SENSE command if firmware is not sending
598 * auto sense data
599 */
600 struct {
601 u8 *sense_buffer;
602 dma_addr_t sense_buffer_dma;
603 };
604 };
564}; 605};
565 606
566/* 607/*
@@ -568,6 +609,7 @@ struct pmcraid_cmd {
568 */ 609 */
569struct pmcraid_interrupts { 610struct pmcraid_interrupts {
570 void __iomem *ioa_host_interrupt_reg; 611 void __iomem *ioa_host_interrupt_reg;
612 void __iomem *ioa_host_msix_interrupt_reg;
571 void __iomem *ioa_host_interrupt_clr_reg; 613 void __iomem *ioa_host_interrupt_clr_reg;
572 void __iomem *ioa_host_interrupt_mask_reg; 614 void __iomem *ioa_host_interrupt_mask_reg;
573 void __iomem *ioa_host_interrupt_mask_clr_reg; 615 void __iomem *ioa_host_interrupt_mask_clr_reg;
@@ -578,11 +620,12 @@ struct pmcraid_interrupts {
578 620
579/* ISR parameters LLD allocates (one for each MSI-X if enabled) vectors */ 621/* ISR parameters LLD allocates (one for each MSI-X if enabled) vectors */
580struct pmcraid_isr_param { 622struct pmcraid_isr_param {
581 u8 hrrq_id; /* hrrq entry index */
582 u16 vector; /* allocated msi-x vector */
583 struct pmcraid_instance *drv_inst; 623 struct pmcraid_instance *drv_inst;
624 u16 vector; /* allocated msi-x vector */
625 u8 hrrq_id; /* hrrq entry index */
584}; 626};
585 627
628
586/* AEN message header sent as part of event data to applications */ 629/* AEN message header sent as part of event data to applications */
587struct pmcraid_aen_msg { 630struct pmcraid_aen_msg {
588 u32 hostno; 631 u32 hostno;
@@ -591,6 +634,19 @@ struct pmcraid_aen_msg {
591 u8 data[0]; 634 u8 data[0];
592}; 635};
593 636
637/* Controller state event message type */
638struct pmcraid_state_msg {
639 struct pmcraid_aen_msg msg;
640 u32 ioa_state;
641};
642
643#define PMC_DEVICE_EVENT_RESET_START 0x11000000
644#define PMC_DEVICE_EVENT_RESET_SUCCESS 0x11000001
645#define PMC_DEVICE_EVENT_RESET_FAILED 0x11000002
646#define PMC_DEVICE_EVENT_SHUTDOWN_START 0x11000003
647#define PMC_DEVICE_EVENT_SHUTDOWN_SUCCESS 0x11000004
648#define PMC_DEVICE_EVENT_SHUTDOWN_FAILED 0x11000005
649
594struct pmcraid_hostrcb { 650struct pmcraid_hostrcb {
595 struct pmcraid_instance *drv_inst; 651 struct pmcraid_instance *drv_inst;
596 struct pmcraid_aen_msg *msg; 652 struct pmcraid_aen_msg *msg;
@@ -628,6 +684,7 @@ struct pmcraid_instance {
628 /* HostRCBs needed for HCAM */ 684 /* HostRCBs needed for HCAM */
629 struct pmcraid_hostrcb ldn; 685 struct pmcraid_hostrcb ldn;
630 struct pmcraid_hostrcb ccn; 686 struct pmcraid_hostrcb ccn;
687 struct pmcraid_state_msg scn; /* controller state change msg */
631 688
632 689
633 /* Bus address of start of HRRQ */ 690 /* Bus address of start of HRRQ */
@@ -645,12 +702,15 @@ struct pmcraid_instance {
645 /* Lock for HRRQ access */ 702 /* Lock for HRRQ access */
646 spinlock_t hrrq_lock[PMCRAID_NUM_MSIX_VECTORS]; 703 spinlock_t hrrq_lock[PMCRAID_NUM_MSIX_VECTORS];
647 704
705 struct pmcraid_inquiry_data *inq_data;
706 dma_addr_t inq_data_baddr;
707
708 /* size of configuration table entry, varies based on the firmware */
709 u32 config_table_entry_size;
710
648 /* Expected toggle bit at host */ 711 /* Expected toggle bit at host */
649 u8 host_toggle_bit[PMCRAID_NUM_MSIX_VECTORS]; 712 u8 host_toggle_bit[PMCRAID_NUM_MSIX_VECTORS];
650 713
651 /* No of Reset IOA retries . IOA marked dead if threshold exceeds */
652 u8 ioa_reset_attempts;
653#define PMCRAID_RESET_ATTEMPTS 3
654 714
655 /* Wait Q for threads to wait for Reset IOA completion */ 715 /* Wait Q for threads to wait for Reset IOA completion */
656 wait_queue_head_t reset_wait_q; 716 wait_queue_head_t reset_wait_q;
@@ -664,14 +724,22 @@ struct pmcraid_instance {
664 struct Scsi_Host *host; /* mid layer interface structure handle */ 724 struct Scsi_Host *host; /* mid layer interface structure handle */
665 struct pci_dev *pdev; /* PCI device structure handle */ 725 struct pci_dev *pdev; /* PCI device structure handle */
666 726
727 /* No of Reset IOA retries . IOA marked dead if threshold exceeds */
728 u8 ioa_reset_attempts;
729#define PMCRAID_RESET_ATTEMPTS 3
730
667 u8 current_log_level; /* default level for logging IOASC errors */ 731 u8 current_log_level; /* default level for logging IOASC errors */
668 732
669 u8 num_hrrq; /* Number of interrupt vectors allocated */ 733 u8 num_hrrq; /* Number of interrupt vectors allocated */
734 u8 interrupt_mode; /* current interrupt mode legacy or msix */
670 dev_t dev; /* Major-Minor numbers for Char device */ 735 dev_t dev; /* Major-Minor numbers for Char device */
671 736
672 /* Used as ISR handler argument */ 737 /* Used as ISR handler argument */
673 struct pmcraid_isr_param hrrq_vector[PMCRAID_NUM_MSIX_VECTORS]; 738 struct pmcraid_isr_param hrrq_vector[PMCRAID_NUM_MSIX_VECTORS];
674 739
740 /* Message id as filled in last fired IOARCB, used to identify HRRQ */
741 atomic_t last_message_id;
742
675 /* configuration table */ 743 /* configuration table */
676 struct pmcraid_config_table *cfg_table; 744 struct pmcraid_config_table *cfg_table;
677 dma_addr_t cfg_table_bus_addr; 745 dma_addr_t cfg_table_bus_addr;
@@ -686,8 +754,14 @@ struct pmcraid_instance {
686 754
687 struct list_head free_cmd_pool; 755 struct list_head free_cmd_pool;
688 struct list_head pending_cmd_pool; 756 struct list_head pending_cmd_pool;
689 spinlock_t free_pool_lock; /* free pool lock */ 757 spinlock_t free_pool_lock; /* free pool lock */
690 spinlock_t pending_pool_lock; /* pending pool lock */ 758 spinlock_t pending_pool_lock; /* pending pool lock */
759
760 /* Tasklet to handle deferred processing */
761 struct tasklet_struct isr_tasklet[PMCRAID_NUM_MSIX_VECTORS];
762
763 /* Work-queue (Shared) for deferred reset processing */
764 struct work_struct worker_q;
691 765
692 /* No of IO commands pending with FW */ 766 /* No of IO commands pending with FW */
693 atomic_t outstanding_cmds; 767 atomic_t outstanding_cmds;
@@ -695,11 +769,6 @@ struct pmcraid_instance {
695 /* should add/delete resources to mid-layer now ?*/ 769 /* should add/delete resources to mid-layer now ?*/
696 atomic_t expose_resources; 770 atomic_t expose_resources;
697 771
698 /* Tasklet to handle deferred processing */
699 struct tasklet_struct isr_tasklet[PMCRAID_NUM_MSIX_VECTORS];
700
701 /* Work-queue (Shared) for deferred reset processing */
702 struct work_struct worker_q;
703 772
704 773
705 u32 ioa_state:4; /* For IOA Reset sequence FSM */ 774 u32 ioa_state:4; /* For IOA Reset sequence FSM */
@@ -728,7 +797,10 @@ struct pmcraid_instance {
728/* LLD maintained resource entry structure */ 797/* LLD maintained resource entry structure */
729struct pmcraid_resource_entry { 798struct pmcraid_resource_entry {
730 struct list_head queue; /* link to "to be exposed" resources */ 799 struct list_head queue; /* link to "to be exposed" resources */
731 struct pmcraid_config_table_entry cfg_entry; 800 union {
801 struct pmcraid_config_table_entry cfg_entry;
802 struct pmcraid_config_table_entry_ext cfg_entry_ext;
803 };
732 struct scsi_device *scsi_dev; /* Link scsi_device structure */ 804 struct scsi_device *scsi_dev; /* Link scsi_device structure */
733 atomic_t read_failures; /* count of failed READ commands */ 805 atomic_t read_failures; /* count of failed READ commands */
734 atomic_t write_failures; /* count of failed WRITE commands */ 806 atomic_t write_failures; /* count of failed WRITE commands */
@@ -771,73 +843,75 @@ struct pmcraid_ioasc_error {
771 * statically. 843 * statically.
772 */ 844 */
773static struct pmcraid_ioasc_error pmcraid_ioasc_error_table[] = { 845static struct pmcraid_ioasc_error pmcraid_ioasc_error_table[] = {
774 {0x01180600, IOASC_LOG_LEVEL_MUST, 846 {0x01180600, IOASC_LOG_LEVEL_HARD,
775 "Recovered Error, soft media error, sector reassignment suggested"}, 847 "Recovered Error, soft media error, sector reassignment suggested"},
776 {0x015D0000, IOASC_LOG_LEVEL_MUST, 848 {0x015D0000, IOASC_LOG_LEVEL_HARD,
777 "Recovered Error, failure prediction threshold exceeded"}, 849 "Recovered Error, failure prediction thresold exceeded"},
778 {0x015D9200, IOASC_LOG_LEVEL_MUST, 850 {0x015D9200, IOASC_LOG_LEVEL_HARD,
779 "Recovered Error, soft Cache Card Battery error threshold"}, 851 "Recovered Error, soft Cache Card Battery error thresold"},
780 {0x015D9200, IOASC_LOG_LEVEL_MUST, 852 {0x015D9200, IOASC_LOG_LEVEL_HARD,
781 "Recovered Error, soft Cache Card Battery error threshold"}, 853 "Recovered Error, soft Cache Card Battery error thresold"},
782 {0x02048000, IOASC_LOG_LEVEL_MUST, 854 {0x02048000, IOASC_LOG_LEVEL_HARD,
783 "Not Ready, IOA Reset Required"}, 855 "Not Ready, IOA Reset Required"},
784 {0x02408500, IOASC_LOG_LEVEL_MUST, 856 {0x02408500, IOASC_LOG_LEVEL_HARD,
785 "Not Ready, IOA microcode download required"}, 857 "Not Ready, IOA microcode download required"},
786 {0x03110B00, IOASC_LOG_LEVEL_MUST, 858 {0x03110B00, IOASC_LOG_LEVEL_HARD,
787 "Medium Error, data unreadable, reassignment suggested"}, 859 "Medium Error, data unreadable, reassignment suggested"},
788 {0x03110C00, IOASC_LOG_LEVEL_MUST, 860 {0x03110C00, IOASC_LOG_LEVEL_MUST,
789 "Medium Error, data unreadable do not reassign"}, 861 "Medium Error, data unreadable do not reassign"},
790 {0x03310000, IOASC_LOG_LEVEL_MUST, 862 {0x03310000, IOASC_LOG_LEVEL_HARD,
791 "Medium Error, media corrupted"}, 863 "Medium Error, media corrupted"},
792 {0x04050000, IOASC_LOG_LEVEL_MUST, 864 {0x04050000, IOASC_LOG_LEVEL_HARD,
793 "Hardware Error, IOA can't communicate with device"}, 865 "Hardware Error, IOA can't communicate with device"},
794 {0x04080000, IOASC_LOG_LEVEL_MUST, 866 {0x04080000, IOASC_LOG_LEVEL_MUST,
795 "Hardware Error, device bus error"}, 867 "Hardware Error, device bus error"},
796 {0x04080000, IOASC_LOG_LEVEL_MUST, 868 {0x04088000, IOASC_LOG_LEVEL_MUST,
797 "Hardware Error, device bus is not functioning"}, 869 "Hardware Error, device bus is not functioning"},
798 {0x04118000, IOASC_LOG_LEVEL_MUST, 870 {0x04118000, IOASC_LOG_LEVEL_HARD,
799 "Hardware Error, IOA reserved area data check"}, 871 "Hardware Error, IOA reserved area data check"},
800 {0x04118100, IOASC_LOG_LEVEL_MUST, 872 {0x04118100, IOASC_LOG_LEVEL_HARD,
801 "Hardware Error, IOA reserved area invalid data pattern"}, 873 "Hardware Error, IOA reserved area invalid data pattern"},
802 {0x04118200, IOASC_LOG_LEVEL_MUST, 874 {0x04118200, IOASC_LOG_LEVEL_HARD,
803 "Hardware Error, IOA reserved area LRC error"}, 875 "Hardware Error, IOA reserved area LRC error"},
804 {0x04320000, IOASC_LOG_LEVEL_MUST, 876 {0x04320000, IOASC_LOG_LEVEL_HARD,
805 "Hardware Error, reassignment space exhausted"}, 877 "Hardware Error, reassignment space exhausted"},
806 {0x04330000, IOASC_LOG_LEVEL_MUST, 878 {0x04330000, IOASC_LOG_LEVEL_HARD,
807 "Hardware Error, data transfer underlength error"}, 879 "Hardware Error, data transfer underlength error"},
808 {0x04330000, IOASC_LOG_LEVEL_MUST, 880 {0x04330000, IOASC_LOG_LEVEL_HARD,
809 "Hardware Error, data transfer overlength error"}, 881 "Hardware Error, data transfer overlength error"},
810 {0x04418000, IOASC_LOG_LEVEL_MUST, 882 {0x04418000, IOASC_LOG_LEVEL_MUST,
811 "Hardware Error, PCI bus error"}, 883 "Hardware Error, PCI bus error"},
812 {0x04440000, IOASC_LOG_LEVEL_MUST, 884 {0x04440000, IOASC_LOG_LEVEL_HARD,
813 "Hardware Error, device error"}, 885 "Hardware Error, device error"},
814 {0x04448300, IOASC_LOG_LEVEL_MUST, 886 {0x04448200, IOASC_LOG_LEVEL_MUST,
887 "Hardware Error, IOA error"},
888 {0x04448300, IOASC_LOG_LEVEL_HARD,
815 "Hardware Error, undefined device response"}, 889 "Hardware Error, undefined device response"},
816 {0x04448400, IOASC_LOG_LEVEL_MUST, 890 {0x04448400, IOASC_LOG_LEVEL_HARD,
817 "Hardware Error, IOA microcode error"}, 891 "Hardware Error, IOA microcode error"},
818 {0x04448600, IOASC_LOG_LEVEL_MUST, 892 {0x04448600, IOASC_LOG_LEVEL_HARD,
819 "Hardware Error, IOA reset required"}, 893 "Hardware Error, IOA reset required"},
820 {0x04449200, IOASC_LOG_LEVEL_MUST, 894 {0x04449200, IOASC_LOG_LEVEL_HARD,
821 "Hardware Error, hard Cache Fearuee Card Battery error"}, 895 "Hardware Error, hard Cache Fearuee Card Battery error"},
822 {0x0444A000, IOASC_LOG_LEVEL_MUST, 896 {0x0444A000, IOASC_LOG_LEVEL_HARD,
823 "Hardware Error, failed device altered"}, 897 "Hardware Error, failed device altered"},
824 {0x0444A200, IOASC_LOG_LEVEL_MUST, 898 {0x0444A200, IOASC_LOG_LEVEL_HARD,
825 "Hardware Error, data check after reassignment"}, 899 "Hardware Error, data check after reassignment"},
826 {0x0444A300, IOASC_LOG_LEVEL_MUST, 900 {0x0444A300, IOASC_LOG_LEVEL_HARD,
827 "Hardware Error, LRC error after reassignment"}, 901 "Hardware Error, LRC error after reassignment"},
828 {0x044A0000, IOASC_LOG_LEVEL_MUST, 902 {0x044A0000, IOASC_LOG_LEVEL_HARD,
829 "Hardware Error, device bus error (msg/cmd phase)"}, 903 "Hardware Error, device bus error (msg/cmd phase)"},
830 {0x04670400, IOASC_LOG_LEVEL_MUST, 904 {0x04670400, IOASC_LOG_LEVEL_HARD,
831 "Hardware Error, new device can't be used"}, 905 "Hardware Error, new device can't be used"},
832 {0x04678000, IOASC_LOG_LEVEL_MUST, 906 {0x04678000, IOASC_LOG_LEVEL_HARD,
833 "Hardware Error, invalid multiadapter configuration"}, 907 "Hardware Error, invalid multiadapter configuration"},
834 {0x04678100, IOASC_LOG_LEVEL_MUST, 908 {0x04678100, IOASC_LOG_LEVEL_HARD,
835 "Hardware Error, incorrect connection between enclosures"}, 909 "Hardware Error, incorrect connection between enclosures"},
836 {0x04678200, IOASC_LOG_LEVEL_MUST, 910 {0x04678200, IOASC_LOG_LEVEL_HARD,
837 "Hardware Error, connections exceed IOA design limits"}, 911 "Hardware Error, connections exceed IOA design limits"},
838 {0x04678300, IOASC_LOG_LEVEL_MUST, 912 {0x04678300, IOASC_LOG_LEVEL_HARD,
839 "Hardware Error, incorrect multipath connection"}, 913 "Hardware Error, incorrect multipath connection"},
840 {0x04679000, IOASC_LOG_LEVEL_MUST, 914 {0x04679000, IOASC_LOG_LEVEL_HARD,
841 "Hardware Error, command to LUN failed"}, 915 "Hardware Error, command to LUN failed"},
842 {0x064C8000, IOASC_LOG_LEVEL_HARD, 916 {0x064C8000, IOASC_LOG_LEVEL_HARD,
843 "Unit Attention, cache exists for missing/failed device"}, 917 "Unit Attention, cache exists for missing/failed device"},
@@ -845,15 +919,15 @@ static struct pmcraid_ioasc_error pmcraid_ioasc_error_table[] = {
845 "Unit Attention, incompatible exposed mode device"}, 919 "Unit Attention, incompatible exposed mode device"},
846 {0x06670600, IOASC_LOG_LEVEL_HARD, 920 {0x06670600, IOASC_LOG_LEVEL_HARD,
847 "Unit Attention, attachment of logical unit failed"}, 921 "Unit Attention, attachment of logical unit failed"},
848 {0x06678000, IOASC_LOG_LEVEL_MUST, 922 {0x06678000, IOASC_LOG_LEVEL_HARD,
849 "Unit Attention, cables exceed connective design limit"}, 923 "Unit Attention, cables exceed connective design limit"},
850 {0x06678300, IOASC_LOG_LEVEL_MUST, 924 {0x06678300, IOASC_LOG_LEVEL_HARD,
851 "Unit Attention, incomplete multipath connection between" \ 925 "Unit Attention, incomplete multipath connection between" \
852 "IOA and enclosure"}, 926 "IOA and enclosure"},
853 {0x06678400, IOASC_LOG_LEVEL_MUST, 927 {0x06678400, IOASC_LOG_LEVEL_HARD,
854 "Unit Attention, incomplete multipath connection between" \ 928 "Unit Attention, incomplete multipath connection between" \
855 "device and enclosure"}, 929 "device and enclosure"},
856 {0x06678500, IOASC_LOG_LEVEL_MUST, 930 {0x06678500, IOASC_LOG_LEVEL_HARD,
857 "Unit Attention, incomplete multipath connection between" \ 931 "Unit Attention, incomplete multipath connection between" \
858 "IOA and remote IOA"}, 932 "IOA and remote IOA"},
859 {0x06678600, IOASC_LOG_LEVEL_HARD, 933 {0x06678600, IOASC_LOG_LEVEL_HARD,
@@ -863,11 +937,11 @@ static struct pmcraid_ioasc_error pmcraid_ioasc_error_table[] = {
863 "function"}, 937 "function"},
864 {0x06698200, IOASC_LOG_LEVEL_HARD, 938 {0x06698200, IOASC_LOG_LEVEL_HARD,
865 "Unit Attention, corrupt array parity detected on device"}, 939 "Unit Attention, corrupt array parity detected on device"},
866 {0x066B0200, IOASC_LOG_LEVEL_MUST, 940 {0x066B0200, IOASC_LOG_LEVEL_HARD,
867 "Unit Attention, array exposed"}, 941 "Unit Attention, array exposed"},
868 {0x066B8200, IOASC_LOG_LEVEL_HARD, 942 {0x066B8200, IOASC_LOG_LEVEL_HARD,
869 "Unit Attention, exposed array is still protected"}, 943 "Unit Attention, exposed array is still protected"},
870 {0x066B9200, IOASC_LOG_LEVEL_MUST, 944 {0x066B9200, IOASC_LOG_LEVEL_HARD,
871 "Unit Attention, Multipath redundancy level got worse"}, 945 "Unit Attention, Multipath redundancy level got worse"},
872 {0x07270000, IOASC_LOG_LEVEL_HARD, 946 {0x07270000, IOASC_LOG_LEVEL_HARD,
873 "Data Protect, device is read/write protected by IOA"}, 947 "Data Protect, device is read/write protected by IOA"},
@@ -875,37 +949,37 @@ static struct pmcraid_ioasc_error pmcraid_ioasc_error_table[] = {
875 "Data Protect, IOA doesn't support device attribute"}, 949 "Data Protect, IOA doesn't support device attribute"},
876 {0x07278100, IOASC_LOG_LEVEL_HARD, 950 {0x07278100, IOASC_LOG_LEVEL_HARD,
877 "Data Protect, NVRAM mirroring prohibited"}, 951 "Data Protect, NVRAM mirroring prohibited"},
878 {0x07278400, IOASC_LOG_LEVEL_MUST, 952 {0x07278400, IOASC_LOG_LEVEL_HARD,
879 "Data Protect, array is short 2 or more devices"}, 953 "Data Protect, array is short 2 or more devices"},
880 {0x07278600, IOASC_LOG_LEVEL_MUST, 954 {0x07278600, IOASC_LOG_LEVEL_HARD,
881 "Data Protect, exposed array is short a required device"}, 955 "Data Protect, exposed array is short a required device"},
882 {0x07278700, IOASC_LOG_LEVEL_MUST, 956 {0x07278700, IOASC_LOG_LEVEL_HARD,
883 "Data Protect, array members not at required addresses"}, 957 "Data Protect, array members not at required addresses"},
884 {0x07278800, IOASC_LOG_LEVEL_MUST, 958 {0x07278800, IOASC_LOG_LEVEL_HARD,
885 "Data Protect, exposed mode device resource address conflict"}, 959 "Data Protect, exposed mode device resource address conflict"},
886 {0x07278900, IOASC_LOG_LEVEL_MUST, 960 {0x07278900, IOASC_LOG_LEVEL_HARD,
887 "Data Protect, incorrect resource address of exposed mode device"}, 961 "Data Protect, incorrect resource address of exposed mode device"},
888 {0x07278A00, IOASC_LOG_LEVEL_MUST, 962 {0x07278A00, IOASC_LOG_LEVEL_HARD,
889 "Data Protect, Array is missing a device and parity is out of sync"}, 963 "Data Protect, Array is missing a device and parity is out of sync"},
890 {0x07278B00, IOASC_LOG_LEVEL_MUST, 964 {0x07278B00, IOASC_LOG_LEVEL_HARD,
891 "Data Protect, maximum number of arrays already exist"}, 965 "Data Protect, maximum number of arrays already exist"},
892 {0x07278C00, IOASC_LOG_LEVEL_HARD, 966 {0x07278C00, IOASC_LOG_LEVEL_HARD,
893 "Data Protect, cannot locate cache data for device"}, 967 "Data Protect, cannot locate cache data for device"},
894 {0x07278D00, IOASC_LOG_LEVEL_HARD, 968 {0x07278D00, IOASC_LOG_LEVEL_HARD,
895 "Data Protect, cache data exits for a changed device"}, 969 "Data Protect, cache data exits for a changed device"},
896 {0x07279100, IOASC_LOG_LEVEL_MUST, 970 {0x07279100, IOASC_LOG_LEVEL_HARD,
897 "Data Protect, detection of a device requiring format"}, 971 "Data Protect, detection of a device requiring format"},
898 {0x07279200, IOASC_LOG_LEVEL_MUST, 972 {0x07279200, IOASC_LOG_LEVEL_HARD,
899 "Data Protect, IOA exceeds maximum number of devices"}, 973 "Data Protect, IOA exceeds maximum number of devices"},
900 {0x07279600, IOASC_LOG_LEVEL_MUST, 974 {0x07279600, IOASC_LOG_LEVEL_HARD,
901 "Data Protect, missing array, volume set is not functional"}, 975 "Data Protect, missing array, volume set is not functional"},
902 {0x07279700, IOASC_LOG_LEVEL_MUST, 976 {0x07279700, IOASC_LOG_LEVEL_HARD,
903 "Data Protect, single device for a volume set"}, 977 "Data Protect, single device for a volume set"},
904 {0x07279800, IOASC_LOG_LEVEL_MUST, 978 {0x07279800, IOASC_LOG_LEVEL_HARD,
905 "Data Protect, missing multiple devices for a volume set"}, 979 "Data Protect, missing multiple devices for a volume set"},
906 {0x07279900, IOASC_LOG_LEVEL_HARD, 980 {0x07279900, IOASC_LOG_LEVEL_HARD,
907 "Data Protect, maximum number of volument sets already exists"}, 981 "Data Protect, maximum number of volument sets already exists"},
908 {0x07279A00, IOASC_LOG_LEVEL_MUST, 982 {0x07279A00, IOASC_LOG_LEVEL_HARD,
909 "Data Protect, other volume set problem"}, 983 "Data Protect, other volume set problem"},
910}; 984};
911 985
@@ -952,27 +1026,6 @@ struct pmcraid_ioctl_header {
952 1026
953#define PMCRAID_IOCTL_SIGNATURE "PMCRAID" 1027#define PMCRAID_IOCTL_SIGNATURE "PMCRAID"
954 1028
955
956/*
957 * pmcraid_event_details - defines AEN details that apps can retrieve from LLD
958 *
959 * .rcb_ccn - complete RCB of CCN
960 * .rcb_ldn - complete RCB of CCN
961 */
962struct pmcraid_event_details {
963 struct pmcraid_hcam_ccn rcb_ccn;
964 struct pmcraid_hcam_ldn rcb_ldn;
965};
966
967/*
968 * pmcraid_driver_ioctl_buffer - structure passed as argument to most of the
969 * PMC driver handled ioctls.
970 */
971struct pmcraid_driver_ioctl_buffer {
972 struct pmcraid_ioctl_header ioctl_header;
973 struct pmcraid_event_details event_details;
974};
975
976/* 1029/*
977 * pmcraid_passthrough_ioctl_buffer - structure given as argument to 1030 * pmcraid_passthrough_ioctl_buffer - structure given as argument to
978 * passthrough(or firmware handled) IOCTL commands. Note that ioarcb requires 1031 * passthrough(or firmware handled) IOCTL commands. Note that ioarcb requires