aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/aacraid/aacraid.h5
-rw-r--r--drivers/scsi/aacraid/comminit.c154
-rw-r--r--drivers/scsi/aacraid/linit.c147
-rw-r--r--drivers/scsi/aacraid/rx.c1
-rw-r--r--drivers/scsi/aacraid/sa.c1
-rw-r--r--drivers/scsi/aacraid/src.c2
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);
2127int aac_src_init(struct aac_dev *dev); 2131int aac_src_init(struct aac_dev *dev);
2128int aac_srcv_init(struct aac_dev *dev); 2132int aac_srcv_init(struct aac_dev *dev);
2129int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify); 2133int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify);
2134void aac_define_int_mode(struct aac_dev *dev);
2130unsigned int aac_response_normal(struct aac_queue * q); 2135unsigned int aac_response_normal(struct aac_queue * q);
2131unsigned int aac_command_normal(struct aac_queue * q); 2136unsigned int aac_command_normal(struct aac_queue * q);
2132unsigned int aac_intr_normal(struct aac_dev *dev, u32 Index, 2137unsigned 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
46static void aac_define_int_mode(struct aac_dev *dev);
47
48struct aac_common aac_config = { 46struct 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
339void 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}
341struct aac_dev *aac_init_adapter(struct aac_dev *dev) 415struct 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
511static 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))
1321void 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
1347static 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
1411error_iounmap:
1412 return -1;
1413
1414}
1415static 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
1434static 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
1455fail_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
1320static void aac_shutdown(struct pci_dev *dev) 1463static 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