diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/scsi/megaraid/megaraid_mbox.c | 59 | ||||
| -rw-r--r-- | drivers/scsi/megaraid/megaraid_mbox.h | 7 |
2 files changed, 46 insertions, 20 deletions
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index c11e5ce6865e..bec1424eda85 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
| 11 | * | 11 | * |
| 12 | * FILE : megaraid_mbox.c | 12 | * FILE : megaraid_mbox.c |
| 13 | * Version : v2.20.4.7 (Nov 14 2005) | 13 | * Version : v2.20.4.8 (Apr 11 2006) |
| 14 | * | 14 | * |
| 15 | * Authors: | 15 | * Authors: |
| 16 | * Atul Mukker <Atul.Mukker@lsil.com> | 16 | * Atul Mukker <Atul.Mukker@lsil.com> |
| @@ -2278,6 +2278,7 @@ megaraid_mbox_dpc(unsigned long devp) | |||
| 2278 | unsigned long flags; | 2278 | unsigned long flags; |
| 2279 | uint8_t c; | 2279 | uint8_t c; |
| 2280 | int status; | 2280 | int status; |
| 2281 | uioc_t *kioc; | ||
| 2281 | 2282 | ||
| 2282 | 2283 | ||
| 2283 | if (!adapter) return; | 2284 | if (!adapter) return; |
| @@ -2320,6 +2321,9 @@ megaraid_mbox_dpc(unsigned long devp) | |||
| 2320 | // remove from local clist | 2321 | // remove from local clist |
| 2321 | list_del_init(&scb->list); | 2322 | list_del_init(&scb->list); |
| 2322 | 2323 | ||
| 2324 | kioc = (uioc_t *)scb->gp; | ||
| 2325 | kioc->status = 0; | ||
| 2326 | |||
| 2323 | megaraid_mbox_mm_done(adapter, scb); | 2327 | megaraid_mbox_mm_done(adapter, scb); |
| 2324 | 2328 | ||
| 2325 | continue; | 2329 | continue; |
| @@ -2636,6 +2640,7 @@ megaraid_reset_handler(struct scsi_cmnd *scp) | |||
| 2636 | int recovery_window; | 2640 | int recovery_window; |
| 2637 | int recovering; | 2641 | int recovering; |
| 2638 | int i; | 2642 | int i; |
| 2643 | uioc_t *kioc; | ||
| 2639 | 2644 | ||
| 2640 | adapter = SCP2ADAPTER(scp); | 2645 | adapter = SCP2ADAPTER(scp); |
| 2641 | raid_dev = ADAP2RAIDDEV(adapter); | 2646 | raid_dev = ADAP2RAIDDEV(adapter); |
| @@ -2655,32 +2660,51 @@ megaraid_reset_handler(struct scsi_cmnd *scp) | |||
| 2655 | // Also, reset all the commands currently owned by the driver | 2660 | // Also, reset all the commands currently owned by the driver |
| 2656 | spin_lock_irqsave(PENDING_LIST_LOCK(adapter), flags); | 2661 | spin_lock_irqsave(PENDING_LIST_LOCK(adapter), flags); |
| 2657 | list_for_each_entry_safe(scb, tmp, &adapter->pend_list, list) { | 2662 | list_for_each_entry_safe(scb, tmp, &adapter->pend_list, list) { |
| 2658 | |||
| 2659 | list_del_init(&scb->list); // from pending list | 2663 | list_del_init(&scb->list); // from pending list |
| 2660 | 2664 | ||
| 2661 | con_log(CL_ANN, (KERN_WARNING | 2665 | if (scb->sno >= MBOX_MAX_SCSI_CMDS) { |
| 2662 | "megaraid: %ld:%d[%d:%d], reset from pending list\n", | 2666 | con_log(CL_ANN, (KERN_WARNING |
| 2663 | scp->serial_number, scb->sno, | 2667 | "megaraid: IOCTL packet with %d[%d:%d] being reset\n", |
| 2664 | scb->dev_channel, scb->dev_target)); | 2668 | scb->sno, scb->dev_channel, scb->dev_target)); |
| 2665 | 2669 | ||
| 2666 | scp->result = (DID_RESET << 16); | 2670 | scb->status = -1; |
| 2667 | scp->scsi_done(scp); | ||
| 2668 | 2671 | ||
| 2669 | megaraid_dealloc_scb(adapter, scb); | 2672 | kioc = (uioc_t *)scb->gp; |
| 2673 | kioc->status = -EFAULT; | ||
| 2674 | |||
| 2675 | megaraid_mbox_mm_done(adapter, scb); | ||
| 2676 | } else { | ||
| 2677 | if (scb->scp == scp) { // Found command | ||
| 2678 | con_log(CL_ANN, (KERN_WARNING | ||
| 2679 | "megaraid: %ld:%d[%d:%d], reset from pending list\n", | ||
| 2680 | scp->serial_number, scb->sno, | ||
| 2681 | scb->dev_channel, scb->dev_target)); | ||
| 2682 | } else { | ||
| 2683 | con_log(CL_ANN, (KERN_WARNING | ||
| 2684 | "megaraid: IO packet with %d[%d:%d] being reset\n", | ||
| 2685 | scb->sno, scb->dev_channel, scb->dev_target)); | ||
| 2686 | } | ||
| 2687 | |||
| 2688 | scb->scp->result = (DID_RESET << 16); | ||
| 2689 | scb->scp->scsi_done(scb->scp); | ||
| 2690 | |||
| 2691 | megaraid_dealloc_scb(adapter, scb); | ||
| 2692 | } | ||
| 2670 | } | 2693 | } |
| 2671 | spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter), flags); | 2694 | spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter), flags); |
| 2672 | 2695 | ||
| 2673 | if (adapter->outstanding_cmds) { | 2696 | if (adapter->outstanding_cmds) { |
| 2674 | con_log(CL_ANN, (KERN_NOTICE | 2697 | con_log(CL_ANN, (KERN_NOTICE |
| 2675 | "megaraid: %d outstanding commands. Max wait %d sec\n", | 2698 | "megaraid: %d outstanding commands. Max wait %d sec\n", |
| 2676 | adapter->outstanding_cmds, MBOX_RESET_WAIT)); | 2699 | adapter->outstanding_cmds, |
| 2700 | (MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT))); | ||
| 2677 | } | 2701 | } |
| 2678 | 2702 | ||
| 2679 | recovery_window = MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT; | 2703 | recovery_window = MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT; |
| 2680 | 2704 | ||
| 2681 | recovering = adapter->outstanding_cmds; | 2705 | recovering = adapter->outstanding_cmds; |
| 2682 | 2706 | ||
| 2683 | for (i = 0; i < recovery_window && adapter->outstanding_cmds; i++) { | 2707 | for (i = 0; i < recovery_window; i++) { |
| 2684 | 2708 | ||
| 2685 | megaraid_ack_sequence(adapter); | 2709 | megaraid_ack_sequence(adapter); |
| 2686 | 2710 | ||
| @@ -2689,12 +2713,11 @@ megaraid_reset_handler(struct scsi_cmnd *scp) | |||
| 2689 | con_log(CL_ANN, ( | 2713 | con_log(CL_ANN, ( |
| 2690 | "megaraid mbox: Wait for %d commands to complete:%d\n", | 2714 | "megaraid mbox: Wait for %d commands to complete:%d\n", |
| 2691 | adapter->outstanding_cmds, | 2715 | adapter->outstanding_cmds, |
| 2692 | MBOX_RESET_WAIT - i)); | 2716 | (MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT) - i)); |
| 2693 | } | 2717 | } |
| 2694 | 2718 | ||
| 2695 | // bailout if no recovery happended in reset time | 2719 | // bailout if no recovery happended in reset time |
| 2696 | if ((i == MBOX_RESET_WAIT) && | 2720 | if (adapter->outstanding_cmds == 0) { |
| 2697 | (recovering == adapter->outstanding_cmds)) { | ||
| 2698 | break; | 2721 | break; |
| 2699 | } | 2722 | } |
| 2700 | 2723 | ||
| @@ -2918,12 +2941,13 @@ mbox_post_sync_cmd_fast(adapter_t *adapter, uint8_t raw_mbox[]) | |||
| 2918 | wmb(); | 2941 | wmb(); |
| 2919 | WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x1); | 2942 | WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x1); |
| 2920 | 2943 | ||
| 2921 | for (i = 0; i < 0xFFFFF; i++) { | 2944 | for (i = 0; i < MBOX_SYNC_WAIT_CNT; i++) { |
| 2922 | if (mbox->numstatus != 0xFF) break; | 2945 | if (mbox->numstatus != 0xFF) break; |
| 2923 | rmb(); | 2946 | rmb(); |
| 2947 | udelay(MBOX_SYNC_DELAY_200); | ||
| 2924 | } | 2948 | } |
| 2925 | 2949 | ||
| 2926 | if (i == 0xFFFFF) { | 2950 | if (i == MBOX_SYNC_WAIT_CNT) { |
| 2927 | // We may need to re-calibrate the counter | 2951 | // We may need to re-calibrate the counter |
| 2928 | con_log(CL_ANN, (KERN_CRIT | 2952 | con_log(CL_ANN, (KERN_CRIT |
| 2929 | "megaraid: fast sync command timed out\n")); | 2953 | "megaraid: fast sync command timed out\n")); |
| @@ -3475,7 +3499,7 @@ megaraid_cmm_register(adapter_t *adapter) | |||
| 3475 | adp.drvr_data = (unsigned long)adapter; | 3499 | adp.drvr_data = (unsigned long)adapter; |
| 3476 | adp.pdev = adapter->pdev; | 3500 | adp.pdev = adapter->pdev; |
| 3477 | adp.issue_uioc = megaraid_mbox_mm_handler; | 3501 | adp.issue_uioc = megaraid_mbox_mm_handler; |
| 3478 | adp.timeout = 300; | 3502 | adp.timeout = MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT; |
| 3479 | adp.max_kioc = MBOX_MAX_USER_CMDS; | 3503 | adp.max_kioc = MBOX_MAX_USER_CMDS; |
| 3480 | 3504 | ||
| 3481 | if ((rval = mraid_mm_register_adp(&adp)) != 0) { | 3505 | if ((rval = mraid_mm_register_adp(&adp)) != 0) { |
| @@ -3702,7 +3726,6 @@ megaraid_mbox_mm_done(adapter_t *adapter, scb_t *scb) | |||
| 3702 | unsigned long flags; | 3726 | unsigned long flags; |
| 3703 | 3727 | ||
| 3704 | kioc = (uioc_t *)scb->gp; | 3728 | kioc = (uioc_t *)scb->gp; |
| 3705 | kioc->status = 0; | ||
| 3706 | mbox64 = (mbox64_t *)(unsigned long)kioc->cmdbuf; | 3729 | mbox64 = (mbox64_t *)(unsigned long)kioc->cmdbuf; |
| 3707 | mbox64->mbox32.status = scb->status; | 3730 | mbox64->mbox32.status = scb->status; |
| 3708 | raw_mbox = (uint8_t *)&mbox64->mbox32; | 3731 | raw_mbox = (uint8_t *)&mbox64->mbox32; |
diff --git a/drivers/scsi/megaraid/megaraid_mbox.h b/drivers/scsi/megaraid/megaraid_mbox.h index 882fb1a0b575..868fb0ec93e7 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.h +++ b/drivers/scsi/megaraid/megaraid_mbox.h | |||
| @@ -21,8 +21,8 @@ | |||
| 21 | #include "megaraid_ioctl.h" | 21 | #include "megaraid_ioctl.h" |
| 22 | 22 | ||
| 23 | 23 | ||
| 24 | #define MEGARAID_VERSION "2.20.4.7" | 24 | #define MEGARAID_VERSION "2.20.4.8" |
| 25 | #define MEGARAID_EXT_VERSION "(Release Date: Mon Nov 14 12:27:22 EST 2005)" | 25 | #define MEGARAID_EXT_VERSION "(Release Date: Mon Apr 11 12:27:22 EST 2006)" |
| 26 | 26 | ||
| 27 | 27 | ||
| 28 | /* | 28 | /* |
| @@ -100,6 +100,9 @@ | |||
| 100 | #define MBOX_BUSY_WAIT 10 // max usec to wait for busy mailbox | 100 | #define MBOX_BUSY_WAIT 10 // max usec to wait for busy mailbox |
| 101 | #define MBOX_RESET_WAIT 180 // wait these many seconds in reset | 101 | #define MBOX_RESET_WAIT 180 // wait these many seconds in reset |
| 102 | #define MBOX_RESET_EXT_WAIT 120 // extended wait reset | 102 | #define MBOX_RESET_EXT_WAIT 120 // extended wait reset |
| 103 | #define MBOX_SYNC_WAIT_CNT 0xFFFF // wait loop index for synchronous mode | ||
| 104 | |||
| 105 | #define MBOX_SYNC_DELAY_200 200 // 200 micro-seconds | ||
| 103 | 106 | ||
| 104 | /* | 107 | /* |
| 105 | * maximum transfer that can happen through the firmware commands issued | 108 | * maximum transfer that can happen through the firmware commands issued |
