4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 /*
27 *
28 * nv_sata is a combo SATA HBA driver for ck804/mcp5x (mcp5x = mcp55/mcp51)
29 * based chipsets.
30 *
31 * NCQ
32 * ---
33 *
34 * A portion of the NCQ is in place, but is incomplete. NCQ is disabled
35 * and is likely to be revisited in the future.
36 *
37 *
38 * Power Management
39 * ----------------
40 *
41 * Normally power management would be responsible for ensuring the device
42 * is quiescent and then changing power states to the device, such as
43 * powering down parts or all of the device. mcp5x/ck804 is unique in
44 * that it is only available as part of a larger southbridge chipset, so
45 * removing power to the device isn't possible. Switches to control
46 * power management states D0/D3 in the PCI configuration space appear to
47 * be supported but changes to these states are apparently are ignored.
48 * The only further PM that the driver _could_ do is shut down the PHY,
49 * but in order to deliver the first rev of the driver sooner than later,
295 /*
296 * Request Sense CDB for ATAPI
297 */
298 static const uint8_t nv_rqsense_cdb[16] = {
299 SCMD_REQUEST_SENSE,
300 0,
301 0,
302 0,
303 SATA_ATAPI_MIN_RQSENSE_LEN,
304 0,
305 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* pad out to max CDB length */
306 };
307
308
309 static sata_tran_hotplug_ops_t nv_hotplug_ops;
310
311 extern struct mod_ops mod_driverops;
312
313 static struct modldrv modldrv = {
314 &mod_driverops, /* driverops */
315 "Nvidia ck804/mcp51/mcp55 HBA",
316 &nv_dev_ops, /* driver ops */
317 };
318
319 static struct modlinkage modlinkage = {
320 MODREV_1,
321 &modldrv,
322 NULL
323 };
324
325 /*
326 * Maximum number of consecutive interrupts processed in the loop in the
327 * single invocation of the port interrupt routine.
328 */
329 int nv_max_intr_loops = NV_MAX_INTR_PER_DEV;
330
331 /*
332 * wait between checks of reg status
333 */
334 int nv_usec_delay = NV_WAIT_REG_CHECK;
335
582
583 case DDI_ATTACH:
584
585 attach_state = ATTACH_PROGRESS_NONE;
586
587 status = ddi_soft_state_zalloc(nv_statep, inst);
588
589 if (status != DDI_SUCCESS) {
590 break;
591 }
592
593 nvc = ddi_get_soft_state(nv_statep, inst);
594
595 nvc->nvc_dip = dip;
596
597 NVLOG(NVDBG_INIT, nvc, NULL, "nv_attach(): DDI_ATTACH", NULL);
598
599 attach_state |= ATTACH_PROGRESS_STATEP_ALLOC;
600
601 if (pci_config_setup(dip, &pci_conf_handle) == DDI_SUCCESS) {
602 nvc->nvc_revid = pci_config_get8(pci_conf_handle,
603 PCI_CONF_REVID);
604 NVLOG(NVDBG_INIT, nvc, NULL,
605 "inst %d: silicon revid is %x nv_debug_flags=%x",
606 inst, nvc->nvc_revid, nv_debug_flags);
607 } else {
608 break;
609 }
610
611 attach_state |= ATTACH_PROGRESS_CONF_HANDLE;
612
613 /*
614 * Set the PCI command register: enable IO/MEM/Master.
615 */
616 command = pci_config_get16(pci_conf_handle, PCI_CONF_COMM);
617 pci_config_put16(pci_conf_handle, PCI_CONF_COMM,
618 command|PCI_COMM_IO|PCI_COMM_MAE|PCI_COMM_ME);
619
620 subclass = pci_config_get8(pci_conf_handle, PCI_CONF_SUBCLASS);
621
622 if (subclass & PCI_MASS_RAID) {
623 cmn_err(CE_WARN,
624 "attach failed: RAID mode not supported");
625
626 break;
2477
2478
2479 serr = nv_get32(bar5_hdl, nvp->nvp_serror);
2480 DTRACE_PROBE1(last_serror_h, int, serr);
2481
2482 if (reset_success == B_FALSE) {
2483 NVLOG(NVDBG_RESET, nvc, nvp, "nv_reset not succeeded "
2484 "after %d attempts. serr: 0x%x", i, serr);
2485 } else {
2486 NVLOG(NVDBG_RESET, nvc, nvp, "nv_reset succeeded"
2487 " after %dms. serr: 0x%x", TICK_TO_MSEC(ddi_get_lbolt() -
2488 nvp->nvp_reset_time), serr);
2489 }
2490
2491 nvp->nvp_wait_sig = NV_WAIT_SIG;
2492 nv_setup_timeout(nvp, nvp->nvp_wait_sig);
2493 }
2494
2495
2496 /*
2497 * Initialize register handling specific to mcp51/mcp55
2498 */
2499 /* ARGSUSED */
2500 static void
2501 mcp5x_reg_init(nv_ctl_t *nvc, ddi_acc_handle_t pci_conf_handle)
2502 {
2503 nv_port_t *nvp;
2504 uchar_t *bar5 = nvc->nvc_bar_addr[5];
2505 uint8_t off, port;
2506
2507 nvc->nvc_mcp5x_ctl = (uint32_t *)(bar5 + MCP5X_CTL);
2508 nvc->nvc_mcp5x_ncq = (uint32_t *)(bar5 + MCP5X_NCQ);
2509
2510 for (port = 0, off = 0; port < NV_MAX_PORTS(nvc); port++, off += 2) {
2511 nvp = &(nvc->nvc_port[port]);
2512 nvp->nvp_mcp5x_int_status =
2513 (uint16_t *)(bar5 + MCP5X_INT_STATUS + off);
2514 nvp->nvp_mcp5x_int_ctl =
2515 (uint16_t *)(bar5 + MCP5X_INT_CTL + off);
2516
2517 /*
2532 nv_put16(nvc->nvc_bar_hdl[5], nvp->nvp_mcp5x_int_ctl,
2533 ~(MCP5X_INT_IGNORE));
2534 }
2535
2536 /*
2537 * Allow the driver to program the BM on the first command instead
2538 * of waiting for an interrupt.
2539 */
2540 #ifdef NCQ
2541 flags = MCP_SATA_AE_NCQ_PDEV_FIRST_CMD | MCP_SATA_AE_NCQ_SDEV_FIRST_CMD;
2542 nv_put32(nvc->nvc_bar_hdl[5], nvc->nvc_mcp5x_ncq, flags);
2543 flags = MCP_SATA_AE_CTL_PRI_SWNCQ | MCP_SATA_AE_CTL_SEC_SWNCQ;
2544 nv_put32(nvc->nvc_bar_hdl[5], nvc->nvc_mcp5x_ctl, flags);
2545 #endif
2546
2547 /*
2548 * mcp55 rev A03 and above supports 40-bit physical addressing.
2549 * Enable DMA to take advantage of that.
2550 *
2551 */
2552 if (nvc->nvc_revid >= 0xa3) {
2553 if (nv_sata_40bit_dma == B_TRUE) {
2554 uint32_t reg32;
2555 NVLOG(NVDBG_INIT, nvp->nvp_ctlp, nvp,
2556 "rev id is %X. 40-bit DMA addressing"
2557 " enabled", nvc->nvc_revid);
2558 nvc->dma_40bit = B_TRUE;
2559
2560 reg32 = pci_config_get32(pci_conf_handle,
2561 NV_SATA_CFG_20);
2562 pci_config_put32(pci_conf_handle, NV_SATA_CFG_20,
2563 reg32 | NV_40BIT_PRD);
2564
2565 /*
2566 * CFG_23 bits 0-7 contain the top 8 bits (of 40
2567 * bits) for the primary PRD table, and bits 8-15
2568 * contain the top 8 bits for the secondary. Set
2569 * to zero because the DMA attribute table for PRD
2570 * allocation forces it into 32 bit address space
2571 * anyway.
2572 */
2573 reg32 = pci_config_get32(pci_conf_handle,
2574 NV_SATA_CFG_23);
2575 pci_config_put32(pci_conf_handle, NV_SATA_CFG_23,
2576 reg32 & 0xffff0000);
2577 } else {
2578 NVLOG(NVDBG_INIT, nvp->nvp_ctlp, nvp,
2579 "40-bit DMA disabled by nv_sata_40bit_dma", NULL);
2580 }
2581 } else {
2582 nv_cmn_err(CE_NOTE, nvp->nvp_ctlp, nvp, "rev id is %X and is "
2583 "not capable of 40-bit DMA addressing", nvc->nvc_revid);
2584 }
2585 }
2586
2587
2588 /*
2589 * Initialize register handling specific to ck804
2590 */
2591 static void
2592 ck804_reg_init(nv_ctl_t *nvc, ddi_acc_handle_t pci_conf_handle)
2593 {
2594 uchar_t *bar5 = nvc->nvc_bar_addr[5];
2595 uint32_t reg32;
2596 uint16_t reg16;
2597 nv_port_t *nvp;
2598 int j;
2599
2600 /*
2601 * delay hotplug interrupts until PHYRDY.
2602 */
2603 reg32 = pci_config_get32(pci_conf_handle, NV_SATA_CFG_42);
2625 */
2626 for (j = 0; j < NV_MAX_PORTS(nvc); j++) {
2627 nvp = &(nvc->nvc_port[j]);
2628 mutex_enter(&nvp->nvp_mutex);
2629 (*(nvp->nvp_ctlp->nvc_set_intr))(nvp,
2630 NV_INTR_CLEAR_ALL|NV_INTR_ENABLE);
2631 mutex_exit(&nvp->nvp_mutex);
2632 }
2633 }
2634
2635
2636 /*
2637 * Initialize the controller and set up driver data structures.
2638 * determine if ck804 or mcp5x class.
2639 */
2640 static int
2641 nv_init_ctl(nv_ctl_t *nvc, ddi_acc_handle_t pci_conf_handle)
2642 {
2643 struct sata_hba_tran stran;
2644 nv_port_t *nvp;
2645 int j, ck804;
2646 uchar_t *cmd_addr, *ctl_addr, *bm_addr;
2647 ddi_acc_handle_t bar5_hdl = nvc->nvc_bar_hdl[5];
2648 uchar_t *bar5 = nvc->nvc_bar_addr[5];
2649 uint32_t reg32;
2650 uint8_t reg8, reg8_save;
2651
2652 NVLOG(NVDBG_INIT, nvc, NULL, "nv_init_ctl entered", NULL);
2653
2654 ck804 = B_TRUE;
2655 #ifdef SGPIO_SUPPORT
2656 nvc->nvc_mcp5x_flag = B_FALSE;
2657 #endif
2658
2659 /*
2660 * Need to set bit 2 to 1 at config offset 0x50
2661 * to enable access to the bar5 registers.
2662 */
2663 reg32 = pci_config_get32(pci_conf_handle, NV_SATA_CFG_20);
2664 if (!(reg32 & NV_BAR5_SPACE_EN)) {
2665 pci_config_put32(pci_conf_handle, NV_SATA_CFG_20,
2666 reg32 | NV_BAR5_SPACE_EN);
2667 }
2668
2669 /*
2670 * Determine if this is ck804 or mcp5x. ck804 will map in the
2671 * task file registers into bar5 while mcp5x won't. The offset of
2672 * the task file registers in mcp5x's space is unused, so it will
2673 * return zero. So check one of the task file registers to see if it is
2674 * writable and reads back what was written. If it's mcp5x it will
2675 * return back 0xff whereas ck804 will return the value written.
2676 */
2677 reg8_save = nv_get8(bar5_hdl,
2678 (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X));
2679
2680
2681 for (j = 1; j < 3; j++) {
2682
2683 nv_put8(bar5_hdl, (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X), j);
2684 reg8 = nv_get8(bar5_hdl,
2685 (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X));
2686
2687 if (reg8 != j) {
2688 ck804 = B_FALSE;
2689 nvc->nvc_mcp5x_flag = B_TRUE;
2690 break;
2691 }
2692 }
2693
2694 nv_put8(bar5_hdl, (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X), reg8_save);
2695
2696 if (ck804 == B_TRUE) {
2697 NVLOG(NVDBG_INIT, nvc, NULL, "controller is CK804", NULL);
2698 nvc->nvc_interrupt = ck804_intr;
2699 nvc->nvc_reg_init = ck804_reg_init;
2700 nvc->nvc_set_intr = ck804_set_intr;
2701 } else {
2702 NVLOG(NVDBG_INIT, nvc, NULL, "controller is MCP51/MCP55", NULL);
2703 nvc->nvc_interrupt = mcp5x_intr;
2704 nvc->nvc_reg_init = mcp5x_reg_init;
2705 nvc->nvc_set_intr = mcp5x_set_intr;
2706 }
2707
2708
2709 stran.sata_tran_hba_rev = SATA_TRAN_HBA_REV;
2710 stran.sata_tran_hba_dip = nvc->nvc_dip;
2711 stran.sata_tran_hba_num_cports = NV_NUM_PORTS;
2712 stran.sata_tran_hba_features_support =
2713 SATA_CTLF_HOTPLUG | SATA_CTLF_ASN | SATA_CTLF_ATAPI;
2714 stran.sata_tran_hba_qdepth = NV_QUEUE_SLOTS;
2715 stran.sata_tran_probe_port = nv_sata_probe;
2716 stran.sata_tran_start = nv_sata_start;
2717 stran.sata_tran_abort = nv_sata_abort;
2718 stran.sata_tran_reset_dport = nv_sata_reset;
2719 stran.sata_tran_selftest = NULL;
2720 stran.sata_tran_hotplug_ops = &nv_hotplug_ops;
2721 stran.sata_tran_pwrmgt_ops = NULL;
2722 stran.sata_tran_ioctl = NULL;
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 /*
28 *
29 * nv_sata is a combo SATA HBA driver for CK804/MCP04 (ck804) and
30 * MCP55/MCP51/MCP61 (mcp5x) based chipsets.
31 *
32 * NCQ
33 * ---
34 *
35 * A portion of the NCQ is in place, but is incomplete. NCQ is disabled
36 * and is likely to be revisited in the future.
37 *
38 *
39 * Power Management
40 * ----------------
41 *
42 * Normally power management would be responsible for ensuring the device
43 * is quiescent and then changing power states to the device, such as
44 * powering down parts or all of the device. mcp5x/ck804 is unique in
45 * that it is only available as part of a larger southbridge chipset, so
46 * removing power to the device isn't possible. Switches to control
47 * power management states D0/D3 in the PCI configuration space appear to
48 * be supported but changes to these states are apparently are ignored.
49 * The only further PM that the driver _could_ do is shut down the PHY,
50 * but in order to deliver the first rev of the driver sooner than later,
296 /*
297 * Request Sense CDB for ATAPI
298 */
299 static const uint8_t nv_rqsense_cdb[16] = {
300 SCMD_REQUEST_SENSE,
301 0,
302 0,
303 0,
304 SATA_ATAPI_MIN_RQSENSE_LEN,
305 0,
306 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* pad out to max CDB length */
307 };
308
309
310 static sata_tran_hotplug_ops_t nv_hotplug_ops;
311
312 extern struct mod_ops mod_driverops;
313
314 static struct modldrv modldrv = {
315 &mod_driverops, /* driverops */
316 "NVIDIA CK804/MCP04/MCP51/MCP55/MCP61 HBA",
317 &nv_dev_ops, /* driver ops */
318 };
319
320 static struct modlinkage modlinkage = {
321 MODREV_1,
322 &modldrv,
323 NULL
324 };
325
326 /*
327 * Maximum number of consecutive interrupts processed in the loop in the
328 * single invocation of the port interrupt routine.
329 */
330 int nv_max_intr_loops = NV_MAX_INTR_PER_DEV;
331
332 /*
333 * wait between checks of reg status
334 */
335 int nv_usec_delay = NV_WAIT_REG_CHECK;
336
583
584 case DDI_ATTACH:
585
586 attach_state = ATTACH_PROGRESS_NONE;
587
588 status = ddi_soft_state_zalloc(nv_statep, inst);
589
590 if (status != DDI_SUCCESS) {
591 break;
592 }
593
594 nvc = ddi_get_soft_state(nv_statep, inst);
595
596 nvc->nvc_dip = dip;
597
598 NVLOG(NVDBG_INIT, nvc, NULL, "nv_attach(): DDI_ATTACH", NULL);
599
600 attach_state |= ATTACH_PROGRESS_STATEP_ALLOC;
601
602 if (pci_config_setup(dip, &pci_conf_handle) == DDI_SUCCESS) {
603 nvc->nvc_devid = pci_config_get16(pci_conf_handle,
604 PCI_CONF_DEVID);
605 nvc->nvc_revid = pci_config_get8(pci_conf_handle,
606 PCI_CONF_REVID);
607 NVLOG(NVDBG_INIT, nvc, NULL,
608 "inst %d: devid is %x silicon revid is %x"
609 " nv_debug_flags=%x", inst, nvc->nvc_devid,
610 nvc->nvc_revid, nv_debug_flags);
611 } else {
612 break;
613 }
614
615 attach_state |= ATTACH_PROGRESS_CONF_HANDLE;
616
617 /*
618 * Set the PCI command register: enable IO/MEM/Master.
619 */
620 command = pci_config_get16(pci_conf_handle, PCI_CONF_COMM);
621 pci_config_put16(pci_conf_handle, PCI_CONF_COMM,
622 command|PCI_COMM_IO|PCI_COMM_MAE|PCI_COMM_ME);
623
624 subclass = pci_config_get8(pci_conf_handle, PCI_CONF_SUBCLASS);
625
626 if (subclass & PCI_MASS_RAID) {
627 cmn_err(CE_WARN,
628 "attach failed: RAID mode not supported");
629
630 break;
2481
2482
2483 serr = nv_get32(bar5_hdl, nvp->nvp_serror);
2484 DTRACE_PROBE1(last_serror_h, int, serr);
2485
2486 if (reset_success == B_FALSE) {
2487 NVLOG(NVDBG_RESET, nvc, nvp, "nv_reset not succeeded "
2488 "after %d attempts. serr: 0x%x", i, serr);
2489 } else {
2490 NVLOG(NVDBG_RESET, nvc, nvp, "nv_reset succeeded"
2491 " after %dms. serr: 0x%x", TICK_TO_MSEC(ddi_get_lbolt() -
2492 nvp->nvp_reset_time), serr);
2493 }
2494
2495 nvp->nvp_wait_sig = NV_WAIT_SIG;
2496 nv_setup_timeout(nvp, nvp->nvp_wait_sig);
2497 }
2498
2499
2500 /*
2501 * Initialize register handling specific to mcp51/mcp55/mcp61
2502 */
2503 /* ARGSUSED */
2504 static void
2505 mcp5x_reg_init(nv_ctl_t *nvc, ddi_acc_handle_t pci_conf_handle)
2506 {
2507 nv_port_t *nvp;
2508 uchar_t *bar5 = nvc->nvc_bar_addr[5];
2509 uint8_t off, port;
2510
2511 nvc->nvc_mcp5x_ctl = (uint32_t *)(bar5 + MCP5X_CTL);
2512 nvc->nvc_mcp5x_ncq = (uint32_t *)(bar5 + MCP5X_NCQ);
2513
2514 for (port = 0, off = 0; port < NV_MAX_PORTS(nvc); port++, off += 2) {
2515 nvp = &(nvc->nvc_port[port]);
2516 nvp->nvp_mcp5x_int_status =
2517 (uint16_t *)(bar5 + MCP5X_INT_STATUS + off);
2518 nvp->nvp_mcp5x_int_ctl =
2519 (uint16_t *)(bar5 + MCP5X_INT_CTL + off);
2520
2521 /*
2536 nv_put16(nvc->nvc_bar_hdl[5], nvp->nvp_mcp5x_int_ctl,
2537 ~(MCP5X_INT_IGNORE));
2538 }
2539
2540 /*
2541 * Allow the driver to program the BM on the first command instead
2542 * of waiting for an interrupt.
2543 */
2544 #ifdef NCQ
2545 flags = MCP_SATA_AE_NCQ_PDEV_FIRST_CMD | MCP_SATA_AE_NCQ_SDEV_FIRST_CMD;
2546 nv_put32(nvc->nvc_bar_hdl[5], nvc->nvc_mcp5x_ncq, flags);
2547 flags = MCP_SATA_AE_CTL_PRI_SWNCQ | MCP_SATA_AE_CTL_SEC_SWNCQ;
2548 nv_put32(nvc->nvc_bar_hdl[5], nvc->nvc_mcp5x_ctl, flags);
2549 #endif
2550
2551 /*
2552 * mcp55 rev A03 and above supports 40-bit physical addressing.
2553 * Enable DMA to take advantage of that.
2554 *
2555 */
2556 if ((nvc->nvc_devid > 0x37f) ||
2557 ((nvc->nvc_devid == 0x37f) && (nvc->nvc_revid >= 0xa3))) {
2558 if (nv_sata_40bit_dma == B_TRUE) {
2559 uint32_t reg32;
2560 NVLOG(NVDBG_INIT, nvp->nvp_ctlp, nvp,
2561 "devid is %X revid is %X. 40-bit DMA"
2562 " addressing enabled", nvc->nvc_devid,
2563 nvc->nvc_revid);
2564 nvc->dma_40bit = B_TRUE;
2565
2566 reg32 = pci_config_get32(pci_conf_handle,
2567 NV_SATA_CFG_20);
2568 pci_config_put32(pci_conf_handle, NV_SATA_CFG_20,
2569 reg32 | NV_40BIT_PRD);
2570
2571 /*
2572 * CFG_23 bits 0-7 contain the top 8 bits (of 40
2573 * bits) for the primary PRD table, and bits 8-15
2574 * contain the top 8 bits for the secondary. Set
2575 * to zero because the DMA attribute table for PRD
2576 * allocation forces it into 32 bit address space
2577 * anyway.
2578 */
2579 reg32 = pci_config_get32(pci_conf_handle,
2580 NV_SATA_CFG_23);
2581 pci_config_put32(pci_conf_handle, NV_SATA_CFG_23,
2582 reg32 & 0xffff0000);
2583 } else {
2584 NVLOG(NVDBG_INIT, nvp->nvp_ctlp, nvp,
2585 "40-bit DMA disabled by nv_sata_40bit_dma", NULL);
2586 }
2587 } else {
2588 nv_cmn_err(CE_NOTE, nvp->nvp_ctlp, nvp, "devid is %X revid is"
2589 " %X. Not capable of 40-bit DMA addressing",
2590 nvc->nvc_devid, nvc->nvc_revid);
2591 }
2592 }
2593
2594
2595 /*
2596 * Initialize register handling specific to ck804
2597 */
2598 static void
2599 ck804_reg_init(nv_ctl_t *nvc, ddi_acc_handle_t pci_conf_handle)
2600 {
2601 uchar_t *bar5 = nvc->nvc_bar_addr[5];
2602 uint32_t reg32;
2603 uint16_t reg16;
2604 nv_port_t *nvp;
2605 int j;
2606
2607 /*
2608 * delay hotplug interrupts until PHYRDY.
2609 */
2610 reg32 = pci_config_get32(pci_conf_handle, NV_SATA_CFG_42);
2632 */
2633 for (j = 0; j < NV_MAX_PORTS(nvc); j++) {
2634 nvp = &(nvc->nvc_port[j]);
2635 mutex_enter(&nvp->nvp_mutex);
2636 (*(nvp->nvp_ctlp->nvc_set_intr))(nvp,
2637 NV_INTR_CLEAR_ALL|NV_INTR_ENABLE);
2638 mutex_exit(&nvp->nvp_mutex);
2639 }
2640 }
2641
2642
2643 /*
2644 * Initialize the controller and set up driver data structures.
2645 * determine if ck804 or mcp5x class.
2646 */
2647 static int
2648 nv_init_ctl(nv_ctl_t *nvc, ddi_acc_handle_t pci_conf_handle)
2649 {
2650 struct sata_hba_tran stran;
2651 nv_port_t *nvp;
2652 int j;
2653 uchar_t *cmd_addr, *ctl_addr, *bm_addr;
2654 ddi_acc_handle_t bar5_hdl = nvc->nvc_bar_hdl[5];
2655 uchar_t *bar5 = nvc->nvc_bar_addr[5];
2656 uint32_t reg32;
2657 uint8_t reg8, reg8_save;
2658
2659 NVLOG(NVDBG_INIT, nvc, NULL, "nv_init_ctl entered", NULL);
2660
2661 nvc->nvc_mcp5x_flag = B_FALSE;
2662
2663 /*
2664 * Need to set bit 2 to 1 at config offset 0x50
2665 * to enable access to the bar5 registers.
2666 */
2667 reg32 = pci_config_get32(pci_conf_handle, NV_SATA_CFG_20);
2668 if (!(reg32 & NV_BAR5_SPACE_EN)) {
2669 pci_config_put32(pci_conf_handle, NV_SATA_CFG_20,
2670 reg32 | NV_BAR5_SPACE_EN);
2671 }
2672
2673 /*
2674 * Determine if this is ck804 or mcp5x. ck804 will map in the
2675 * task file registers into bar5 while mcp5x won't. The offset of
2676 * the task file registers in mcp5x's space is unused, so it will
2677 * return zero. So check one of the task file registers to see if it is
2678 * writable and reads back what was written. If it's mcp5x it will
2679 * return back 0xff whereas ck804 will return the value written.
2680 */
2681 reg8_save = nv_get8(bar5_hdl,
2682 (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X));
2683
2684
2685 for (j = 1; j < 3; j++) {
2686
2687 nv_put8(bar5_hdl, (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X), j);
2688 reg8 = nv_get8(bar5_hdl,
2689 (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X));
2690
2691 if (reg8 != j) {
2692 nvc->nvc_mcp5x_flag = B_TRUE;
2693 break;
2694 }
2695 }
2696
2697 nv_put8(bar5_hdl, (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X), reg8_save);
2698
2699 if (nvc->nvc_mcp5x_flag == B_FALSE) {
2700 NVLOG(NVDBG_INIT, nvc, NULL, "controller is CK804/MCP04",
2701 NULL);
2702 nvc->nvc_interrupt = ck804_intr;
2703 nvc->nvc_reg_init = ck804_reg_init;
2704 nvc->nvc_set_intr = ck804_set_intr;
2705 } else {
2706 NVLOG(NVDBG_INIT, nvc, NULL, "controller is MCP51/MCP55/MCP61",
2707 NULL);
2708 nvc->nvc_interrupt = mcp5x_intr;
2709 nvc->nvc_reg_init = mcp5x_reg_init;
2710 nvc->nvc_set_intr = mcp5x_set_intr;
2711 }
2712
2713
2714 stran.sata_tran_hba_rev = SATA_TRAN_HBA_REV;
2715 stran.sata_tran_hba_dip = nvc->nvc_dip;
2716 stran.sata_tran_hba_num_cports = NV_NUM_PORTS;
2717 stran.sata_tran_hba_features_support =
2718 SATA_CTLF_HOTPLUG | SATA_CTLF_ASN | SATA_CTLF_ATAPI;
2719 stran.sata_tran_hba_qdepth = NV_QUEUE_SLOTS;
2720 stran.sata_tran_probe_port = nv_sata_probe;
2721 stran.sata_tran_start = nv_sata_start;
2722 stran.sata_tran_abort = nv_sata_abort;
2723 stran.sata_tran_reset_dport = nv_sata_reset;
2724 stran.sata_tran_selftest = NULL;
2725 stran.sata_tran_hotplug_ops = &nv_hotplug_ops;
2726 stran.sata_tran_pwrmgt_ops = NULL;
2727 stran.sata_tran_ioctl = NULL;
|