aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authoradam radford <aradford@gmail.com>2010-12-21 13:23:23 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-12-23 00:26:52 -0500
commitcd50ba8ede5cd3c4606a8e5d163913da5ff36ad7 (patch)
treed4353f5a3b622df47a39bfa84744c5f7e5c9e417 /drivers/scsi
parentb6d5d8808b4c563a56414a4c4c6d652b5f87c088 (diff)
[SCSI] megaraid_sas: Add struct megasas_instance_template changes
The following patch adds struct megasas_instance_template changes to the megaraid_sas driver, and changes all code to use the new instance entries: irqreturn_t (*service_isr )(int irq, void *devp); void (*tasklet)(unsigned long); u32 (*init_adapter)(struct megasas_instance *); u32 (*build_and_issue_cmd) (struct megasas_instance *, struct scsi_cmnd *); void (*issue_dcmd) (struct megasas_instance *instance, struct megasas_cmd *cmd); Signed-off-by: Adam Radford <aradford@gmail.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h7
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_base.c278
2 files changed, 180 insertions, 105 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 0e09a0ff479d..a0b8ee1a5d2d 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1364,6 +1364,13 @@ struct megasas_instance_template {
1364 struct megasas_register_set __iomem *); 1364 struct megasas_register_set __iomem *);
1365 int (*check_reset)(struct megasas_instance *, \ 1365 int (*check_reset)(struct megasas_instance *, \
1366 struct megasas_register_set __iomem *); 1366 struct megasas_register_set __iomem *);
1367 irqreturn_t (*service_isr)(int irq, void *devp);
1368 void (*tasklet)(unsigned long);
1369 u32 (*init_adapter)(struct megasas_instance *);
1370 u32 (*build_and_issue_cmd) (struct megasas_instance *,
1371 struct scsi_cmnd *);
1372 void (*issue_dcmd) (struct megasas_instance *instance,
1373 struct megasas_cmd *cmd);
1367}; 1374};
1368 1375
1369#define MEGASAS_IS_LOGICAL(scp) \ 1376#define MEGASAS_IS_LOGICAL(scp) \
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 6e7bb7ca9869..5938267e472b 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -131,6 +131,20 @@ spinlock_t poll_aen_lock;
131static void 131static void
132megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, 132megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
133 u8 alt_status); 133 u8 alt_status);
134static irqreturn_t megasas_isr(int irq, void *devp);
135static u32
136megasas_init_adapter_mfi(struct megasas_instance *instance);
137u32
138megasas_build_and_issue_cmd(struct megasas_instance *instance,
139 struct scsi_cmnd *scmd);
140static void megasas_complete_cmd_dpc(unsigned long instance_addr);
141
142void
143megasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
144{
145 instance->instancet->fire_cmd(instance,
146 cmd->frame_phys_addr, 0, instance->reg_set);
147}
134 148
135/** 149/**
136 * megasas_get_cmd - Get a command from the free pool 150 * megasas_get_cmd - Get a command from the free pool
@@ -334,6 +348,11 @@ static struct megasas_instance_template megasas_instance_template_xscale = {
334 .read_fw_status_reg = megasas_read_fw_status_reg_xscale, 348 .read_fw_status_reg = megasas_read_fw_status_reg_xscale,
335 .adp_reset = megasas_adp_reset_xscale, 349 .adp_reset = megasas_adp_reset_xscale,
336 .check_reset = megasas_check_reset_xscale, 350 .check_reset = megasas_check_reset_xscale,
351 .service_isr = megasas_isr,
352 .tasklet = megasas_complete_cmd_dpc,
353 .init_adapter = megasas_init_adapter_mfi,
354 .build_and_issue_cmd = megasas_build_and_issue_cmd,
355 .issue_dcmd = megasas_issue_dcmd,
337}; 356};
338 357
339/** 358/**
@@ -460,6 +479,11 @@ static struct megasas_instance_template megasas_instance_template_ppc = {
460 .read_fw_status_reg = megasas_read_fw_status_reg_ppc, 479 .read_fw_status_reg = megasas_read_fw_status_reg_ppc,
461 .adp_reset = megasas_adp_reset_ppc, 480 .adp_reset = megasas_adp_reset_ppc,
462 .check_reset = megasas_check_reset_ppc, 481 .check_reset = megasas_check_reset_ppc,
482 .service_isr = megasas_isr,
483 .tasklet = megasas_complete_cmd_dpc,
484 .init_adapter = megasas_init_adapter_mfi,
485 .build_and_issue_cmd = megasas_build_and_issue_cmd,
486 .issue_dcmd = megasas_issue_dcmd,
463}; 487};
464 488
465/** 489/**
@@ -581,6 +605,11 @@ static struct megasas_instance_template megasas_instance_template_skinny = {
581 .read_fw_status_reg = megasas_read_fw_status_reg_skinny, 605 .read_fw_status_reg = megasas_read_fw_status_reg_skinny,
582 .adp_reset = megasas_adp_reset_skinny, 606 .adp_reset = megasas_adp_reset_skinny,
583 .check_reset = megasas_check_reset_skinny, 607 .check_reset = megasas_check_reset_skinny,
608 .service_isr = megasas_isr,
609 .tasklet = megasas_complete_cmd_dpc,
610 .init_adapter = megasas_init_adapter_mfi,
611 .build_and_issue_cmd = megasas_build_and_issue_cmd,
612 .issue_dcmd = megasas_issue_dcmd,
584}; 613};
585 614
586 615
@@ -755,6 +784,11 @@ static struct megasas_instance_template megasas_instance_template_gen2 = {
755 .read_fw_status_reg = megasas_read_fw_status_reg_gen2, 784 .read_fw_status_reg = megasas_read_fw_status_reg_gen2,
756 .adp_reset = megasas_adp_reset_gen2, 785 .adp_reset = megasas_adp_reset_gen2,
757 .check_reset = megasas_check_reset_gen2, 786 .check_reset = megasas_check_reset_gen2,
787 .service_isr = megasas_isr,
788 .tasklet = megasas_complete_cmd_dpc,
789 .init_adapter = megasas_init_adapter_mfi,
790 .build_and_issue_cmd = megasas_build_and_issue_cmd,
791 .issue_dcmd = megasas_issue_dcmd,
758}; 792};
759 793
760/** 794/**
@@ -1339,6 +1373,51 @@ megasas_dump_pending_frames(struct megasas_instance *instance)
1339 printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no); 1373 printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no);
1340} 1374}
1341 1375
1376u32
1377megasas_build_and_issue_cmd(struct megasas_instance *instance,
1378 struct scsi_cmnd *scmd)
1379{
1380 struct megasas_cmd *cmd;
1381 u32 frame_count;
1382
1383 cmd = megasas_get_cmd(instance);
1384 if (!cmd)
1385 return SCSI_MLQUEUE_HOST_BUSY;
1386
1387 /*
1388 * Logical drive command
1389 */
1390 if (megasas_is_ldio(scmd))
1391 frame_count = megasas_build_ldio(instance, scmd, cmd);
1392 else
1393 frame_count = megasas_build_dcdb(instance, scmd, cmd);
1394
1395 if (!frame_count)
1396 goto out_return_cmd;
1397
1398 cmd->scmd = scmd;
1399 scmd->SCp.ptr = (char *)cmd;
1400
1401 /*
1402 * Issue the command to the FW
1403 */
1404 atomic_inc(&instance->fw_outstanding);
1405
1406 instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
1407 cmd->frame_count-1, instance->reg_set);
1408 /*
1409 * Check if we have pend cmds to be completed
1410 */
1411 if (poll_mode_io && atomic_read(&instance->fw_outstanding))
1412 tasklet_schedule(&instance->isr_tasklet);
1413
1414 return 0;
1415out_return_cmd:
1416 megasas_return_cmd(instance, cmd);
1417 return 1;
1418}
1419
1420
1342/** 1421/**
1343 * megasas_queue_command - Queue entry point 1422 * megasas_queue_command - Queue entry point
1344 * @scmd: SCSI command to be queued 1423 * @scmd: SCSI command to be queued
@@ -1347,8 +1426,6 @@ megasas_dump_pending_frames(struct megasas_instance *instance)
1347static int 1426static int
1348megasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) 1427megasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
1349{ 1428{
1350 u32 frame_count;
1351 struct megasas_cmd *cmd;
1352 struct megasas_instance *instance; 1429 struct megasas_instance *instance;
1353 unsigned long flags; 1430 unsigned long flags;
1354 1431
@@ -1387,42 +1464,13 @@ megasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd
1387 break; 1464 break;
1388 } 1465 }
1389 1466
1390 cmd = megasas_get_cmd(instance); 1467 if (instance->instancet->build_and_issue_cmd(instance, scmd)) {
1391 if (!cmd) 1468 printk(KERN_ERR "megasas: Err returned from build_and_issue_cmd\n");
1392 return SCSI_MLQUEUE_HOST_BUSY; 1469 return SCSI_MLQUEUE_HOST_BUSY;
1393 1470 }
1394 /*
1395 * Logical drive command
1396 */
1397 if (megasas_is_ldio(scmd))
1398 frame_count = megasas_build_ldio(instance, scmd, cmd);
1399 else
1400 frame_count = megasas_build_dcdb(instance, scmd, cmd);
1401
1402 if (!frame_count)
1403 goto out_return_cmd;
1404
1405 cmd->scmd = scmd;
1406 scmd->SCp.ptr = (char *)cmd;
1407
1408 /*
1409 * Issue the command to the FW
1410 */
1411 atomic_inc(&instance->fw_outstanding);
1412
1413 instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
1414 cmd->frame_count-1, instance->reg_set);
1415 /*
1416 * Check if we have pend cmds to be completed
1417 */
1418 if (poll_mode_io && atomic_read(&instance->fw_outstanding))
1419 tasklet_schedule(&instance->isr_tasklet);
1420
1421 1471
1422 return 0; 1472 return 0;
1423 1473
1424 out_return_cmd:
1425 megasas_return_cmd(instance, cmd);
1426 out_done: 1474 out_done:
1427 done(scmd); 1475 done(scmd);
1428 return 0; 1476 return 0;
@@ -3221,69 +3269,15 @@ megasas_io_completion_timer(unsigned long instance_addr)
3221 jiffies + MEGASAS_COMPLETION_TIMER_INTERVAL); 3269 jiffies + MEGASAS_COMPLETION_TIMER_INTERVAL);
3222} 3270}
3223 3271
3224/** 3272static u32
3225 * megasas_init_mfi - Initializes the FW 3273megasas_init_adapter_mfi(struct megasas_instance *instance)
3226 * @instance: Adapter soft state
3227 *
3228 * This is the main function for initializing MFI firmware.
3229 */
3230static int megasas_init_mfi(struct megasas_instance *instance)
3231{ 3274{
3275 struct megasas_register_set __iomem *reg_set;
3232 u32 context_sz; 3276 u32 context_sz;
3233 u32 reply_q_sz; 3277 u32 reply_q_sz;
3234 u32 max_sectors_1;
3235 u32 max_sectors_2;
3236 u32 tmp_sectors;
3237 struct megasas_register_set __iomem *reg_set;
3238 struct megasas_ctrl_info *ctrl_info;
3239 unsigned long bar_list;
3240
3241 /* Find first memory bar */
3242 bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
3243 instance->bar = find_first_bit(&bar_list, sizeof(unsigned long));
3244 instance->base_addr = pci_resource_start(instance->pdev, instance->bar);
3245 if (pci_request_selected_regions(instance->pdev, instance->bar,
3246 "megasas: LSI")) {
3247 printk(KERN_DEBUG "megasas: IO memory region busy!\n");
3248 return -EBUSY;
3249 }
3250
3251 instance->reg_set = ioremap_nocache(instance->base_addr, 8192);
3252
3253 if (!instance->reg_set) {
3254 printk(KERN_DEBUG "megasas: Failed to map IO mem\n");
3255 goto fail_ioremap;
3256 }
3257 3278
3258 reg_set = instance->reg_set; 3279 reg_set = instance->reg_set;
3259 3280
3260 switch(instance->pdev->device)
3261 {
3262 case PCI_DEVICE_ID_LSI_SAS1078R:
3263 case PCI_DEVICE_ID_LSI_SAS1078DE:
3264 instance->instancet = &megasas_instance_template_ppc;
3265 break;
3266 case PCI_DEVICE_ID_LSI_SAS1078GEN2:
3267 case PCI_DEVICE_ID_LSI_SAS0079GEN2:
3268 instance->instancet = &megasas_instance_template_gen2;
3269 break;
3270 case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
3271 case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
3272 instance->instancet = &megasas_instance_template_skinny;
3273 break;
3274 case PCI_DEVICE_ID_LSI_SAS1064R:
3275 case PCI_DEVICE_ID_DELL_PERC5:
3276 default:
3277 instance->instancet = &megasas_instance_template_xscale;
3278 break;
3279 }
3280
3281 /*
3282 * We expect the FW state to be READY
3283 */
3284 if (megasas_transition_to_ready(instance))
3285 goto fail_ready_state;
3286
3287 /* 3281 /*
3288 * Get various operational parameters from status register 3282 * Get various operational parameters from status register
3289 */ 3283 */
@@ -3337,6 +3331,87 @@ static int megasas_init_mfi(struct megasas_instance *instance)
3337 if (instance->fw_support_ieee) 3331 if (instance->fw_support_ieee)
3338 instance->flag_ieee = 1; 3332 instance->flag_ieee = 1;
3339 3333
3334 return 0;
3335
3336fail_fw_init:
3337
3338 pci_free_consistent(instance->pdev, reply_q_sz,
3339 instance->reply_queue, instance->reply_queue_h);
3340fail_reply_queue:
3341 megasas_free_cmds(instance);
3342
3343fail_alloc_cmds:
3344 iounmap(instance->reg_set);
3345 return 1;
3346}
3347
3348/**
3349 * megasas_init_fw - Initializes the FW
3350 * @instance: Adapter soft state
3351 *
3352 * This is the main function for initializing firmware
3353 */
3354
3355static int megasas_init_fw(struct megasas_instance *instance)
3356{
3357 u32 max_sectors_1;
3358 u32 max_sectors_2;
3359 u32 tmp_sectors;
3360 struct megasas_register_set __iomem *reg_set;
3361 struct megasas_ctrl_info *ctrl_info;
3362 unsigned long bar_list;
3363
3364 /* Find first memory bar */
3365 bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
3366 instance->bar = find_first_bit(&bar_list, sizeof(unsigned long));
3367 instance->base_addr = pci_resource_start(instance->pdev, instance->bar);
3368 if (pci_request_selected_regions(instance->pdev, instance->bar,
3369 "megasas: LSI")) {
3370 printk(KERN_DEBUG "megasas: IO memory region busy!\n");
3371 return -EBUSY;
3372 }
3373
3374 instance->reg_set = ioremap_nocache(instance->base_addr, 8192);
3375
3376 if (!instance->reg_set) {
3377 printk(KERN_DEBUG "megasas: Failed to map IO mem\n");
3378 goto fail_ioremap;
3379 }
3380
3381 reg_set = instance->reg_set;
3382
3383 switch (instance->pdev->device) {
3384 case PCI_DEVICE_ID_LSI_SAS1078R:
3385 case PCI_DEVICE_ID_LSI_SAS1078DE:
3386 instance->instancet = &megasas_instance_template_ppc;
3387 break;
3388 case PCI_DEVICE_ID_LSI_SAS1078GEN2:
3389 case PCI_DEVICE_ID_LSI_SAS0079GEN2:
3390 instance->instancet = &megasas_instance_template_gen2;
3391 break;
3392 case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
3393 case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
3394 instance->instancet = &megasas_instance_template_skinny;
3395 break;
3396 case PCI_DEVICE_ID_LSI_SAS1064R:
3397 case PCI_DEVICE_ID_DELL_PERC5:
3398 default:
3399 instance->instancet = &megasas_instance_template_xscale;
3400 break;
3401 }
3402
3403 /*
3404 * We expect the FW state to be READY
3405 */
3406 if (megasas_transition_to_ready(instance))
3407 goto fail_ready_state;
3408
3409 /* Get operational params, sge flags, send init cmd to controller */
3410 if (instance->instancet->init_adapter(instance))
3411 return -ENODEV;
3412
3413 printk(KERN_ERR "megasas: INIT adapter done\n");
3414
3340 /** for passthrough 3415 /** for passthrough
3341 * the following function will get the PD LIST. 3416 * the following function will get the PD LIST.
3342 */ 3417 */
@@ -3392,15 +3467,7 @@ static int megasas_init_mfi(struct megasas_instance *instance)
3392 MEGASAS_COMPLETION_TIMER_INTERVAL); 3467 MEGASAS_COMPLETION_TIMER_INTERVAL);
3393 return 0; 3468 return 0;
3394 3469
3395 fail_fw_init: 3470fail_ready_state:
3396
3397 pci_free_consistent(instance->pdev, reply_q_sz,
3398 instance->reply_queue, instance->reply_queue_h);
3399 fail_reply_queue:
3400 megasas_free_cmds(instance);
3401
3402 fail_alloc_cmds:
3403 fail_ready_state:
3404 iounmap(instance->reg_set); 3471 iounmap(instance->reg_set);
3405 3472
3406 fail_ioremap: 3473 fail_ioremap:
@@ -3855,7 +3922,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
3855 /* 3922 /*
3856 * Initialize MFI Firmware 3923 * Initialize MFI Firmware
3857 */ 3924 */
3858 if (megasas_init_mfi(instance)) 3925 if (megasas_init_fw(instance))
3859 goto fail_init_mfi; 3926 goto fail_init_mfi;
3860 3927
3861 /* Try to enable MSI-X */ 3928 /* Try to enable MSI-X */
@@ -3870,7 +3937,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
3870 * Register IRQ 3937 * Register IRQ
3871 */ 3938 */
3872 if (request_irq(instance->msi_flag ? instance->msixentry.vector : 3939 if (request_irq(instance->msi_flag ? instance->msixentry.vector :
3873 pdev->irq, megasas_isr, 3940 pdev->irq, instance->instancet->service_isr,
3874 IRQF_SHARED, "megasas", instance)) { 3941 IRQF_SHARED, "megasas", instance)) {
3875 printk(KERN_DEBUG "megasas: Failed to register IRQ\n"); 3942 printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
3876 goto fail_irq; 3943 goto fail_irq;
@@ -3920,7 +3987,6 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
3920 instance->pdev->irq, instance); 3987 instance->pdev->irq, instance);
3921 if (instance->msi_flag) 3988 if (instance->msi_flag)
3922 pci_disable_msix(instance->pdev); 3989 pci_disable_msix(instance->pdev);
3923 megasas_release_mfi(instance);
3924 3990
3925 fail_irq: 3991 fail_irq:
3926 fail_init_mfi: 3992 fail_init_mfi:
@@ -3930,9 +3996,11 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
3930 instance->evt_detail, 3996 instance->evt_detail,
3931 instance->evt_detail_h); 3997 instance->evt_detail_h);
3932 3998
3933 if (instance->producer) 3999 if (instance->producer) {
3934 pci_free_consistent(pdev, sizeof(u32), instance->producer, 4000 pci_free_consistent(pdev, sizeof(u32), instance->producer,
3935 instance->producer_h); 4001 instance->producer_h);
4002 megasas_release_mfi(instance);
4003 }
3936 if (instance->consumer) 4004 if (instance->consumer)
3937 pci_free_consistent(pdev, sizeof(u32), instance->consumer, 4005 pci_free_consistent(pdev, sizeof(u32), instance->consumer,
3938 instance->consumer_h); 4006 instance->consumer_h);
@@ -4134,7 +4202,7 @@ megasas_resume(struct pci_dev *pdev)
4134 * Register IRQ 4202 * Register IRQ
4135 */ 4203 */
4136 if (request_irq(instance->msi_flag ? instance->msixentry.vector : 4204 if (request_irq(instance->msi_flag ? instance->msixentry.vector :
4137 pdev->irq, megasas_isr, 4205 pdev->irq, instance->instancet->service_isr,
4138 IRQF_SHARED, "megasas", instance)) { 4206 IRQF_SHARED, "megasas", instance)) {
4139 printk(KERN_ERR "megasas: Failed to register IRQ\n"); 4207 printk(KERN_ERR "megasas: Failed to register IRQ\n");
4140 goto fail_irq; 4208 goto fail_irq;