init.c (57b8628bb0ac4e47c806e45c5bbd89282e93869b) init.c (abec912d71c44bbd642ce12ad98aab76f5a53163)
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *

--- 383 unchanged lines hidden (view full) ---

392 err = devm_request_irq(&pdev->dev, pdev->irq, isci_intx_isr,
393 IRQF_SHARED, DRV_NAME"-intx", ihost);
394 if (err)
395 break;
396 }
397 return err;
398}
399
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *

--- 383 unchanged lines hidden (view full) ---

392 err = devm_request_irq(&pdev->dev, pdev->irq, isci_intx_isr,
393 IRQF_SHARED, DRV_NAME"-intx", ihost);
394 if (err)
395 break;
396 }
397 return err;
398}
399
400static void isci_user_parameters_get(struct sci_user_parameters *u)
401{
402 int i;
403
404 for (i = 0; i < SCI_MAX_PHYS; i++) {
405 struct sci_phy_user_params *u_phy = &u->phys[i];
406
407 u_phy->max_speed_generation = phy_gen;
408
409 /* we are not exporting these for now */
410 u_phy->align_insertion_frequency = 0x7f;
411 u_phy->in_connection_align_insertion_frequency = 0xff;
412 u_phy->notify_enable_spin_up_insertion_frequency = 0x33;
413 }
414
415 u->stp_inactivity_timeout = stp_inactive_to;
416 u->ssp_inactivity_timeout = ssp_inactive_to;
417 u->stp_max_occupancy_timeout = stp_max_occ_to;
418 u->ssp_max_occupancy_timeout = ssp_max_occ_to;
419 u->no_outbound_task_timeout = no_outbound_task_to;
420 u->max_concurr_spinup = max_concurr_spinup;
421}
422
423static enum sci_status sci_user_parameters_set(struct isci_host *ihost,
424 struct sci_user_parameters *sci_parms)
425{
426 u16 index;
427
428 /*
429 * Validate the user parameters. If they are not legal, then
430 * return a failure.
431 */
432 for (index = 0; index < SCI_MAX_PHYS; index++) {
433 struct sci_phy_user_params *u;
434
435 u = &sci_parms->phys[index];
436
437 if (!((u->max_speed_generation <= SCIC_SDS_PARM_MAX_SPEED) &&
438 (u->max_speed_generation > SCIC_SDS_PARM_NO_SPEED)))
439 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
440
441 if (u->in_connection_align_insertion_frequency < 3)
442 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
443
444 if ((u->in_connection_align_insertion_frequency < 3) ||
445 (u->align_insertion_frequency == 0) ||
446 (u->notify_enable_spin_up_insertion_frequency == 0))
447 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
448 }
449
450 if ((sci_parms->stp_inactivity_timeout == 0) ||
451 (sci_parms->ssp_inactivity_timeout == 0) ||
452 (sci_parms->stp_max_occupancy_timeout == 0) ||
453 (sci_parms->ssp_max_occupancy_timeout == 0) ||
454 (sci_parms->no_outbound_task_timeout == 0))
455 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
456
457 memcpy(&ihost->user_parameters, sci_parms, sizeof(*sci_parms));
458
459 return SCI_SUCCESS;
460}
461
462static void sci_oem_defaults(struct isci_host *ihost)
463{
464 /* these defaults are overridden by the platform / firmware */
465 struct sci_user_parameters *user = &ihost->user_parameters;
466 struct sci_oem_params *oem = &ihost->oem_parameters;
467 int i;
468
469 /* Default to APC mode. */
470 oem->controller.mode_type = SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE;
471
472 /* Default to APC mode. */
473 oem->controller.max_concurr_spin_up = 1;
474
475 /* Default to no SSC operation. */
476 oem->controller.do_enable_ssc = false;
477
478 /* Default to short cables on all phys. */
479 oem->controller.cable_selection_mask = 0;
480
481 /* Initialize all of the port parameter information to narrow ports. */
482 for (i = 0; i < SCI_MAX_PORTS; i++)
483 oem->ports[i].phy_mask = 0;
484
485 /* Initialize all of the phy parameter information. */
486 for (i = 0; i < SCI_MAX_PHYS; i++) {
487 /* Default to 3G (i.e. Gen 2). */
488 user->phys[i].max_speed_generation = SCIC_SDS_PARM_GEN2_SPEED;
489
490 /* the frequencies cannot be 0 */
491 user->phys[i].align_insertion_frequency = 0x7f;
492 user->phys[i].in_connection_align_insertion_frequency = 0xff;
493 user->phys[i].notify_enable_spin_up_insertion_frequency = 0x33;
494
495 /* Previous Vitesse based expanders had a arbitration issue that
496 * is worked around by having the upper 32-bits of SAS address
497 * with a value greater then the Vitesse company identifier.
498 * Hence, usage of 0x5FCFFFFF.
499 */
500 oem->phys[i].sas_address.low = 0x1 + ihost->id;
501 oem->phys[i].sas_address.high = 0x5FCFFFFF;
502 }
503
504 user->stp_inactivity_timeout = 5;
505 user->ssp_inactivity_timeout = 5;
506 user->stp_max_occupancy_timeout = 5;
507 user->ssp_max_occupancy_timeout = 20;
508 user->no_outbound_task_timeout = 2;
509}
510
400static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id)
401{
511static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id)
512{
402 struct isci_host *isci_host;
513 struct isci_orom *orom = to_pci_info(pdev)->orom;
514 struct sci_user_parameters sci_user_params;
515 u8 oem_version = ISCI_ROM_VER_1_0;
516 struct isci_host *ihost;
403 struct Scsi_Host *shost;
517 struct Scsi_Host *shost;
404 int err;
518 int err, i;
405
519
406 isci_host = devm_kzalloc(&pdev->dev, sizeof(*isci_host), GFP_KERNEL);
407 if (!isci_host)
520 ihost = devm_kzalloc(&pdev->dev, sizeof(*ihost), GFP_KERNEL);
521 if (!ihost)
408 return NULL;
409
522 return NULL;
523
410 isci_host->pdev = pdev;
411 isci_host->id = id;
524 ihost->pdev = pdev;
525 ihost->id = id;
526 spin_lock_init(&ihost->scic_lock);
527 init_waitqueue_head(&ihost->eventq);
528 ihost->sas_ha.dev = &ihost->pdev->dev;
529 ihost->sas_ha.lldd_ha = ihost;
530 tasklet_init(&ihost->completion_tasklet,
531 isci_host_completion_routine, (unsigned long)ihost);
412
532
533 /* validate module parameters */
534 /* TODO: kill struct sci_user_parameters and reference directly */
535 sci_oem_defaults(ihost);
536 isci_user_parameters_get(&sci_user_params);
537 if (sci_user_parameters_set(ihost, &sci_user_params)) {
538 dev_warn(&pdev->dev,
539 "%s: sci_user_parameters_set failed\n", __func__);
540 return NULL;
541 }
542
543 /* sanity check platform (or 'firmware') oem parameters */
544 if (orom) {
545 if (id < 0 || id >= SCI_MAX_CONTROLLERS || id > orom->hdr.num_elements) {
546 dev_warn(&pdev->dev, "parsing firmware oem parameters failed\n");
547 return NULL;
548 }
549 ihost->oem_parameters = orom->ctrl[id];
550 oem_version = orom->hdr.version;
551 }
552
553 /* validate oem parameters (platform, firmware, or built-in defaults) */
554 if (sci_oem_parameters_validate(&ihost->oem_parameters, oem_version)) {
555 dev_warn(&pdev->dev, "oem parameter validation failed\n");
556 return NULL;
557 }
558
559 INIT_LIST_HEAD(&ihost->requests_to_complete);
560 INIT_LIST_HEAD(&ihost->requests_to_errorback);
561 for (i = 0; i < SCI_MAX_PORTS; i++) {
562 struct isci_port *iport = &ihost->ports[i];
563
564 INIT_LIST_HEAD(&iport->remote_dev_list);
565 iport->isci_host = ihost;
566 }
567
568 for (i = 0; i < SCI_MAX_PHYS; i++)
569 isci_phy_init(&ihost->phys[i], ihost, i);
570
571 for (i = 0; i < SCI_MAX_REMOTE_DEVICES; i++) {
572 struct isci_remote_device *idev = &ihost->devices[i];
573
574 INIT_LIST_HEAD(&idev->reqs_in_process);
575 INIT_LIST_HEAD(&idev->node);
576 }
577
413 shost = scsi_host_alloc(&isci_sht, sizeof(void *));
414 if (!shost)
415 return NULL;
578 shost = scsi_host_alloc(&isci_sht, sizeof(void *));
579 if (!shost)
580 return NULL;
416 isci_host->shost = shost;
581 ihost->shost = shost;
417
418 dev_info(&pdev->dev, "%sSCU controller %d: phy 3-0 cables: "
419 "{%s, %s, %s, %s}\n",
582
583 dev_info(&pdev->dev, "%sSCU controller %d: phy 3-0 cables: "
584 "{%s, %s, %s, %s}\n",
420 (is_cable_select_overridden() ? "* " : ""), isci_host->id,
421 lookup_cable_names(decode_cable_selection(isci_host, 3)),
422 lookup_cable_names(decode_cable_selection(isci_host, 2)),
423 lookup_cable_names(decode_cable_selection(isci_host, 1)),
424 lookup_cable_names(decode_cable_selection(isci_host, 0)));
585 (is_cable_select_overridden() ? "* " : ""), ihost->id,
586 lookup_cable_names(decode_cable_selection(ihost, 3)),
587 lookup_cable_names(decode_cable_selection(ihost, 2)),
588 lookup_cable_names(decode_cable_selection(ihost, 1)),
589 lookup_cable_names(decode_cable_selection(ihost, 0)));
425
590
426 err = isci_host_init(isci_host);
591 err = isci_host_init(ihost);
427 if (err)
428 goto err_shost;
429
592 if (err)
593 goto err_shost;
594
430 SHOST_TO_SAS_HA(shost) = &isci_host->sas_ha;
431 isci_host->sas_ha.core.shost = shost;
595 SHOST_TO_SAS_HA(shost) = &ihost->sas_ha;
596 ihost->sas_ha.core.shost = shost;
432 shost->transportt = isci_transport_template;
433
434 shost->max_id = ~0;
435 shost->max_lun = ~0;
436 shost->max_cmd_len = MAX_COMMAND_SIZE;
437
438 err = scsi_add_host(shost, &pdev->dev);
439 if (err)
440 goto err_shost;
441
597 shost->transportt = isci_transport_template;
598
599 shost->max_id = ~0;
600 shost->max_lun = ~0;
601 shost->max_cmd_len = MAX_COMMAND_SIZE;
602
603 err = scsi_add_host(shost, &pdev->dev);
604 if (err)
605 goto err_shost;
606
442 err = isci_register_sas_ha(isci_host);
607 err = isci_register_sas_ha(ihost);
443 if (err)
444 goto err_shost_remove;
445
608 if (err)
609 goto err_shost_remove;
610
446 return isci_host;
611 return ihost;
447
448 err_shost_remove:
449 scsi_remove_host(shost);
450 err_shost:
451 scsi_host_put(shost);
452
453 return NULL;
454}

--- 142 unchanged lines hidden ---
612
613 err_shost_remove:
614 scsi_remove_host(shost);
615 err_shost:
616 scsi_host_put(shost);
617
618 return NULL;
619}

--- 142 unchanged lines hidden ---