diff options
-rw-r--r-- | drivers/scsi/aacraid/aacraid.h | 5 | ||||
-rw-r--r-- | drivers/scsi/aacraid/comminit.c | 154 | ||||
-rw-r--r-- | drivers/scsi/aacraid/linit.c | 147 | ||||
-rw-r--r-- | drivers/scsi/aacraid/rx.c | 1 | ||||
-rw-r--r-- | drivers/scsi/aacraid/sa.c | 1 | ||||
-rw-r--r-- | drivers/scsi/aacraid/src.c | 2 |
6 files changed, 232 insertions, 78 deletions
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 40fe65c91b41..62b099940345 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
@@ -547,6 +547,7 @@ struct adapter_ops | |||
547 | int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4); | 547 | int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4); |
548 | int (*adapter_check_health)(struct aac_dev *dev); | 548 | int (*adapter_check_health)(struct aac_dev *dev); |
549 | int (*adapter_restart)(struct aac_dev *dev, int bled); | 549 | int (*adapter_restart)(struct aac_dev *dev, int bled); |
550 | void (*adapter_start)(struct aac_dev *dev); | ||
550 | /* Transport operations */ | 551 | /* Transport operations */ |
551 | int (*adapter_ioremap)(struct aac_dev * dev, u32 size); | 552 | int (*adapter_ioremap)(struct aac_dev * dev, u32 size); |
552 | irq_handler_t adapter_intr; | 553 | irq_handler_t adapter_intr; |
@@ -1247,6 +1248,9 @@ struct aac_dev | |||
1247 | #define aac_adapter_restart(dev,bled) \ | 1248 | #define aac_adapter_restart(dev,bled) \ |
1248 | (dev)->a_ops.adapter_restart(dev,bled) | 1249 | (dev)->a_ops.adapter_restart(dev,bled) |
1249 | 1250 | ||
1251 | #define aac_adapter_start(dev) \ | ||
1252 | ((dev)->a_ops.adapter_start(dev)) | ||
1253 | |||
1250 | #define aac_adapter_ioremap(dev, size) \ | 1254 | #define aac_adapter_ioremap(dev, size) \ |
1251 | (dev)->a_ops.adapter_ioremap(dev, size) | 1255 | (dev)->a_ops.adapter_ioremap(dev, size) |
1252 | 1256 | ||
@@ -2127,6 +2131,7 @@ int aac_sa_init(struct aac_dev *dev); | |||
2127 | int aac_src_init(struct aac_dev *dev); | 2131 | int aac_src_init(struct aac_dev *dev); |
2128 | int aac_srcv_init(struct aac_dev *dev); | 2132 | int aac_srcv_init(struct aac_dev *dev); |
2129 | int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify); | 2133 | int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify); |
2134 | void aac_define_int_mode(struct aac_dev *dev); | ||
2130 | unsigned int aac_response_normal(struct aac_queue * q); | 2135 | unsigned int aac_response_normal(struct aac_queue * q); |
2131 | unsigned int aac_command_normal(struct aac_queue * q); | 2136 | unsigned int aac_command_normal(struct aac_queue * q); |
2132 | unsigned int aac_intr_normal(struct aac_dev *dev, u32 Index, | 2137 | unsigned int aac_intr_normal(struct aac_dev *dev, u32 Index, |
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 45db84ad322f..45a0a044dfdb 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c | |||
@@ -43,8 +43,6 @@ | |||
43 | 43 | ||
44 | #include "aacraid.h" | 44 | #include "aacraid.h" |
45 | 45 | ||
46 | static void aac_define_int_mode(struct aac_dev *dev); | ||
47 | |||
48 | struct aac_common aac_config = { | 46 | struct aac_common aac_config = { |
49 | .irq_mod = 1 | 47 | .irq_mod = 1 |
50 | }; | 48 | }; |
@@ -338,6 +336,82 @@ static int aac_comm_init(struct aac_dev * dev) | |||
338 | return 0; | 336 | return 0; |
339 | } | 337 | } |
340 | 338 | ||
339 | void aac_define_int_mode(struct aac_dev *dev) | ||
340 | { | ||
341 | int i, msi_count; | ||
342 | |||
343 | msi_count = i = 0; | ||
344 | /* max. vectors from GET_COMM_PREFERRED_SETTINGS */ | ||
345 | if (dev->max_msix == 0 || | ||
346 | dev->pdev->device == PMC_DEVICE_S6 || | ||
347 | dev->sync_mode) { | ||
348 | dev->max_msix = 1; | ||
349 | dev->vector_cap = | ||
350 | dev->scsi_host_ptr->can_queue + | ||
351 | AAC_NUM_MGT_FIB; | ||
352 | return; | ||
353 | } | ||
354 | |||
355 | /* Don't bother allocating more MSI-X vectors than cpus */ | ||
356 | msi_count = min(dev->max_msix, | ||
357 | (unsigned int)num_online_cpus()); | ||
358 | |||
359 | dev->max_msix = msi_count; | ||
360 | |||
361 | if (msi_count > AAC_MAX_MSIX) | ||
362 | msi_count = AAC_MAX_MSIX; | ||
363 | |||
364 | for (i = 0; i < msi_count; i++) | ||
365 | dev->msixentry[i].entry = i; | ||
366 | |||
367 | if (msi_count > 1 && | ||
368 | pci_find_capability(dev->pdev, PCI_CAP_ID_MSIX)) { | ||
369 | i = pci_enable_msix(dev->pdev, | ||
370 | dev->msixentry, | ||
371 | msi_count); | ||
372 | /* Check how many MSIX vectors are allocated */ | ||
373 | if (i >= 0) { | ||
374 | dev->msi_enabled = 1; | ||
375 | if (i) { | ||
376 | msi_count = i; | ||
377 | if (pci_enable_msix(dev->pdev, | ||
378 | dev->msixentry, | ||
379 | msi_count)) { | ||
380 | dev->msi_enabled = 0; | ||
381 | printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n", | ||
382 | dev->name, dev->id, i); | ||
383 | } | ||
384 | } | ||
385 | } else { | ||
386 | dev->msi_enabled = 0; | ||
387 | printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n", | ||
388 | dev->name, dev->id, i); | ||
389 | } | ||
390 | } | ||
391 | |||
392 | if (!dev->msi_enabled) { | ||
393 | msi_count = 1; | ||
394 | i = pci_enable_msi(dev->pdev); | ||
395 | |||
396 | if (!i) { | ||
397 | dev->msi_enabled = 1; | ||
398 | dev->msi = 1; | ||
399 | } else { | ||
400 | printk(KERN_ERR "%s%d: MSI not supported!! Will try INTx 0x%x.\n", | ||
401 | dev->name, dev->id, i); | ||
402 | } | ||
403 | } | ||
404 | |||
405 | if (!dev->msi_enabled) | ||
406 | dev->max_msix = msi_count = 1; | ||
407 | else { | ||
408 | if (dev->max_msix > msi_count) | ||
409 | dev->max_msix = msi_count; | ||
410 | } | ||
411 | dev->vector_cap = | ||
412 | (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) / | ||
413 | msi_count; | ||
414 | } | ||
341 | struct aac_dev *aac_init_adapter(struct aac_dev *dev) | 415 | struct aac_dev *aac_init_adapter(struct aac_dev *dev) |
342 | { | 416 | { |
343 | u32 status[5]; | 417 | u32 status[5]; |
@@ -508,79 +582,3 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) | |||
508 | return dev; | 582 | return dev; |
509 | } | 583 | } |
510 | 584 | ||
511 | static void aac_define_int_mode(struct aac_dev *dev) | ||
512 | { | ||
513 | |||
514 | int i, msi_count; | ||
515 | |||
516 | msi_count = i = 0; | ||
517 | /* max. vectors from GET_COMM_PREFERRED_SETTINGS */ | ||
518 | if (dev->max_msix == 0 || | ||
519 | dev->pdev->device == PMC_DEVICE_S6 || | ||
520 | dev->sync_mode) { | ||
521 | dev->max_msix = 1; | ||
522 | dev->vector_cap = | ||
523 | dev->scsi_host_ptr->can_queue + | ||
524 | AAC_NUM_MGT_FIB; | ||
525 | return; | ||
526 | } | ||
527 | |||
528 | msi_count = min(dev->max_msix, | ||
529 | (unsigned int)num_online_cpus()); | ||
530 | |||
531 | dev->max_msix = msi_count; | ||
532 | |||
533 | if (msi_count > AAC_MAX_MSIX) | ||
534 | msi_count = AAC_MAX_MSIX; | ||
535 | |||
536 | for (i = 0; i < msi_count; i++) | ||
537 | dev->msixentry[i].entry = i; | ||
538 | |||
539 | if (msi_count > 1 && | ||
540 | pci_find_capability(dev->pdev, PCI_CAP_ID_MSIX)) { | ||
541 | i = pci_enable_msix(dev->pdev, | ||
542 | dev->msixentry, | ||
543 | msi_count); | ||
544 | /* Check how many MSIX vectors are allocated */ | ||
545 | if (i >= 0) { | ||
546 | dev->msi_enabled = 1; | ||
547 | if (i) { | ||
548 | msi_count = i; | ||
549 | if (pci_enable_msix(dev->pdev, | ||
550 | dev->msixentry, | ||
551 | msi_count)) { | ||
552 | dev->msi_enabled = 0; | ||
553 | printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n", | ||
554 | dev->name, dev->id, i); | ||
555 | } | ||
556 | } | ||
557 | } else { | ||
558 | dev->msi_enabled = 0; | ||
559 | printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n", | ||
560 | dev->name, dev->id, i); | ||
561 | } | ||
562 | } | ||
563 | |||
564 | if (!dev->msi_enabled) { | ||
565 | msi_count = 1; | ||
566 | i = pci_enable_msi(dev->pdev); | ||
567 | |||
568 | if (!i) { | ||
569 | dev->msi_enabled = 1; | ||
570 | dev->msi = 1; | ||
571 | } else { | ||
572 | printk(KERN_ERR "%s%d: MSI not supported!! Will try INTx 0x%x.\n", | ||
573 | dev->name, dev->id, i); | ||
574 | } | ||
575 | } | ||
576 | |||
577 | if (!dev->msi_enabled) | ||
578 | dev->max_msix = msi_count = 1; | ||
579 | else { | ||
580 | if (dev->max_msix > msi_count) | ||
581 | dev->max_msix = msi_count; | ||
582 | } | ||
583 | dev->vector_cap = | ||
584 | (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) / | ||
585 | msi_count; | ||
586 | } | ||
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 9eec02733c86..37375cf7d126 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c | |||
@@ -1317,6 +1317,149 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1317 | return error; | 1317 | return error; |
1318 | } | 1318 | } |
1319 | 1319 | ||
1320 | #if (defined(CONFIG_PM)) | ||
1321 | void aac_release_resources(struct aac_dev *aac) | ||
1322 | { | ||
1323 | int i; | ||
1324 | |||
1325 | aac_adapter_disable_int(aac); | ||
1326 | if (aac->pdev->device == PMC_DEVICE_S6 || | ||
1327 | aac->pdev->device == PMC_DEVICE_S7 || | ||
1328 | aac->pdev->device == PMC_DEVICE_S8 || | ||
1329 | aac->pdev->device == PMC_DEVICE_S9) { | ||
1330 | if (aac->max_msix > 1) { | ||
1331 | for (i = 0; i < aac->max_msix; i++) | ||
1332 | free_irq(aac->msixentry[i].vector, | ||
1333 | &(aac->aac_msix[i])); | ||
1334 | } else { | ||
1335 | free_irq(aac->pdev->irq, &(aac->aac_msix[0])); | ||
1336 | } | ||
1337 | } else { | ||
1338 | free_irq(aac->pdev->irq, aac); | ||
1339 | } | ||
1340 | if (aac->msi) | ||
1341 | pci_disable_msi(aac->pdev); | ||
1342 | else if (aac->max_msix > 1) | ||
1343 | pci_disable_msix(aac->pdev); | ||
1344 | |||
1345 | } | ||
1346 | |||
1347 | static int aac_acquire_resources(struct aac_dev *dev) | ||
1348 | { | ||
1349 | int i, j; | ||
1350 | int instance = dev->id; | ||
1351 | const char *name = dev->name; | ||
1352 | unsigned long status; | ||
1353 | /* | ||
1354 | * First clear out all interrupts. Then enable the one's that we | ||
1355 | * can handle. | ||
1356 | */ | ||
1357 | while (!((status = src_readl(dev, MUnit.OMR)) & KERNEL_UP_AND_RUNNING) | ||
1358 | || status == 0xffffffff) | ||
1359 | msleep(20); | ||
1360 | |||
1361 | aac_adapter_disable_int(dev); | ||
1362 | aac_adapter_enable_int(dev); | ||
1363 | |||
1364 | |||
1365 | if ((dev->pdev->device == PMC_DEVICE_S7 || | ||
1366 | dev->pdev->device == PMC_DEVICE_S8 || | ||
1367 | dev->pdev->device == PMC_DEVICE_S9)) | ||
1368 | aac_define_int_mode(dev); | ||
1369 | |||
1370 | if (dev->msi_enabled) | ||
1371 | aac_src_access_devreg(dev, AAC_ENABLE_MSIX); | ||
1372 | |||
1373 | if (!dev->sync_mode && dev->msi_enabled && dev->max_msix > 1) { | ||
1374 | for (i = 0; i < dev->max_msix; i++) { | ||
1375 | dev->aac_msix[i].vector_no = i; | ||
1376 | dev->aac_msix[i].dev = dev; | ||
1377 | |||
1378 | if (request_irq(dev->msixentry[i].vector, | ||
1379 | dev->a_ops.adapter_intr, | ||
1380 | 0, "aacraid", &(dev->aac_msix[i]))) { | ||
1381 | printk(KERN_ERR "%s%d: Failed to register IRQ for vector %d.\n", | ||
1382 | name, instance, i); | ||
1383 | for (j = 0 ; j < i ; j++) | ||
1384 | free_irq(dev->msixentry[j].vector, | ||
1385 | &(dev->aac_msix[j])); | ||
1386 | pci_disable_msix(dev->pdev); | ||
1387 | goto error_iounmap; | ||
1388 | } | ||
1389 | } | ||
1390 | } else { | ||
1391 | dev->aac_msix[0].vector_no = 0; | ||
1392 | dev->aac_msix[0].dev = dev; | ||
1393 | |||
1394 | if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr, | ||
1395 | IRQF_SHARED, "aacraid", | ||
1396 | &(dev->aac_msix[0])) < 0) { | ||
1397 | if (dev->msi) | ||
1398 | pci_disable_msi(dev->pdev); | ||
1399 | printk(KERN_ERR "%s%d: Interrupt unavailable.\n", | ||
1400 | name, instance); | ||
1401 | goto error_iounmap; | ||
1402 | } | ||
1403 | } | ||
1404 | |||
1405 | aac_adapter_enable_int(dev); | ||
1406 | |||
1407 | if (!dev->sync_mode) | ||
1408 | aac_adapter_start(dev); | ||
1409 | return 0; | ||
1410 | |||
1411 | error_iounmap: | ||
1412 | return -1; | ||
1413 | |||
1414 | } | ||
1415 | static int aac_suspend(struct pci_dev *pdev, pm_message_t state) | ||
1416 | { | ||
1417 | |||
1418 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | ||
1419 | struct aac_dev *aac = (struct aac_dev *)shost->hostdata; | ||
1420 | |||
1421 | scsi_block_requests(shost); | ||
1422 | aac_send_shutdown(aac); | ||
1423 | |||
1424 | aac_release_resources(aac); | ||
1425 | |||
1426 | pci_set_drvdata(pdev, shost); | ||
1427 | pci_save_state(pdev); | ||
1428 | pci_disable_device(pdev); | ||
1429 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
1430 | |||
1431 | return 0; | ||
1432 | } | ||
1433 | |||
1434 | static int aac_resume(struct pci_dev *pdev) | ||
1435 | { | ||
1436 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | ||
1437 | struct aac_dev *aac = (struct aac_dev *)shost->hostdata; | ||
1438 | int r; | ||
1439 | |||
1440 | pci_set_power_state(pdev, PCI_D0); | ||
1441 | pci_enable_wake(pdev, PCI_D0, 0); | ||
1442 | pci_restore_state(pdev); | ||
1443 | r = pci_enable_device(pdev); | ||
1444 | |||
1445 | if (r) | ||
1446 | goto fail_device; | ||
1447 | |||
1448 | pci_set_master(pdev); | ||
1449 | if (aac_acquire_resources(aac)) | ||
1450 | goto fail_device; | ||
1451 | scsi_unblock_requests(shost); | ||
1452 | |||
1453 | return 0; | ||
1454 | |||
1455 | fail_device: | ||
1456 | printk(KERN_INFO "%s%d: resume failed.\n", aac->name, aac->id); | ||
1457 | scsi_host_put(shost); | ||
1458 | pci_disable_device(pdev); | ||
1459 | return -ENODEV; | ||
1460 | } | ||
1461 | #endif | ||
1462 | |||
1320 | static void aac_shutdown(struct pci_dev *dev) | 1463 | static void aac_shutdown(struct pci_dev *dev) |
1321 | { | 1464 | { |
1322 | struct Scsi_Host *shost = pci_get_drvdata(dev); | 1465 | struct Scsi_Host *shost = pci_get_drvdata(dev); |
@@ -1356,6 +1499,10 @@ static struct pci_driver aac_pci_driver = { | |||
1356 | .id_table = aac_pci_tbl, | 1499 | .id_table = aac_pci_tbl, |
1357 | .probe = aac_probe_one, | 1500 | .probe = aac_probe_one, |
1358 | .remove = aac_remove_one, | 1501 | .remove = aac_remove_one, |
1502 | #if (defined(CONFIG_PM)) | ||
1503 | .suspend = aac_suspend, | ||
1504 | .resume = aac_resume, | ||
1505 | #endif | ||
1359 | .shutdown = aac_shutdown, | 1506 | .shutdown = aac_shutdown, |
1360 | }; | 1507 | }; |
1361 | 1508 | ||
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c index 9570612b80ce..ac1638069335 100644 --- a/drivers/scsi/aacraid/rx.c +++ b/drivers/scsi/aacraid/rx.c | |||
@@ -623,6 +623,7 @@ int _aac_rx_init(struct aac_dev *dev) | |||
623 | dev->a_ops.adapter_sync_cmd = rx_sync_cmd; | 623 | dev->a_ops.adapter_sync_cmd = rx_sync_cmd; |
624 | dev->a_ops.adapter_check_health = aac_rx_check_health; | 624 | dev->a_ops.adapter_check_health = aac_rx_check_health; |
625 | dev->a_ops.adapter_restart = aac_rx_restart_adapter; | 625 | dev->a_ops.adapter_restart = aac_rx_restart_adapter; |
626 | dev->a_ops.adapter_start = aac_rx_start_adapter; | ||
626 | 627 | ||
627 | /* | 628 | /* |
628 | * First clear out all interrupts. Then enable the one's that we | 629 | * First clear out all interrupts. Then enable the one's that we |
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c index e66477c98240..869aea23c041 100644 --- a/drivers/scsi/aacraid/sa.c +++ b/drivers/scsi/aacraid/sa.c | |||
@@ -372,6 +372,7 @@ int aac_sa_init(struct aac_dev *dev) | |||
372 | dev->a_ops.adapter_sync_cmd = sa_sync_cmd; | 372 | dev->a_ops.adapter_sync_cmd = sa_sync_cmd; |
373 | dev->a_ops.adapter_check_health = aac_sa_check_health; | 373 | dev->a_ops.adapter_check_health = aac_sa_check_health; |
374 | dev->a_ops.adapter_restart = aac_sa_restart_adapter; | 374 | dev->a_ops.adapter_restart = aac_sa_restart_adapter; |
375 | dev->a_ops.adapter_start = aac_sa_start_adapter; | ||
375 | dev->a_ops.adapter_intr = aac_sa_intr; | 376 | dev->a_ops.adapter_intr = aac_sa_intr; |
376 | dev->a_ops.adapter_deliver = aac_rx_deliver_producer; | 377 | dev->a_ops.adapter_deliver = aac_rx_deliver_producer; |
377 | dev->a_ops.adapter_ioremap = aac_sa_ioremap; | 378 | dev->a_ops.adapter_ioremap = aac_sa_ioremap; |
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index e63cf9f22f36..b147341ac24d 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c | |||
@@ -726,6 +726,7 @@ int aac_src_init(struct aac_dev *dev) | |||
726 | dev->a_ops.adapter_sync_cmd = src_sync_cmd; | 726 | dev->a_ops.adapter_sync_cmd = src_sync_cmd; |
727 | dev->a_ops.adapter_check_health = aac_src_check_health; | 727 | dev->a_ops.adapter_check_health = aac_src_check_health; |
728 | dev->a_ops.adapter_restart = aac_src_restart_adapter; | 728 | dev->a_ops.adapter_restart = aac_src_restart_adapter; |
729 | dev->a_ops.adapter_start = aac_src_start_adapter; | ||
729 | 730 | ||
730 | /* | 731 | /* |
731 | * First clear out all interrupts. Then enable the one's that we | 732 | * First clear out all interrupts. Then enable the one's that we |
@@ -892,6 +893,7 @@ int aac_srcv_init(struct aac_dev *dev) | |||
892 | dev->a_ops.adapter_sync_cmd = src_sync_cmd; | 893 | dev->a_ops.adapter_sync_cmd = src_sync_cmd; |
893 | dev->a_ops.adapter_check_health = aac_src_check_health; | 894 | dev->a_ops.adapter_check_health = aac_src_check_health; |
894 | dev->a_ops.adapter_restart = aac_src_restart_adapter; | 895 | dev->a_ops.adapter_restart = aac_src_restart_adapter; |
896 | dev->a_ops.adapter_start = aac_src_start_adapter; | ||
895 | 897 | ||
896 | /* | 898 | /* |
897 | * First clear out all interrupts. Then enable the one's that we | 899 | * First clear out all interrupts. Then enable the one's that we |