Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

adam radford and committed by
James Bottomley
cd50ba8e b6d5d880

+180 -105
+7
drivers/scsi/megaraid/megaraid_sas.h
··· 1364 1364 struct megasas_register_set __iomem *); 1365 1365 int (*check_reset)(struct megasas_instance *, \ 1366 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 1376 #define MEGASAS_IS_LOGICAL(scp) \
+173 -105
drivers/scsi/megaraid/megaraid_sas_base.c
··· 131 131 static void 132 132 megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, 133 133 u8 alt_status); 134 + static irqreturn_t megasas_isr(int irq, void *devp); 135 + static u32 136 + megasas_init_adapter_mfi(struct megasas_instance *instance); 137 + u32 138 + megasas_build_and_issue_cmd(struct megasas_instance *instance, 139 + struct scsi_cmnd *scmd); 140 + static void megasas_complete_cmd_dpc(unsigned long instance_addr); 141 + 142 + void 143 + megasas_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 150 * megasas_get_cmd - Get a command from the free pool ··· 348 334 .read_fw_status_reg = megasas_read_fw_status_reg_xscale, 349 335 .adp_reset = megasas_adp_reset_xscale, 350 336 .check_reset = megasas_check_reset_xscale, 337 + .service_isr = megasas_isr, 338 + .tasklet = megasas_complete_cmd_dpc, 339 + .init_adapter = megasas_init_adapter_mfi, 340 + .build_and_issue_cmd = megasas_build_and_issue_cmd, 341 + .issue_dcmd = megasas_issue_dcmd, 351 342 }; 352 343 353 344 /** ··· 479 460 .read_fw_status_reg = megasas_read_fw_status_reg_ppc, 480 461 .adp_reset = megasas_adp_reset_ppc, 481 462 .check_reset = megasas_check_reset_ppc, 463 + .service_isr = megasas_isr, 464 + .tasklet = megasas_complete_cmd_dpc, 465 + .init_adapter = megasas_init_adapter_mfi, 466 + .build_and_issue_cmd = megasas_build_and_issue_cmd, 467 + .issue_dcmd = megasas_issue_dcmd, 482 468 }; 483 469 484 470 /** ··· 605 581 .read_fw_status_reg = megasas_read_fw_status_reg_skinny, 606 582 .adp_reset = megasas_adp_reset_skinny, 607 583 .check_reset = megasas_check_reset_skinny, 584 + .service_isr = megasas_isr, 585 + .tasklet = megasas_complete_cmd_dpc, 586 + .init_adapter = megasas_init_adapter_mfi, 587 + .build_and_issue_cmd = megasas_build_and_issue_cmd, 588 + .issue_dcmd = megasas_issue_dcmd, 608 589 }; 609 590 610 591 ··· 784 755 .read_fw_status_reg = megasas_read_fw_status_reg_gen2, 785 756 .adp_reset = megasas_adp_reset_gen2, 786 757 .check_reset = megasas_check_reset_gen2, 758 + .service_isr = megasas_isr, 759 + .tasklet = megasas_complete_cmd_dpc, 760 + .init_adapter = megasas_init_adapter_mfi, 761 + .build_and_issue_cmd = megasas_build_and_issue_cmd, 762 + .issue_dcmd = megasas_issue_dcmd, 787 763 }; 788 764 789 765 /** ··· 1373 1339 printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no); 1374 1340 } 1375 1341 1342 + u32 1343 + megasas_build_and_issue_cmd(struct megasas_instance *instance, 1344 + struct scsi_cmnd *scmd) 1345 + { 1346 + struct megasas_cmd *cmd; 1347 + u32 frame_count; 1348 + 1349 + cmd = megasas_get_cmd(instance); 1350 + if (!cmd) 1351 + return SCSI_MLQUEUE_HOST_BUSY; 1352 + 1353 + /* 1354 + * Logical drive command 1355 + */ 1356 + if (megasas_is_ldio(scmd)) 1357 + frame_count = megasas_build_ldio(instance, scmd, cmd); 1358 + else 1359 + frame_count = megasas_build_dcdb(instance, scmd, cmd); 1360 + 1361 + if (!frame_count) 1362 + goto out_return_cmd; 1363 + 1364 + cmd->scmd = scmd; 1365 + scmd->SCp.ptr = (char *)cmd; 1366 + 1367 + /* 1368 + * Issue the command to the FW 1369 + */ 1370 + atomic_inc(&instance->fw_outstanding); 1371 + 1372 + instance->instancet->fire_cmd(instance, cmd->frame_phys_addr, 1373 + cmd->frame_count-1, instance->reg_set); 1374 + /* 1375 + * Check if we have pend cmds to be completed 1376 + */ 1377 + if (poll_mode_io && atomic_read(&instance->fw_outstanding)) 1378 + tasklet_schedule(&instance->isr_tasklet); 1379 + 1380 + return 0; 1381 + out_return_cmd: 1382 + megasas_return_cmd(instance, cmd); 1383 + return 1; 1384 + } 1385 + 1386 + 1376 1387 /** 1377 1388 * megasas_queue_command - Queue entry point 1378 1389 * @scmd: SCSI command to be queued ··· 1426 1347 static int 1427 1348 megasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) 1428 1349 { 1429 - u32 frame_count; 1430 - struct megasas_cmd *cmd; 1431 1350 struct megasas_instance *instance; 1432 1351 unsigned long flags; 1433 1352 ··· 1464 1387 break; 1465 1388 } 1466 1389 1467 - cmd = megasas_get_cmd(instance); 1468 - if (!cmd) 1390 + if (instance->instancet->build_and_issue_cmd(instance, scmd)) { 1391 + printk(KERN_ERR "megasas: Err returned from build_and_issue_cmd\n"); 1469 1392 return SCSI_MLQUEUE_HOST_BUSY; 1470 - 1471 - /* 1472 - * Logical drive command 1473 - */ 1474 - if (megasas_is_ldio(scmd)) 1475 - frame_count = megasas_build_ldio(instance, scmd, cmd); 1476 - else 1477 - frame_count = megasas_build_dcdb(instance, scmd, cmd); 1478 - 1479 - if (!frame_count) 1480 - goto out_return_cmd; 1481 - 1482 - cmd->scmd = scmd; 1483 - scmd->SCp.ptr = (char *)cmd; 1484 - 1485 - /* 1486 - * Issue the command to the FW 1487 - */ 1488 - atomic_inc(&instance->fw_outstanding); 1489 - 1490 - instance->instancet->fire_cmd(instance, cmd->frame_phys_addr, 1491 - cmd->frame_count-1, instance->reg_set); 1492 - /* 1493 - * Check if we have pend cmds to be completed 1494 - */ 1495 - if (poll_mode_io && atomic_read(&instance->fw_outstanding)) 1496 - tasklet_schedule(&instance->isr_tasklet); 1497 - 1393 + } 1498 1394 1499 1395 return 0; 1500 1396 1501 - out_return_cmd: 1502 - megasas_return_cmd(instance, cmd); 1503 1397 out_done: 1504 1398 done(scmd); 1505 1399 return 0; ··· 3269 3221 jiffies + MEGASAS_COMPLETION_TIMER_INTERVAL); 3270 3222 } 3271 3223 3272 - /** 3273 - * megasas_init_mfi - Initializes the FW 3274 - * @instance: Adapter soft state 3275 - * 3276 - * This is the main function for initializing MFI firmware. 3277 - */ 3278 - static int megasas_init_mfi(struct megasas_instance *instance) 3224 + static u32 3225 + megasas_init_adapter_mfi(struct megasas_instance *instance) 3279 3226 { 3227 + struct megasas_register_set __iomem *reg_set; 3280 3228 u32 context_sz; 3281 3229 u32 reply_q_sz; 3282 - u32 max_sectors_1; 3283 - u32 max_sectors_2; 3284 - u32 tmp_sectors; 3285 - struct megasas_register_set __iomem *reg_set; 3286 - struct megasas_ctrl_info *ctrl_info; 3287 - unsigned long bar_list; 3288 - 3289 - /* Find first memory bar */ 3290 - bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM); 3291 - instance->bar = find_first_bit(&bar_list, sizeof(unsigned long)); 3292 - instance->base_addr = pci_resource_start(instance->pdev, instance->bar); 3293 - if (pci_request_selected_regions(instance->pdev, instance->bar, 3294 - "megasas: LSI")) { 3295 - printk(KERN_DEBUG "megasas: IO memory region busy!\n"); 3296 - return -EBUSY; 3297 - } 3298 - 3299 - instance->reg_set = ioremap_nocache(instance->base_addr, 8192); 3300 - 3301 - if (!instance->reg_set) { 3302 - printk(KERN_DEBUG "megasas: Failed to map IO mem\n"); 3303 - goto fail_ioremap; 3304 - } 3305 3230 3306 3231 reg_set = instance->reg_set; 3307 - 3308 - switch(instance->pdev->device) 3309 - { 3310 - case PCI_DEVICE_ID_LSI_SAS1078R: 3311 - case PCI_DEVICE_ID_LSI_SAS1078DE: 3312 - instance->instancet = &megasas_instance_template_ppc; 3313 - break; 3314 - case PCI_DEVICE_ID_LSI_SAS1078GEN2: 3315 - case PCI_DEVICE_ID_LSI_SAS0079GEN2: 3316 - instance->instancet = &megasas_instance_template_gen2; 3317 - break; 3318 - case PCI_DEVICE_ID_LSI_SAS0073SKINNY: 3319 - case PCI_DEVICE_ID_LSI_SAS0071SKINNY: 3320 - instance->instancet = &megasas_instance_template_skinny; 3321 - break; 3322 - case PCI_DEVICE_ID_LSI_SAS1064R: 3323 - case PCI_DEVICE_ID_DELL_PERC5: 3324 - default: 3325 - instance->instancet = &megasas_instance_template_xscale; 3326 - break; 3327 - } 3328 - 3329 - /* 3330 - * We expect the FW state to be READY 3331 - */ 3332 - if (megasas_transition_to_ready(instance)) 3333 - goto fail_ready_state; 3334 3232 3335 3233 /* 3336 3234 * Get various operational parameters from status register ··· 3330 3336 3331 3337 if (instance->fw_support_ieee) 3332 3338 instance->flag_ieee = 1; 3339 + 3340 + return 0; 3341 + 3342 + fail_fw_init: 3343 + 3344 + pci_free_consistent(instance->pdev, reply_q_sz, 3345 + instance->reply_queue, instance->reply_queue_h); 3346 + fail_reply_queue: 3347 + megasas_free_cmds(instance); 3348 + 3349 + fail_alloc_cmds: 3350 + iounmap(instance->reg_set); 3351 + return 1; 3352 + } 3353 + 3354 + /** 3355 + * megasas_init_fw - Initializes the FW 3356 + * @instance: Adapter soft state 3357 + * 3358 + * This is the main function for initializing firmware 3359 + */ 3360 + 3361 + static int megasas_init_fw(struct megasas_instance *instance) 3362 + { 3363 + u32 max_sectors_1; 3364 + u32 max_sectors_2; 3365 + u32 tmp_sectors; 3366 + struct megasas_register_set __iomem *reg_set; 3367 + struct megasas_ctrl_info *ctrl_info; 3368 + unsigned long bar_list; 3369 + 3370 + /* Find first memory bar */ 3371 + bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM); 3372 + instance->bar = find_first_bit(&bar_list, sizeof(unsigned long)); 3373 + instance->base_addr = pci_resource_start(instance->pdev, instance->bar); 3374 + if (pci_request_selected_regions(instance->pdev, instance->bar, 3375 + "megasas: LSI")) { 3376 + printk(KERN_DEBUG "megasas: IO memory region busy!\n"); 3377 + return -EBUSY; 3378 + } 3379 + 3380 + instance->reg_set = ioremap_nocache(instance->base_addr, 8192); 3381 + 3382 + if (!instance->reg_set) { 3383 + printk(KERN_DEBUG "megasas: Failed to map IO mem\n"); 3384 + goto fail_ioremap; 3385 + } 3386 + 3387 + reg_set = instance->reg_set; 3388 + 3389 + switch (instance->pdev->device) { 3390 + case PCI_DEVICE_ID_LSI_SAS1078R: 3391 + case PCI_DEVICE_ID_LSI_SAS1078DE: 3392 + instance->instancet = &megasas_instance_template_ppc; 3393 + break; 3394 + case PCI_DEVICE_ID_LSI_SAS1078GEN2: 3395 + case PCI_DEVICE_ID_LSI_SAS0079GEN2: 3396 + instance->instancet = &megasas_instance_template_gen2; 3397 + break; 3398 + case PCI_DEVICE_ID_LSI_SAS0073SKINNY: 3399 + case PCI_DEVICE_ID_LSI_SAS0071SKINNY: 3400 + instance->instancet = &megasas_instance_template_skinny; 3401 + break; 3402 + case PCI_DEVICE_ID_LSI_SAS1064R: 3403 + case PCI_DEVICE_ID_DELL_PERC5: 3404 + default: 3405 + instance->instancet = &megasas_instance_template_xscale; 3406 + break; 3407 + } 3408 + 3409 + /* 3410 + * We expect the FW state to be READY 3411 + */ 3412 + if (megasas_transition_to_ready(instance)) 3413 + goto fail_ready_state; 3414 + 3415 + /* Get operational params, sge flags, send init cmd to controller */ 3416 + if (instance->instancet->init_adapter(instance)) 3417 + return -ENODEV; 3418 + 3419 + printk(KERN_ERR "megasas: INIT adapter done\n"); 3333 3420 3334 3421 /** for passthrough 3335 3422 * the following function will get the PD LIST. ··· 3467 3392 MEGASAS_COMPLETION_TIMER_INTERVAL); 3468 3393 return 0; 3469 3394 3470 - fail_fw_init: 3471 - 3472 - pci_free_consistent(instance->pdev, reply_q_sz, 3473 - instance->reply_queue, instance->reply_queue_h); 3474 - fail_reply_queue: 3475 - megasas_free_cmds(instance); 3476 - 3477 - fail_alloc_cmds: 3478 - fail_ready_state: 3395 + fail_ready_state: 3479 3396 iounmap(instance->reg_set); 3480 3397 3481 3398 fail_ioremap: ··· 3922 3855 /* 3923 3856 * Initialize MFI Firmware 3924 3857 */ 3925 - if (megasas_init_mfi(instance)) 3858 + if (megasas_init_fw(instance)) 3926 3859 goto fail_init_mfi; 3927 3860 3928 3861 /* Try to enable MSI-X */ ··· 3937 3870 * Register IRQ 3938 3871 */ 3939 3872 if (request_irq(instance->msi_flag ? instance->msixentry.vector : 3940 - pdev->irq, megasas_isr, 3873 + pdev->irq, instance->instancet->service_isr, 3941 3874 IRQF_SHARED, "megasas", instance)) { 3942 3875 printk(KERN_DEBUG "megasas: Failed to register IRQ\n"); 3943 3876 goto fail_irq; ··· 3987 3920 instance->pdev->irq, instance); 3988 3921 if (instance->msi_flag) 3989 3922 pci_disable_msix(instance->pdev); 3990 - megasas_release_mfi(instance); 3991 3923 3992 3924 fail_irq: 3993 3925 fail_init_mfi: ··· 3996 3930 instance->evt_detail, 3997 3931 instance->evt_detail_h); 3998 3932 3999 - if (instance->producer) 3933 + if (instance->producer) { 4000 3934 pci_free_consistent(pdev, sizeof(u32), instance->producer, 4001 3935 instance->producer_h); 3936 + megasas_release_mfi(instance); 3937 + } 4002 3938 if (instance->consumer) 4003 3939 pci_free_consistent(pdev, sizeof(u32), instance->consumer, 4004 3940 instance->consumer_h); ··· 4202 4134 * Register IRQ 4203 4135 */ 4204 4136 if (request_irq(instance->msi_flag ? instance->msixentry.vector : 4205 - pdev->irq, megasas_isr, 4137 + pdev->irq, instance->instancet->service_isr, 4206 4138 IRQF_SHARED, "megasas", instance)) { 4207 4139 printk(KERN_ERR "megasas: Failed to register IRQ\n"); 4208 4140 goto fail_irq;