aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid/megaraid_mbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/megaraid/megaraid_mbox.c')
-rw-r--r--drivers/scsi/megaraid/megaraid_mbox.c140
1 files changed, 112 insertions, 28 deletions
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index 7bac86dda88f..49ee50cc4e84 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -10,13 +10,13 @@
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.9 (Jul 16 2006) 13 * Version : v2.20.5.1 (Nov 16 2006)
14 * 14 *
15 * Authors: 15 * Authors:
16 * Atul Mukker <Atul.Mukker@lsil.com> 16 * Atul Mukker <Atul.Mukker@lsi.com>
17 * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com> 17 * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsi.com>
18 * Manoj Jose <Manoj.Jose@lsil.com> 18 * Manoj Jose <Manoj.Jose@lsi.com>
19 * Seokmann Ju <Seokmann.Ju@lsil.com> 19 * Seokmann Ju
20 * 20 *
21 * List of supported controllers 21 * List of supported controllers
22 * 22 *
@@ -107,6 +107,7 @@ static int megaraid_mbox_support_random_del(adapter_t *);
107static int megaraid_mbox_get_max_sg(adapter_t *); 107static int megaraid_mbox_get_max_sg(adapter_t *);
108static void megaraid_mbox_enum_raid_scsi(adapter_t *); 108static void megaraid_mbox_enum_raid_scsi(adapter_t *);
109static void megaraid_mbox_flush_cache(adapter_t *); 109static void megaraid_mbox_flush_cache(adapter_t *);
110static int megaraid_mbox_fire_sync_cmd(adapter_t *);
110 111
111static void megaraid_mbox_display_scb(adapter_t *, scb_t *); 112static void megaraid_mbox_display_scb(adapter_t *, scb_t *);
112static void megaraid_mbox_setup_device_map(adapter_t *); 113static void megaraid_mbox_setup_device_map(adapter_t *);
@@ -137,7 +138,7 @@ static int wait_till_fw_empty(adapter_t *);
137 138
138 139
139 140
140MODULE_AUTHOR("sju@lsil.com"); 141MODULE_AUTHOR("megaraidlinux@lsi.com");
141MODULE_DESCRIPTION("LSI Logic MegaRAID Mailbox Driver"); 142MODULE_DESCRIPTION("LSI Logic MegaRAID Mailbox Driver");
142MODULE_LICENSE("GPL"); 143MODULE_LICENSE("GPL");
143MODULE_VERSION(MEGARAID_VERSION); 144MODULE_VERSION(MEGARAID_VERSION);
@@ -779,33 +780,39 @@ megaraid_init_mbox(adapter_t *adapter)
779 goto out_release_regions; 780 goto out_release_regions;
780 } 781 }
781 782
782 // 783 /* initialize the mutual exclusion lock for the mailbox */
783 // Setup the rest of the soft state using the library of FW routines 784 spin_lock_init(&raid_dev->mailbox_lock);
784 // 785
786 /* allocate memory required for commands */
787 if (megaraid_alloc_cmd_packets(adapter) != 0)
788 goto out_iounmap;
785 789
786 // request IRQ and register the interrupt service routine 790 /*
791 * Issue SYNC cmd to flush the pending cmds in the adapter
792 * and initialize its internal state
793 */
794
795 if (megaraid_mbox_fire_sync_cmd(adapter))
796 con_log(CL_ANN, ("megaraid: sync cmd failed\n"));
797
798 /*
799 * Setup the rest of the soft state using the library of
800 * FW routines
801 */
802
803 /* request IRQ and register the interrupt service routine */
787 if (request_irq(adapter->irq, megaraid_isr, IRQF_SHARED, "megaraid", 804 if (request_irq(adapter->irq, megaraid_isr, IRQF_SHARED, "megaraid",
788 adapter)) { 805 adapter)) {
789 806
790 con_log(CL_ANN, (KERN_WARNING 807 con_log(CL_ANN, (KERN_WARNING
791 "megaraid: Couldn't register IRQ %d!\n", adapter->irq)); 808 "megaraid: Couldn't register IRQ %d!\n", adapter->irq));
809 goto out_alloc_cmds;
792 810
793 goto out_iounmap;
794 }
795
796
797 // initialize the mutual exclusion lock for the mailbox
798 spin_lock_init(&raid_dev->mailbox_lock);
799
800 // allocate memory required for commands
801 if (megaraid_alloc_cmd_packets(adapter) != 0) {
802 goto out_free_irq;
803 } 811 }
804 812
805 // Product info 813 // Product info
806 if (megaraid_mbox_product_info(adapter) != 0) { 814 if (megaraid_mbox_product_info(adapter) != 0)
807 goto out_alloc_cmds; 815 goto out_free_irq;
808 }
809 816
810 // Do we support extended CDBs 817 // Do we support extended CDBs
811 adapter->max_cdb_sz = 10; 818 adapter->max_cdb_sz = 10;
@@ -874,9 +881,8 @@ megaraid_init_mbox(adapter_t *adapter)
874 * Allocate resources required to issue FW calls, when sysfs is 881 * Allocate resources required to issue FW calls, when sysfs is
875 * accessed 882 * accessed
876 */ 883 */
877 if (megaraid_sysfs_alloc_resources(adapter) != 0) { 884 if (megaraid_sysfs_alloc_resources(adapter) != 0)
878 goto out_alloc_cmds; 885 goto out_free_irq;
879 }
880 886
881 // Set the DMA mask to 64-bit. All supported controllers as capable of 887 // Set the DMA mask to 64-bit. All supported controllers as capable of
882 // DMA in this range 888 // DMA in this range
@@ -920,10 +926,10 @@ megaraid_init_mbox(adapter_t *adapter)
920 926
921out_free_sysfs_res: 927out_free_sysfs_res:
922 megaraid_sysfs_free_resources(adapter); 928 megaraid_sysfs_free_resources(adapter);
923out_alloc_cmds:
924 megaraid_free_cmd_packets(adapter);
925out_free_irq: 929out_free_irq:
926 free_irq(adapter->irq, adapter); 930 free_irq(adapter->irq, adapter);
931out_alloc_cmds:
932 megaraid_free_cmd_packets(adapter);
927out_iounmap: 933out_iounmap:
928 iounmap(raid_dev->baseaddr); 934 iounmap(raid_dev->baseaddr);
929out_release_regions: 935out_release_regions:
@@ -3380,6 +3386,84 @@ megaraid_mbox_flush_cache(adapter_t *adapter)
3380 3386
3381 3387
3382/** 3388/**
3389 * megaraid_mbox_fire_sync_cmd - fire the sync cmd
3390 * @param adapter : soft state for the controller
3391 *
3392 * Clears the pending cmds in FW and reinits its RAID structs
3393 */
3394static int
3395megaraid_mbox_fire_sync_cmd(adapter_t *adapter)
3396{
3397 mbox_t *mbox;
3398 uint8_t raw_mbox[sizeof(mbox_t)];
3399 mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter);
3400 mbox64_t *mbox64;
3401 int status = 0;
3402 int i;
3403 uint32_t dword;
3404
3405 mbox = (mbox_t *)raw_mbox;
3406
3407 memset((caddr_t)raw_mbox, 0, sizeof(mbox_t));
3408
3409 raw_mbox[0] = 0xFF;
3410
3411 mbox64 = raid_dev->mbox64;
3412 mbox = raid_dev->mbox;
3413
3414 /* Wait until mailbox is free */
3415 if (megaraid_busywait_mbox(raid_dev) != 0) {
3416 status = 1;
3417 goto blocked_mailbox;
3418 }
3419
3420 /* Copy mailbox data into host structure */
3421 memcpy((caddr_t)mbox, (caddr_t)raw_mbox, 16);
3422 mbox->cmdid = 0xFE;
3423 mbox->busy = 1;
3424 mbox->poll = 0;
3425 mbox->ack = 0;
3426 mbox->numstatus = 0;
3427 mbox->status = 0;
3428
3429 wmb();
3430 WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x1);
3431
3432 /* Wait for maximum 1 min for status to post.
3433 * If the Firmware SUPPORTS the ABOVE COMMAND,
3434 * mbox->cmd will be set to 0
3435 * else
3436 * the firmware will reject the command with
3437 * mbox->numstatus set to 1
3438 */
3439
3440 i = 0;
3441 status = 0;
3442 while (!mbox->numstatus && mbox->cmd == 0xFF) {
3443 rmb();
3444 msleep(1);
3445 i++;
3446 if (i > 1000 * 60) {
3447 status = 1;
3448 break;
3449 }
3450 }
3451 if (mbox->numstatus == 1)
3452 status = 1; /*cmd not supported*/
3453
3454 /* Check for interrupt line */
3455 dword = RDOUTDOOR(raid_dev);
3456 WROUTDOOR(raid_dev, dword);
3457 WRINDOOR(raid_dev,2);
3458
3459 return status;
3460
3461blocked_mailbox:
3462 con_log(CL_ANN, (KERN_WARNING "megaraid: blocked mailbox\n"));
3463 return status;
3464}
3465
3466/**
3383 * megaraid_mbox_display_scb - display SCB information, mostly debug purposes 3467 * megaraid_mbox_display_scb - display SCB information, mostly debug purposes
3384 * @param adapter : controllers' soft state 3468 * @param adapter : controllers' soft state
3385 * @param scb : SCB to be displayed 3469 * @param scb : SCB to be displayed