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