aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnil Ravindranath <anil_ravindranath@pmc-sierra.com>2010-06-08 13:56:34 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 13:01:35 -0400
commitc20c426732a5a5d21e99b36286f79c2024115341 (patch)
treea4fd06a0caba3fca41b8f65e7c50582bfa1f64a7
parent18cacc34887df274feb3f1ff420d7592e4ea246f (diff)
[SCSI] pmcraid: MSI-X support and other changes
1. MSI-X interrupt support 2. Driver changes to support new maxRAID controller FW version. The changes are mainly done to handle async notification changes done in newer controller FW version. 3. Added state change notifications to notify applications of controller states. Signed-off-by: Anil Ravindranath <anil_ravindranath@pmc-sierra.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-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