aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/isci/host.c201
-rw-r--r--drivers/scsi/isci/init.c91
-rw-r--r--drivers/scsi/isci/isci.h1
3 files changed, 134 insertions, 159 deletions
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index cb2e3f9558e9..aa86615fa7a9 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -354,67 +354,6 @@ void isci_host_deinit(struct isci_host *ihost)
354 scic_controller_reset(scic); 354 scic_controller_reset(scic);
355} 355}
356 356
357static int isci_verify_firmware(const struct firmware *fw,
358 struct isci_firmware *isci_fw)
359{
360 const u8 *tmp;
361
362 if (fw->size < ISCI_FIRMWARE_MIN_SIZE)
363 return -EINVAL;
364
365 tmp = fw->data;
366
367 /* 12th char should be the NULL terminate for the ID string */
368 if (tmp[11] != '\0')
369 return -EINVAL;
370
371 if (strncmp("#SCU MAGIC#", tmp, 11) != 0)
372 return -EINVAL;
373
374 isci_fw->id = tmp;
375 isci_fw->version = fw->data[ISCI_FW_VER_OFS];
376 isci_fw->subversion = fw->data[ISCI_FW_SUBVER_OFS];
377
378 tmp = fw->data + ISCI_FW_DATA_OFS;
379
380 while (*tmp != ISCI_FW_HDR_EOF) {
381 switch (*tmp) {
382 case ISCI_FW_HDR_PHYMASK:
383 tmp++;
384 isci_fw->phy_masks_size = *tmp;
385 tmp++;
386 isci_fw->phy_masks = (const u32 *)tmp;
387 tmp += sizeof(u32) * isci_fw->phy_masks_size;
388 break;
389
390 case ISCI_FW_HDR_PHYGEN:
391 tmp++;
392 isci_fw->phy_gens_size = *tmp;
393 tmp++;
394 isci_fw->phy_gens = (const u32 *)tmp;
395 tmp += sizeof(u32) * isci_fw->phy_gens_size;
396 break;
397
398 case ISCI_FW_HDR_SASADDR:
399 tmp++;
400 isci_fw->sas_addrs_size = *tmp;
401 tmp++;
402 isci_fw->sas_addrs = (const u64 *)tmp;
403 tmp += sizeof(u64) * isci_fw->sas_addrs_size;
404 break;
405
406 default:
407 pr_err("bad field in firmware binary blob\n");
408 return -EINVAL;
409 }
410 }
411
412 pr_info("isci firmware v%u.%u loaded.\n",
413 isci_fw->version, isci_fw->subversion);
414
415 return SCI_SUCCESS;
416}
417
418static void __iomem *scu_base(struct isci_host *isci_host) 357static void __iomem *scu_base(struct isci_host *isci_host)
419{ 358{
420 struct pci_dev *pdev = isci_host->pdev; 359 struct pci_dev *pdev = isci_host->pdev;
@@ -442,8 +381,6 @@ int isci_host_init(struct isci_host *isci_host)
442 struct scic_sds_port *scic_port; 381 struct scic_sds_port *scic_port;
443 union scic_oem_parameters scic_oem_params; 382 union scic_oem_parameters scic_oem_params;
444 union scic_user_parameters scic_user_params; 383 union scic_user_parameters scic_user_params;
445 const struct firmware *fw = NULL;
446 struct isci_firmware *isci_fw = NULL;
447 384
448 INIT_LIST_HEAD(&isci_host->timer_list_struct.timers); 385 INIT_LIST_HEAD(&isci_host->timer_list_struct.timers);
449 isci_timer_list_construct( 386 isci_timer_list_construct(
@@ -454,9 +391,11 @@ int isci_host_init(struct isci_host *isci_host)
454 controller = scic_controller_alloc(&isci_host->pdev->dev); 391 controller = scic_controller_alloc(&isci_host->pdev->dev);
455 392
456 if (!controller) { 393 if (!controller) {
457 err = -ENOMEM; 394 dev_err(&isci_host->pdev->dev,
458 dev_err(&isci_host->pdev->dev, "%s: failed (%d)\n", __func__, err); 395 "%s: failed (%d)\n",
459 goto out; 396 __func__,
397 err);
398 return -ENOMEM;
460 } 399 }
461 400
462 isci_host->core_controller = controller; 401 isci_host->core_controller = controller;
@@ -476,8 +415,7 @@ int isci_host_init(struct isci_host *isci_host)
476 "%s: scic_controller_construct failed - status = %x\n", 415 "%s: scic_controller_construct failed - status = %x\n",
477 __func__, 416 __func__,
478 status); 417 status);
479 err = -ENODEV; 418 return -ENODEV;
480 goto out;
481 } 419 }
482 420
483 isci_host->sas_ha.dev = &isci_host->pdev->dev; 421 isci_host->sas_ha.dev = &isci_host->pdev->dev;
@@ -487,93 +425,52 @@ int isci_host_init(struct isci_host *isci_host)
487 * set association host adapter struct in core controller. 425 * set association host adapter struct in core controller.
488 */ 426 */
489 sci_object_set_association(isci_host->core_controller, 427 sci_object_set_association(isci_host->core_controller,
490 (void *)isci_host 428 (void *)isci_host);
491 );
492 429
493 /* grab initial values stored in the controller object for OEM and USER 430 /* grab initial values stored in the controller object for OEM and USER
494 * parameters */ 431 * parameters */
495 scic_oem_parameters_get(controller, &scic_oem_params); 432 scic_oem_parameters_get(controller, &scic_oem_params);
496 scic_user_parameters_get(controller, &scic_user_params); 433 scic_user_parameters_get(controller, &scic_user_params);
497 434
498 isci_fw = devm_kzalloc(&isci_host->pdev->dev, 435 if (isci_firmware) {
499 sizeof(struct isci_firmware), 436 /* grab any OEM and USER parameters specified in binary blob */
500 GFP_KERNEL);
501 if (!isci_fw) {
502 dev_warn(&isci_host->pdev->dev,
503 "allocating firmware struct failed\n");
504 dev_warn(&isci_host->pdev->dev,
505 "Default OEM configuration being used:"
506 " 4 narrow ports, and default SAS Addresses\n");
507 goto set_default_params;
508 }
509
510 status = request_firmware(&fw, ISCI_FW_NAME, &isci_host->pdev->dev);
511 if (status) {
512 dev_warn(&isci_host->pdev->dev,
513 "Loading firmware failed, using default values\n");
514 dev_warn(&isci_host->pdev->dev,
515 "Default OEM configuration being used:"
516 " 4 narrow ports, and default SAS Addresses\n");
517 goto set_default_params;
518 }
519 else {
520 status = isci_verify_firmware(fw, isci_fw);
521 if (status != SCI_SUCCESS) {
522 dev_warn(&isci_host->pdev->dev,
523 "firmware verification failed\n");
524 dev_warn(&isci_host->pdev->dev,
525 "Default OEM configuration being used:"
526 " 4 narrow ports, and default SAS "
527 "Addresses\n");
528 goto set_default_params;
529 }
530
531 /* grab any OEM and USER parameters specified at module load */
532 status = isci_parse_oem_parameters(&scic_oem_params, 437 status = isci_parse_oem_parameters(&scic_oem_params,
533 isci_host->id, isci_fw); 438 isci_host->id,
439 isci_firmware);
534 if (status != SCI_SUCCESS) { 440 if (status != SCI_SUCCESS) {
535 dev_warn(&isci_host->pdev->dev, 441 dev_warn(&isci_host->pdev->dev,
536 "parsing firmware oem parameters failed\n"); 442 "parsing firmware oem parameters failed\n");
537 err = -EINVAL; 443 return -EINVAL;
538 goto out;
539 } 444 }
540 445
541 status = isci_parse_user_parameters(&scic_user_params, 446 status = isci_parse_user_parameters(&scic_user_params,
542 isci_host->id, isci_fw); 447 isci_host->id,
448 isci_firmware);
543 if (status != SCI_SUCCESS) { 449 if (status != SCI_SUCCESS) {
544 dev_warn(&isci_host->pdev->dev, 450 dev_warn(&isci_host->pdev->dev,
545 "%s: isci_parse_user_parameters" 451 "%s: isci_parse_user_parameters"
546 " failed\n", __func__); 452 " failed\n", __func__);
547 err = -EINVAL; 453 return -EINVAL;
548 goto out; 454 }
455 } else {
456 status = scic_oem_parameters_set(isci_host->core_controller,
457 &scic_oem_params);
458 if (status != SCI_SUCCESS) {
459 dev_warn(&isci_host->pdev->dev,
460 "%s: scic_oem_parameters_set failed\n",
461 __func__);
462 return -ENODEV;
549 } 463 }
550 }
551
552 set_default_params:
553
554 status = scic_oem_parameters_set(isci_host->core_controller,
555 &scic_oem_params
556 );
557
558 if (status != SCI_SUCCESS) {
559 dev_warn(&isci_host->pdev->dev,
560 "%s: scic_oem_parameters_set failed\n",
561 __func__);
562 err = -ENODEV;
563 goto out;
564 }
565
566 464
567 status = scic_user_parameters_set(isci_host->core_controller,
568 &scic_user_params
569 );
570 465
571 if (status != SCI_SUCCESS) { 466 status = scic_user_parameters_set(isci_host->core_controller,
572 dev_warn(&isci_host->pdev->dev, 467 &scic_user_params);
573 "%s: scic_user_parameters_set failed\n", 468 if (status != SCI_SUCCESS) {
574 __func__); 469 dev_warn(&isci_host->pdev->dev,
575 err = -ENODEV; 470 "%s: scic_user_parameters_set failed\n",
576 goto out; 471 __func__);
472 return -ENODEV;
473 }
577 } 474 }
578 475
579 status = scic_controller_initialize(isci_host->core_controller); 476 status = scic_controller_initialize(isci_host->core_controller);
@@ -582,8 +479,7 @@ int isci_host_init(struct isci_host *isci_host)
582 "%s: scic_controller_initialize failed -" 479 "%s: scic_controller_initialize failed -"
583 " status = 0x%x\n", 480 " status = 0x%x\n",
584 __func__, status); 481 __func__, status);
585 err = -ENODEV; 482 return -ENODEV;
586 goto out;
587 } 483 }
588 484
589 tasklet_init(&isci_host->completion_tasklet, 485 tasklet_init(&isci_host->completion_tasklet,
@@ -598,7 +494,7 @@ int isci_host_init(struct isci_host *isci_host)
598 err = isci_host_mdl_allocate_coherent(isci_host); 494 err = isci_host_mdl_allocate_coherent(isci_host);
599 495
600 if (err) 496 if (err)
601 goto err_out; 497 return err;
602 498
603 /* 499 /*
604 * keep the pool alloc size around, will use it for a bounds checking 500 * keep the pool alloc size around, will use it for a bounds checking
@@ -610,40 +506,27 @@ int isci_host_init(struct isci_host *isci_host)
610 isci_host->dma_pool_alloc_size, 506 isci_host->dma_pool_alloc_size,
611 SLAB_HWCACHE_ALIGN, 0); 507 SLAB_HWCACHE_ALIGN, 0);
612 508
613 if (!isci_host->dma_pool) { 509 if (!isci_host->dma_pool)
614 err = -ENOMEM; 510 return -ENOMEM;
615 goto req_obj_err_out;
616 }
617 511
618 for (index = 0; index < SCI_MAX_PORTS; index++) { 512 for (index = 0; index < SCI_MAX_PORTS; index++)
619 isci_port_init(&isci_host->isci_ports[index], 513 isci_port_init(&isci_host->isci_ports[index],
620 isci_host, index); 514 isci_host,
621 } 515 index);
622 516
623 for (index = 0; index < SCI_MAX_PHYS; index++) 517 for (index = 0; index < SCI_MAX_PHYS; index++)
624 isci_phy_init(&isci_host->phys[index], isci_host, index); 518 isci_phy_init(&isci_host->phys[index], isci_host, index);
625 519
626 /* Why are we doing this? Is this even necessary? */ 520 /* Why are we doing this? Is this even necessary? */
627 memcpy(&isci_host->sas_addr[0], &isci_host->phys[0].sas_addr[0], 521 memcpy(&isci_host->sas_addr[0],
522 &isci_host->phys[0].sas_addr[0],
628 SAS_ADDR_SIZE); 523 SAS_ADDR_SIZE);
629 524
630 /* Start the ports */ 525 /* Start the ports */
631 for (index = 0; index < SCI_MAX_PORTS; index++) { 526 for (index = 0; index < SCI_MAX_PORTS; index++) {
632
633 scic_controller_get_port_handle(controller, index, &scic_port); 527 scic_controller_get_port_handle(controller, index, &scic_port);
634 scic_port_start(scic_port); 528 scic_port_start(scic_port);
635 } 529 }
636 530
637 goto out; 531 return 0;
638
639/* SPB_Debug: destroy request object cache */
640 req_obj_err_out:
641/* SPB_Debug: destroy remote object cache */
642 err_out:
643/* SPB_Debug: undo controller init, construct and alloc, remove from parent
644 * controller list. */
645 out:
646 if (fw)
647 release_firmware(fw);
648 return err;
649} 532}
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c
index fda26292ba2b..6ca623aff051 100644
--- a/drivers/scsi/isci/init.c
+++ b/drivers/scsi/isci/init.c
@@ -82,6 +82,8 @@ static DEFINE_PCI_DEVICE_TABLE(isci_id_table) = {
82 {} 82 {}
83}; 83};
84 84
85struct isci_firmware *isci_firmware;
86
85static int __devinit isci_pci_probe( 87static int __devinit isci_pci_probe(
86 struct pci_dev *pdev, 88 struct pci_dev *pdev,
87 const struct pci_device_id *device_id_p); 89 const struct pci_device_id *device_id_p);
@@ -519,11 +521,73 @@ static void check_si_rev(struct pci_dev *pdev)
519 521
520} 522}
521 523
524static int isci_verify_firmware(const struct firmware *fw,
525 struct isci_firmware *isci_fw)
526{
527 const u8 *tmp;
528
529 if (fw->size < ISCI_FIRMWARE_MIN_SIZE)
530 return -EINVAL;
531
532 tmp = fw->data;
533
534 /* 12th char should be the NULL terminate for the ID string */
535 if (tmp[11] != '\0')
536 return -EINVAL;
537
538 if (strncmp("#SCU MAGIC#", tmp, 11) != 0)
539 return -EINVAL;
540
541 isci_fw->id = tmp;
542 isci_fw->version = fw->data[ISCI_FW_VER_OFS];
543 isci_fw->subversion = fw->data[ISCI_FW_SUBVER_OFS];
544
545 tmp = fw->data + ISCI_FW_DATA_OFS;
546
547 while (*tmp != ISCI_FW_HDR_EOF) {
548 switch (*tmp) {
549 case ISCI_FW_HDR_PHYMASK:
550 tmp++;
551 isci_fw->phy_masks_size = *tmp;
552 tmp++;
553 isci_fw->phy_masks = (const u32 *)tmp;
554 tmp += sizeof(u32) * isci_fw->phy_masks_size;
555 break;
556
557 case ISCI_FW_HDR_PHYGEN:
558 tmp++;
559 isci_fw->phy_gens_size = *tmp;
560 tmp++;
561 isci_fw->phy_gens = (const u32 *)tmp;
562 tmp += sizeof(u32) * isci_fw->phy_gens_size;
563 break;
564
565 case ISCI_FW_HDR_SASADDR:
566 tmp++;
567 isci_fw->sas_addrs_size = *tmp;
568 tmp++;
569 isci_fw->sas_addrs = (const u64 *)tmp;
570 tmp += sizeof(u64) * isci_fw->sas_addrs_size;
571 break;
572
573 default:
574 pr_err("bad field in firmware binary blob\n");
575 return -EINVAL;
576 }
577 }
578
579 pr_info("isci firmware v%u.%u loaded.\n",
580 isci_fw->version, isci_fw->subversion);
581
582 return SCI_SUCCESS;
583}
584
522static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 585static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
523{ 586{
524 struct isci_pci_info *pci_info; 587 struct isci_pci_info *pci_info;
525 int err, i; 588 int err, i;
526 struct isci_host *isci_host; 589 struct isci_host *isci_host;
590 const struct firmware *fw = NULL;
527 591
528 check_si_rev(pdev); 592 check_si_rev(pdev);
529 593
@@ -532,6 +596,33 @@ static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_devic
532 return -ENOMEM; 596 return -ENOMEM;
533 pci_set_drvdata(pdev, pci_info); 597 pci_set_drvdata(pdev, pci_info);
534 598
599 err = request_firmware(&fw, ISCI_FW_NAME, &pdev->dev);
600 if (err) {
601 dev_warn(&pdev->dev,
602 "Loading firmware failed, using default values\n");
603 dev_warn(&pdev->dev,
604 "Default OEM configuration being used:"
605 " 4 narrow ports, and default SAS Addresses\n");
606 } else {
607 isci_firmware = devm_kzalloc(&pdev->dev,
608 sizeof(struct isci_firmware),
609 GFP_KERNEL);
610 if (isci_firmware) {
611 err = isci_verify_firmware(fw, isci_firmware);
612 if (err != SCI_SUCCESS) {
613 dev_warn(&pdev->dev,
614 "firmware verification failed\n");
615 dev_warn(&pdev->dev,
616 "Default OEM configuration being used:"
617 " 4 narrow ports, and default SAS "
618 "Addresses\n");
619 devm_kfree(&pdev->dev, isci_firmware);
620 isci_firmware = NULL;
621 }
622 }
623 release_firmware(fw);
624 }
625
535 err = isci_pci_init(pdev); 626 err = isci_pci_init(pdev);
536 if (err) 627 if (err)
537 return err; 628 return err;
diff --git a/drivers/scsi/isci/isci.h b/drivers/scsi/isci/isci.h
index 39efd5f27200..6c79b29f3102 100644
--- a/drivers/scsi/isci/isci.h
+++ b/drivers/scsi/isci/isci.h
@@ -86,6 +86,7 @@
86#include "sci_status.h" 86#include "sci_status.h"
87 87
88extern struct kmem_cache *isci_kmem_cache; 88extern struct kmem_cache *isci_kmem_cache;
89extern struct isci_firmware *isci_firmware;
89 90
90#define ISCI_FW_NAME "isci/isci_firmware.bin" 91#define ISCI_FW_NAME "isci/isci_firmware.bin"
91 92