Print this page
MFV: illumos-gate@fd6d41c5025e9fb45a115fc82d86e9983d1e9fd6
9815 Want basic AHCI enclosure services
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Rob Johnston <rob.johnston@joyent.com>
Reviewed by: Yuri Pankov <yuripv@yuripv.net>
Approved by: Dan McDonald <danmcd@joyent.com>
Author: Robert Mustacchi <rm@joyent.com>
Conflicts:
        usr/src/cmd/Makefile
9772 Panic in ahci when the failed slot spkt is NULL
Reviewed by: Andy Stormont <astormont@racktopsystems.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Robert Mustacchi <rm@joyent.com>
NEX-17502 Slow crash dumps, significantly slower than live core
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
re #12164 Marvell 88SE9128: Appliance hard hangs on boot probing duplicated ahci device


   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) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.


  25  */
  26 
  27 /*
  28  * AHCI (Advanced Host Controller Interface) SATA HBA Driver
  29  *
  30  * Power Management Support
  31  * ------------------------
  32  *
  33  * At the moment, the ahci driver only implements suspend/resume to
  34  * support Suspend to RAM on X86 feature. Device power management isn't
  35  * implemented, link power management is disabled, and hot plug isn't
  36  * allowed during the period from suspend to resume.
  37  *
  38  * For s/r support, the ahci driver only need to implement DDI_SUSPEND
  39  * and DDI_RESUME entries, and don't need to take care of new requests
  40  * sent down after suspend because the target driver (sd) has already
  41  * handled these conditions, and blocked these requests. For the detailed
  42  * information, please check with sdopen, sdclose and sdioctl routines.
  43  *




































  44  */
  45 
  46 #include <sys/note.h>
  47 #include <sys/scsi/scsi.h>
  48 #include <sys/pci.h>
  49 #include <sys/disp.h>
  50 #include <sys/sata/sata_hba.h>
  51 #include <sys/sata/adapters/ahci/ahcireg.h>
  52 #include <sys/sata/adapters/ahci/ahcivar.h>
  53 
  54 /*
  55  * FMA header files
  56  */
  57 #include <sys/ddifm.h>
  58 #include <sys/fm/protocol.h>
  59 #include <sys/fm/util.h>
  60 #include <sys/fm/io/ddi.h>
  61 
  62 /*











  63  * This is the string displayed by modinfo, etc.
  64  */
  65 static char ahci_ident[] = "ahci driver";
  66 
  67 /*
  68  * Function prototypes for driver entry points
  69  */
  70 static  int ahci_attach(dev_info_t *, ddi_attach_cmd_t);
  71 static  int ahci_detach(dev_info_t *, ddi_detach_cmd_t);
  72 static  int ahci_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
  73 static  int ahci_quiesce(dev_info_t *);
  74 
  75 /*
  76  * Function prototypes for SATA Framework interfaces
  77  */
  78 static  int ahci_register_sata_hba_tran(ahci_ctl_t *, uint32_t);
  79 static  int ahci_unregister_sata_hba_tran(ahci_ctl_t *);
  80 
  81 static  int ahci_tran_probe_port(dev_info_t *, sata_device_t *);
  82 static  int ahci_tran_start(dev_info_t *, sata_pkt_t *spkt);


 204 static  int ahci_intr_pmult_sntf_events(ahci_ctl_t *, ahci_port_t *, uint8_t);
 205 static  int ahci_intr_port_connect_change(ahci_ctl_t *, ahci_port_t *, uint8_t);
 206 static  int ahci_intr_device_mechanical_presence_status(ahci_ctl_t *,
 207     ahci_port_t *, uint8_t);
 208 static  int ahci_intr_phyrdy_change(ahci_ctl_t *, ahci_port_t *, uint8_t);
 209 static  int ahci_intr_non_fatal_error(ahci_ctl_t *, ahci_port_t *,
 210     uint8_t, uint32_t);
 211 static  int ahci_intr_fatal_error(ahci_ctl_t *, ahci_port_t *,
 212     uint8_t, uint32_t);
 213 static  int ahci_intr_cold_port_detect(ahci_ctl_t *, ahci_port_t *, uint8_t);
 214 
 215 static  void ahci_get_ahci_addr(ahci_ctl_t *, sata_device_t *, ahci_addr_t *);
 216 static  int ahci_get_num_implemented_ports(uint32_t);
 217 static  void ahci_log_fatal_error_message(ahci_ctl_t *, uint8_t, uint32_t);
 218 static  void ahci_dump_commands(ahci_ctl_t *, uint8_t, uint32_t);
 219 static  void ahci_log_serror_message(ahci_ctl_t *, uint8_t, uint32_t, int);
 220 #if AHCI_DEBUG
 221 static  void ahci_log(ahci_ctl_t *, uint_t, char *, ...);
 222 #endif
 223 





 224 

 225 /*
 226  * DMA attributes for the data buffer
 227  *
 228  * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
 229  * does not support 64-bit addressing
 230  */
 231 static ddi_dma_attr_t buffer_dma_attr = {
 232         DMA_ATTR_V0,            /* dma_attr_version */
 233         0x0ull,                 /* dma_attr_addr_lo: lowest bus address */
 234         0xffffffffffffffffull,  /* dma_attr_addr_hi: highest bus address */
 235         0x3fffffull,            /* dma_attr_count_max i.e. for one cookie */
 236         0x2ull,                 /* dma_attr_align: word aligned */
 237         1,                      /* dma_attr_burstsizes */
 238         1,                      /* dma_attr_minxfer */
 239         0xffffffffull,          /* dma_attr_maxxfer i.e. includes all cookies */
 240         0xffffffffull,          /* dma_attr_seg */
 241         AHCI_PRDT_NUMBER,       /* dma_attr_sgllen */
 242         512,                    /* dma_attr_granular */
 243         0,                      /* dma_attr_flags */
 244 };


 298         0xffffffffull,          /* dma_attr_count_max i.e. for one cookie */
 299         0x80ull,                /* dma_attr_align: 128-byte aligned */
 300         1,                      /* dma_attr_burstsizes */
 301         1,                      /* dma_attr_minxfer */
 302         0xffffffffull,          /* dma_attr_maxxfer i.e. includes all cookies */
 303         0xffffffffull,          /* dma_attr_seg */
 304         1,                      /* dma_attr_sgllen */
 305         1,                      /* dma_attr_granular */
 306         0,                      /* dma_attr_flags */
 307 };
 308 
 309 
 310 /* Device access attributes */
 311 static ddi_device_acc_attr_t accattr = {
 312         DDI_DEVICE_ATTR_V1,
 313         DDI_STRUCTURE_LE_ACC,
 314         DDI_STRICTORDER_ACC,
 315         DDI_DEFAULT_ACC
 316 };
 317 
 318 
 319 static struct dev_ops ahcictl_dev_ops = {
 320         DEVO_REV,               /* devo_rev */
 321         0,                      /* refcnt  */
 322         ahci_getinfo,           /* info */
 323         nulldev,                /* identify */
 324         nulldev,                /* probe */
 325         ahci_attach,            /* attach */
 326         ahci_detach,            /* detach */
 327         nodev,                  /* no reset */
 328         (struct cb_ops *)0,     /* driver operations */
 329         NULL,                   /* bus operations */
 330         NULL,                   /* power */
 331         ahci_quiesce,           /* quiesce */
 332 };
 333 
 334 static sata_tran_hotplug_ops_t ahci_tran_hotplug_ops = {
 335         SATA_TRAN_HOTPLUG_OPS_REV_1,
 336         ahci_tran_hotplug_port_activate,
 337         ahci_tran_hotplug_port_deactivate
 338 };
 339 
 340 extern struct mod_ops mod_driverops;
 341 
 342 static  struct modldrv modldrv = {
 343         &mod_driverops,             /* driverops */
 344         ahci_ident,             /* short description */
 345         &ahcictl_dev_ops,   /* driver ops */
 346 };
 347 
 348 static  struct modlinkage modlinkage = {


 393  *      PxCLBU (upper 32-bits for the command list base physical address)
 394  *      PxFBU (upper 32-bits for the received FIS base physical address)
 395  *      CTBAU (upper 32-bits of command table base)
 396  */
 397 boolean_t ahci_commu_64bit_dma = B_TRUE;
 398 
 399 /*
 400  * By default, 64-bit dma for data buffer will be disabled for AMD/ATI SB600
 401  * chipset. If the users want to have a try with 64-bit dma, please change
 402  * the below variable value to enable it.
 403  */
 404 boolean_t sb600_buf_64bit_dma_disable = B_TRUE;
 405 
 406 /*
 407  * By default, 64-bit dma for command buffer will be disabled for AMD/ATI
 408  * SB600/700/710/750/800. If the users want to have a try with 64-bit dma,
 409  * please change the below value to enable it.
 410  */
 411 boolean_t sbxxx_commu_64bit_dma_disable = B_TRUE;
 412 








 413 

 414 /*
 415  * End of global tunable variable definition
 416  */
 417 
 418 #if AHCI_DEBUG
 419 uint32_t ahci_debug_flags = 0;
 420 #else
 421 uint32_t ahci_debug_flags = (AHCIDBG_ERRS|AHCIDBG_TIMEOUT);
 422 #endif
 423 
 424 
 425 #if AHCI_DEBUG
 426 /* The following is needed for ahci_log() */
 427 static kmutex_t ahci_log_mutex;
 428 static char ahci_log_buf[512];
 429 #endif
 430 
 431 /* Opaque state pointer initialized by ddi_soft_state_init() */
 432 static void *ahci_statep = NULL;
 433 


 563                         ahci_ctlp->ahcictl_timeout_id = timeout(
 564                             (void (*)(void *))ahci_watchdog_handler,
 565                             (caddr_t)ahci_ctlp, ahci_watchdog_tick);
 566 
 567                 mutex_exit(&ahci_ctlp->ahcictl_mutex);
 568 
 569                 /*
 570                  * Re-initialize the controller and enable the interrupts and
 571                  * restart all the ports.
 572                  *
 573                  * Note that so far we don't support hot-plug during
 574                  * suspend/resume.
 575                  */
 576                 if (ahci_initialize_controller(ahci_ctlp) != AHCI_SUCCESS) {
 577                         AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PM, ahci_ctlp,
 578                             "Failed to initialize the controller "
 579                             "during DDI_RESUME", NULL);
 580                         return (DDI_FAILURE);
 581                 }
 582 





 583                 mutex_enter(&ahci_ctlp->ahcictl_mutex);
 584                 ahci_ctlp->ahcictl_flags &= ~AHCI_SUSPEND;
 585                 mutex_exit(&ahci_ctlp->ahcictl_mutex);
 586 
 587                 return (DDI_SUCCESS);
 588 
 589         default:
 590                 return (DDI_FAILURE);
 591         }
 592 
 593         attach_state = AHCI_ATTACH_STATE_NONE;
 594 
 595         /* Allocate soft state */
 596         status = ddi_soft_state_zalloc(ahci_statep, instance);
 597         if (status != DDI_SUCCESS) {
 598                 cmn_err(CE_WARN, "!ahci%d: Cannot allocate soft state",
 599                     instance);
 600                 goto err_out;
 601         }
 602 


 697 
 698         /* Get the HBA capabilities information */
 699         cap_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
 700             (uint32_t *)AHCI_GLOBAL_CAP(ahci_ctlp));
 701 
 702         AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba capabilities = 0x%x",
 703             cap_status);
 704 
 705         /* CAP2 (HBA Capabilities Extended) is available since AHCI spec 1.2 */
 706         if (ahci_version >= 0x00010200) {
 707                 uint32_t cap2_status;
 708 
 709                 /* Get the HBA capabilities extended information */
 710                 cap2_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
 711                     (uint32_t *)AHCI_GLOBAL_CAP2(ahci_ctlp));
 712 
 713                 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
 714                     "hba capabilities extended = 0x%x", cap2_status);
 715         }
 716 










 717 #if AHCI_DEBUG
 718         /* Get the interface speed supported by the HBA */
 719         speed = (cap_status & AHCI_HBA_CAP_ISS) >> AHCI_HBA_CAP_ISS_SHIFT;
 720         if (speed == 0x01) {
 721                 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
 722                     "hba interface speed support: Gen 1 (1.5Gbps)", NULL);
 723         } else if (speed == 0x10) {
 724                 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
 725                     "hba interface speed support: Gen 2 (3 Gbps)", NULL);
 726         } else if (speed == 0x11) {
 727                 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
 728                     "hba interface speed support: Gen 3 (6 Gbps)", NULL);
 729         }
 730 #endif
 731 
 732         /* Get the number of command slots supported by the HBA */
 733         ahci_ctlp->ahcictl_num_cmd_slots =
 734             ((cap_status & AHCI_HBA_CAP_NCS) >>
 735             AHCI_HBA_CAP_NCS_SHIFT) + 1;
 736 


 948 
 949         /*
 950          * Initialize the controller and ports.
 951          */
 952         status = ahci_initialize_controller(ahci_ctlp);
 953         if (status != AHCI_SUCCESS) {
 954                 cmn_err(CE_WARN, "!ahci%d: HBA initialization failed",
 955                     instance);
 956                 goto err_out;
 957         }
 958 
 959         attach_state |= AHCI_ATTACH_STATE_HW_INIT;
 960 
 961         /* Start one thread to check packet timeouts */
 962         ahci_ctlp->ahcictl_timeout_id = timeout(
 963             (void (*)(void *))ahci_watchdog_handler,
 964             (caddr_t)ahci_ctlp, ahci_watchdog_tick);
 965 
 966         attach_state |= AHCI_ATTACH_STATE_TIMEOUT_ENABLED;
 967 







 968         if (ahci_register_sata_hba_tran(ahci_ctlp, cap_status)) {
 969                 cmn_err(CE_WARN, "!ahci%d: sata hba tran registration failed",
 970                     instance);
 971                 goto err_out;
 972         }
 973 
 974         /* Check all handles at the end of the attach operation. */
 975         if (ahci_check_all_handle(ahci_ctlp) != DDI_SUCCESS) {
 976                 cmn_err(CE_WARN, "!ahci%d: invalid dma/acc handles",
 977                     instance);
 978                 goto err_out;
 979         }
 980 
 981         ahci_ctlp->ahcictl_flags &= ~AHCI_ATTACH;
 982 
 983         AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "ahci_attach success!", NULL);
 984 
 985         return (DDI_SUCCESS);
 986 
 987 err_out:
 988         /* FMA message */
 989         ahci_fm_ereport(ahci_ctlp, DDI_FM_DEVICE_NO_RESPONSE);
 990         ddi_fm_service_impact(ahci_ctlp->ahcictl_dip, DDI_SERVICE_LOST);
 991 




 992         if (attach_state & AHCI_ATTACH_STATE_TIMEOUT_ENABLED) {
 993                 mutex_enter(&ahci_ctlp->ahcictl_mutex);
 994                 (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
 995                 ahci_ctlp->ahcictl_timeout_id = 0;
 996                 mutex_exit(&ahci_ctlp->ahcictl_mutex);
 997         }
 998 
 999         if (attach_state & AHCI_ATTACH_STATE_HW_INIT) {
1000                 ahci_uninitialize_controller(ahci_ctlp);
1001         }
1002 
1003         if (attach_state & AHCI_ATTACH_STATE_PORT_ALLOC) {
1004                 ahci_dealloc_ports_state(ahci_ctlp);
1005         }
1006 
1007         if (attach_state & AHCI_ATTACH_STATE_MUTEX_INIT) {
1008                 mutex_destroy(&ahci_ctlp->ahcictl_mutex);
1009         }
1010 
1011         if (attach_state & AHCI_ATTACH_STATE_INTR_ADDED) {


1046 
1047         AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_detach enter", NULL);
1048 
1049         switch (cmd) {
1050         case DDI_DETACH:
1051 
1052                 /* disable the interrupts for an uninterrupted detach */
1053                 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1054                 ahci_disable_all_intrs(ahci_ctlp);
1055                 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1056 
1057                 /* unregister from the sata framework. */
1058                 ret = ahci_unregister_sata_hba_tran(ahci_ctlp);
1059                 if (ret != AHCI_SUCCESS) {
1060                         mutex_enter(&ahci_ctlp->ahcictl_mutex);
1061                         ahci_enable_all_intrs(ahci_ctlp);
1062                         mutex_exit(&ahci_ctlp->ahcictl_mutex);
1063                         return (DDI_FAILURE);
1064                 }
1065 


1066                 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1067 
1068                 /* stop the watchdog handler */
1069                 (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1070                 ahci_ctlp->ahcictl_timeout_id = 0;
1071 
1072                 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1073 
1074                 /* uninitialize the controller */
1075                 ahci_uninitialize_controller(ahci_ctlp);
1076 
1077                 /* remove the interrupts */
1078                 ahci_rem_intrs(ahci_ctlp);
1079 
1080                 /* deallocate the ports structures */
1081                 ahci_dealloc_ports_state(ahci_ctlp);
1082 
1083                 /* destroy mutex */
1084                 mutex_destroy(&ahci_ctlp->ahcictl_mutex);
1085 


1095                 /* free the soft state. */
1096                 ddi_soft_state_free(ahci_statep, instance);
1097 
1098                 return (DDI_SUCCESS);
1099 
1100         case DDI_SUSPEND:
1101 
1102                 /*
1103                  * The steps associated with suspension must include putting
1104                  * the underlying device into a quiescent state so that it
1105                  * will not generate interrupts or modify or access memory.
1106                  */
1107                 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1108                 if (ahci_ctlp->ahcictl_flags & AHCI_SUSPEND) {
1109                         mutex_exit(&ahci_ctlp->ahcictl_mutex);
1110                         return (DDI_SUCCESS);
1111                 }
1112 
1113                 ahci_ctlp->ahcictl_flags |= AHCI_SUSPEND;
1114 


1115                 /* stop the watchdog handler */
1116                 if (ahci_ctlp->ahcictl_timeout_id) {
1117                         (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1118                         ahci_ctlp->ahcictl_timeout_id = 0;
1119                 }
1120 
1121                 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1122 
1123                 /*
1124                  * drain the taskq
1125                  */
1126                 ahci_drain_ports_taskq(ahci_ctlp);
1127 
1128                 /*
1129                  * Disable the interrupts and stop all the ports.
1130                  */
1131                 ahci_uninitialize_controller(ahci_ctlp);
1132 
1133                 return (DDI_SUCCESS);
1134 


1245                             SATA_CTLF_PMULT_FBS;
1246                 }
1247         }
1248 
1249         /* Report the number of command slots */
1250         sata_hba_tran->sata_tran_hba_qdepth = ahci_ctlp->ahcictl_num_cmd_slots;
1251 
1252         sata_hba_tran->sata_tran_probe_port = ahci_tran_probe_port;
1253         sata_hba_tran->sata_tran_start = ahci_tran_start;
1254         sata_hba_tran->sata_tran_abort = ahci_tran_abort;
1255         sata_hba_tran->sata_tran_reset_dport = ahci_tran_reset_dport;
1256         sata_hba_tran->sata_tran_hotplug_ops = &ahci_tran_hotplug_ops;
1257 #ifdef __lock_lint
1258         sata_hba_tran->sata_tran_selftest = ahci_selftest;
1259 #endif
1260         /*
1261          * When SATA framework adds support for pwrmgt the
1262          * pwrmgt_ops needs to be updated
1263          */
1264         sata_hba_tran->sata_tran_pwrmgt_ops = NULL;
1265         sata_hba_tran->sata_tran_ioctl = NULL;
1266 
1267         ahci_ctlp->ahcictl_sata_hba_tran = sata_hba_tran;
1268 
1269         mutex_exit(&ahci_ctlp->ahcictl_mutex);
1270 
1271         /* Attach it to SATA framework */
1272         if (sata_hba_attach(ahci_ctlp->ahcictl_dip, sata_hba_tran, DDI_ATTACH)
1273             != DDI_SUCCESS) {
1274                 kmem_free((void *)sata_hba_tran, sizeof (sata_hba_tran_t));
1275                 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1276                 ahci_ctlp->ahcictl_sata_hba_tran = NULL;
1277                 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1278                 return (AHCI_FAILURE);
1279         }
1280 
1281         return (AHCI_SUCCESS);
1282 }
1283 
1284 /*
1285  * Unregisters the ahci with sata framework.


1798         int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
1799         uint8_t port = addrp->aa_port;
1800 
1801         ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
1802 
1803         AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_do_sync_start enter: "
1804             "port %d:%d spkt 0x%p", port, addrp->aa_pmport, spkt);
1805 
1806         if (spkt->satapkt_op_mode & SATA_OPMODE_POLLING) {
1807                 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_POLLING;
1808                 if ((rval = ahci_deliver_satapkt(ahci_ctlp, ahci_portp,
1809                     addrp, spkt)) == AHCI_FAILURE) {
1810                         ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_POLLING;
1811                         return (rval);
1812                 }
1813 
1814                 pkt_timeout_ticks =
1815                     drv_usectohz((clock_t)spkt->satapkt_time * 1000000);
1816 
1817                 while (spkt->satapkt_reason == SATA_PKT_BUSY) {
1818                         mutex_exit(&ahci_portp->ahciport_mutex);
1819 
1820                         /* Simulate the interrupt */

1821                         ahci_port_intr(ahci_ctlp, ahci_portp, port);

1822 
1823                         drv_usecwait(AHCI_10MS_USECS);

1824 


1825                         mutex_enter(&ahci_portp->ahciport_mutex);
1826                         pkt_timeout_ticks -= AHCI_10MS_TICKS;

1827                         if (pkt_timeout_ticks < 0) {
1828                                 cmn_err(CE_WARN, "!ahci%d: ahci_do_sync_start "
1829                                     "port %d satapkt 0x%p timed out\n",
1830                                     instance, port, (void *)spkt);
1831                                 timeout_tags = (0x1 << rval);
1832                                 mutex_exit(&ahci_portp->ahciport_mutex);
1833                                 ahci_timeout_pkts(ahci_ctlp, ahci_portp,
1834                                     port, timeout_tags);
1835                                 mutex_enter(&ahci_portp->ahciport_mutex);
1836                         }
1837                 }

1838                 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_POLLING;
1839                 return (AHCI_SUCCESS);
1840 
1841         } else {
1842                 if ((rval = ahci_deliver_satapkt(ahci_ctlp, ahci_portp,
1843                     addrp, spkt)) == AHCI_FAILURE)
1844                         return (rval);
1845 
1846 #if AHCI_DEBUG
1847                 /*
1848                  * Note that the driver always uses the slot 0 to deliver
1849                  * REQUEST SENSE or READ LOG EXT command
1850                  */
1851                 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
1852                         ASSERT(rval == 0);
1853 #endif
1854 
1855                 while (spkt->satapkt_reason == SATA_PKT_BUSY)
1856                         cv_wait(&ahci_portp->ahciport_cv,
1857                             &ahci_portp->ahciport_mutex);


9457 out:
9458         AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9459             "ahci_fatal_error_recovery_handler: port %d fatal error "
9460             "occurred slot_status = 0x%x, pending_tags = 0x%x, "
9461             "pending_ncq_tags = 0x%x failed_tags = 0x%x",
9462             port, slot_status, ahci_portp->ahciport_pending_tags,
9463             ahci_portp->ahciport_pending_ncq_tags, failed_tags);
9464 
9465         ahci_mop_commands(ahci_ctlp,
9466             ahci_portp,
9467             slot_status,
9468             failed_tags, /* failed tags */
9469             0, /* timeout tags */
9470             0, /* aborted tags */
9471             0); /* reset tags */
9472 }
9473 
9474 /*
9475  * Used to recovery a PMULT pmport fatal error under FIS-based switching.
9476  *      1. device specific.PxFBS.SDE=1
9477  *      2. Non-Deivce specific.
9478  * Nothing will be done when Command-based switching is employed.
9479  *
9480  * Currently code is neither completed nor tested.
9481  */
9482 static void
9483 ahci_pmult_error_recovery_handler(ahci_ctl_t *ahci_ctlp,
9484     ahci_port_t *ahci_portp, uint8_t port, uint32_t intr_status)
9485 {
9486 #ifndef __lock_lint
9487         _NOTE(ARGUNUSED(intr_status))
9488 #endif
9489         uint32_t        port_fbs_ctrl;
9490         int loop_count = 0;
9491         ahci_addr_t     addr;
9492 
9493         ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
9494 
9495         /* Nothing will be done under Command-based switching. */
9496         if (!(ahci_ctlp->ahcictl_cap & AHCI_CAP_PMULT_FBSS))
9497                 return;


9971 
9972 static void
9973 ahci_dump_commands(ahci_ctl_t *ahci_ctlp, uint8_t port,
9974     uint32_t slot_tags)
9975 {
9976         ahci_port_t *ahci_portp;
9977         int tmp_slot;
9978         sata_pkt_t *spkt;
9979         sata_cmd_t cmd;
9980 
9981         ahci_portp = ahci_ctlp->ahcictl_ports[port];
9982         ASSERT(ahci_portp != NULL);
9983 
9984         while (slot_tags) {
9985                 tmp_slot = ddi_ffs(slot_tags) - 1;
9986                 if (tmp_slot == -1) {
9987                         break;
9988                 }
9989 
9990                 spkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9991                 ASSERT(spkt != NULL);
9992                 cmd = spkt->satapkt_cmd;
9993 
9994                 cmn_err(CE_WARN, "!satapkt 0x%p: cmd_reg = 0x%x "
9995                     "features_reg = 0x%x sec_count_msb = 0x%x "
9996                     "lba_low_msb = 0x%x lba_mid_msb = 0x%x "
9997                     "lba_high_msb = 0x%x sec_count_lsb = 0x%x "
9998                     "lba_low_lsb = 0x%x lba_mid_lsb = 0x%x "
9999                     "lba_high_lsb = 0x%x device_reg = 0x%x "
10000                     "addr_type = 0x%x cmd_flags = 0x%x", (void *)spkt,
10001                     cmd.satacmd_cmd_reg, cmd.satacmd_features_reg,
10002                     cmd.satacmd_sec_count_msb, cmd.satacmd_lba_low_msb,
10003                     cmd.satacmd_lba_mid_msb, cmd.satacmd_lba_high_msb,
10004                     cmd.satacmd_sec_count_lsb, cmd.satacmd_lba_low_lsb,
10005                     cmd.satacmd_lba_mid_lsb, cmd.satacmd_lba_high_lsb,
10006                     cmd.satacmd_device_reg, cmd.satacmd_addr_type,
10007                     *((uint32_t *)&(cmd.satacmd_flags)));

10008 
10009                 CLEAR_BIT(slot_tags, tmp_slot);
10010         }
10011 }
10012 
10013 /*
10014  * Dump the serror message to the log.
10015  */
10016 static void
10017 ahci_log_serror_message(ahci_ctl_t *ahci_ctlp, uint8_t port,
10018     uint32_t port_serror, int debug_only)
10019 {
10020         static char err_buf[512];
10021         static char err_msg_header[16];
10022         char *err_msg = err_buf;
10023 
10024         *err_buf = '\0';
10025         *err_msg_header = '\0';
10026 
10027         if (port_serror & SERROR_DATA_ERR_FIXED) {


10187                 (void) sprintf(name, "ahci%d: ",
10188                     ddi_get_instance(ahci_ctlp->ahcictl_dip));
10189         } else {
10190                 (void) sprintf(name, "ahci: ");
10191         }
10192 
10193         (void) vsprintf(ahci_log_buf, fmt, ap);
10194         va_end(ap);
10195 
10196         cmn_err(level, "%s%s", name, ahci_log_buf);
10197 
10198         mutex_exit(&ahci_log_mutex);
10199 }
10200 #endif
10201 
10202 /*
10203  * quiesce(9E) entry point.
10204  *
10205  * This function is called when the system is single-threaded at high
10206  * PIL with preemption disabled. Therefore, this function must not be
10207  * blocked.



10208  *
10209  * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
10210  * DDI_FAILURE indicates an error condition and should almost never happen.
10211  */
10212 static int
10213 ahci_quiesce(dev_info_t *dip)
10214 {
10215         ahci_ctl_t *ahci_ctlp;
10216         ahci_port_t *ahci_portp;
10217         int instance, port;
10218 
10219         instance = ddi_get_instance(dip);
10220         ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
10221 
10222         if (ahci_ctlp == NULL)
10223                 return (DDI_FAILURE);
10224 
10225 #if AHCI_DEBUG
10226         ahci_debug_flags = 0;
10227 #endif


10304                 satapkt = ahci_portp->ahciport_doneq;
10305 
10306                 ahci_portp->ahciport_doneq = NULL;
10307                 ahci_portp->ahciport_doneqtail = &ahci_portp->ahciport_doneq;
10308                 ahci_portp->ahciport_doneq_len = 0;
10309 
10310                 mutex_exit(&ahci_portp->ahciport_mutex);
10311 
10312                 while (satapkt != NULL) {
10313                         next = satapkt->satapkt_hba_driver_private;
10314                         satapkt->satapkt_hba_driver_private = NULL;
10315 
10316                         /* Call the callback */
10317                         (*satapkt->satapkt_comp)(satapkt);
10318 
10319                         satapkt = next;
10320                 }
10321 
10322                 mutex_enter(&ahci_portp->ahciport_mutex);
10323         }














































































































































































































































































































































































































































































10324 }


   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) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  25  * Copyright (c) 2018, Joyent, Inc.
  26  * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  27  */
  28 
  29 /*
  30  * AHCI (Advanced Host Controller Interface) SATA HBA Driver
  31  *
  32  * Power Management Support
  33  * ------------------------
  34  *
  35  * At the moment, the ahci driver only implements suspend/resume to
  36  * support Suspend to RAM on X86 feature. Device power management isn't
  37  * implemented, link power management is disabled, and hot plug isn't
  38  * allowed during the period from suspend to resume.
  39  *
  40  * For s/r support, the ahci driver only need to implement DDI_SUSPEND
  41  * and DDI_RESUME entries, and don't need to take care of new requests
  42  * sent down after suspend because the target driver (sd) has already
  43  * handled these conditions, and blocked these requests. For the detailed
  44  * information, please check with sdopen, sdclose and sdioctl routines.
  45  *
  46  *
  47  * Enclosure Management Support
  48  * ----------------------------
  49  *
  50  * The ahci driver has basic support for AHCI Enclosure Management (EM)
  51  * services. The AHCI specification provides an area in the primary ahci BAR for
  52  * posting data to send out to the enclosure management and provides a register
  53  * that provides both information and control about this. While the
  54  * specification allows for multiple forms of enclosure management, the only
  55  * supported, and commonly found form, is the AHCI specified LED format. The LED
  56  * format is often implemented as a one-way communication mechanism. Software
  57  * can write out what it cares about into the aforementioned data buffer and
  58  * then we wait for the transmission to be sent.
  59  *
  60  * This has some drawbacks. It means that we cannot know whether or not it has
  61  * succeeded. This means we cannot ask hardware what it thinks the LEDs are
  62  * set to. There's also the added unfortunate reality that firmware on the
  63  * microcontroller driving this will often not show the LEDs if no drive is
  64  * present and that actions taken may potentially cause this to get out of sync
  65  * with what we expect it to be. For example, the specification does not
  66  * describe what should happen if a drive is removed from the enclosure while
  67  * this is set and what should happen when it returns. We can only infer that it
  68  * should be the same.
  69  *
  70  * Because only a single command can be sent at any time and we don't want to
  71  * interfere with controller I/O, we create a taskq dedicated to this that has a
  72  * single thread. Both resets (which occur on attach and resume) and normal
  73  * changes to the LED state will be driven through this taskq. Because the taskq
  74  * has a single thread, this guarantees serial processing.
  75  *
  76  * Each userland-submitted task (basically not resets) has a reference counted
  77  * task structure. This allows the thread that called it to be cancelled and
  78  * have the system clean itself up. The user thread in ioctl blocks on a CV that
  79  * can receive signals as it waits for completion.  Note, there is no guarantee
  80  * provided by the kernel that the first thread to enter the kernel will be the
  81  * first one to change state.
  82  */
  83 
  84 #include <sys/note.h>
  85 #include <sys/scsi/scsi.h>
  86 #include <sys/pci.h>
  87 #include <sys/disp.h>
  88 #include <sys/sata/sata_hba.h>
  89 #include <sys/sata/adapters/ahci/ahcireg.h>
  90 #include <sys/sata/adapters/ahci/ahcivar.h>
  91 
  92 /*
  93  * FMA header files
  94  */
  95 #include <sys/ddifm.h>
  96 #include <sys/fm/protocol.h>
  97 #include <sys/fm/util.h>
  98 #include <sys/fm/io/ddi.h>
  99 
 100 /*
 101  * EM Control header files
 102  */
 103 #include <sys/types.h>
 104 #include <sys/file.h>
 105 #include <sys/errno.h>
 106 #include <sys/open.h>
 107 #include <sys/cred.h>
 108 #include <sys/ddi.h>
 109 #include <sys/sunddi.h>
 110 
 111 /*
 112  * This is the string displayed by modinfo, etc.
 113  */
 114 static char ahci_ident[] = "ahci driver";
 115 
 116 /*
 117  * Function prototypes for driver entry points
 118  */
 119 static  int ahci_attach(dev_info_t *, ddi_attach_cmd_t);
 120 static  int ahci_detach(dev_info_t *, ddi_detach_cmd_t);
 121 static  int ahci_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
 122 static  int ahci_quiesce(dev_info_t *);
 123 
 124 /*
 125  * Function prototypes for SATA Framework interfaces
 126  */
 127 static  int ahci_register_sata_hba_tran(ahci_ctl_t *, uint32_t);
 128 static  int ahci_unregister_sata_hba_tran(ahci_ctl_t *);
 129 
 130 static  int ahci_tran_probe_port(dev_info_t *, sata_device_t *);
 131 static  int ahci_tran_start(dev_info_t *, sata_pkt_t *spkt);


 253 static  int ahci_intr_pmult_sntf_events(ahci_ctl_t *, ahci_port_t *, uint8_t);
 254 static  int ahci_intr_port_connect_change(ahci_ctl_t *, ahci_port_t *, uint8_t);
 255 static  int ahci_intr_device_mechanical_presence_status(ahci_ctl_t *,
 256     ahci_port_t *, uint8_t);
 257 static  int ahci_intr_phyrdy_change(ahci_ctl_t *, ahci_port_t *, uint8_t);
 258 static  int ahci_intr_non_fatal_error(ahci_ctl_t *, ahci_port_t *,
 259     uint8_t, uint32_t);
 260 static  int ahci_intr_fatal_error(ahci_ctl_t *, ahci_port_t *,
 261     uint8_t, uint32_t);
 262 static  int ahci_intr_cold_port_detect(ahci_ctl_t *, ahci_port_t *, uint8_t);
 263 
 264 static  void ahci_get_ahci_addr(ahci_ctl_t *, sata_device_t *, ahci_addr_t *);
 265 static  int ahci_get_num_implemented_ports(uint32_t);
 266 static  void ahci_log_fatal_error_message(ahci_ctl_t *, uint8_t, uint32_t);
 267 static  void ahci_dump_commands(ahci_ctl_t *, uint8_t, uint32_t);
 268 static  void ahci_log_serror_message(ahci_ctl_t *, uint8_t, uint32_t, int);
 269 #if AHCI_DEBUG
 270 static  void ahci_log(ahci_ctl_t *, uint_t, char *, ...);
 271 #endif
 272 
 273 static  boolean_t ahci_em_init(ahci_ctl_t *);
 274 static  void ahci_em_fini(ahci_ctl_t *);
 275 static  void ahci_em_suspend(ahci_ctl_t *);
 276 static  void ahci_em_resume(ahci_ctl_t *);
 277 static  int ahci_em_ioctl(dev_info_t *, int, intptr_t);
 278 
 279 
 280 /*
 281  * DMA attributes for the data buffer
 282  *
 283  * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
 284  * does not support 64-bit addressing
 285  */
 286 static ddi_dma_attr_t buffer_dma_attr = {
 287         DMA_ATTR_V0,            /* dma_attr_version */
 288         0x0ull,                 /* dma_attr_addr_lo: lowest bus address */
 289         0xffffffffffffffffull,  /* dma_attr_addr_hi: highest bus address */
 290         0x3fffffull,            /* dma_attr_count_max i.e. for one cookie */
 291         0x2ull,                 /* dma_attr_align: word aligned */
 292         1,                      /* dma_attr_burstsizes */
 293         1,                      /* dma_attr_minxfer */
 294         0xffffffffull,          /* dma_attr_maxxfer i.e. includes all cookies */
 295         0xffffffffull,          /* dma_attr_seg */
 296         AHCI_PRDT_NUMBER,       /* dma_attr_sgllen */
 297         512,                    /* dma_attr_granular */
 298         0,                      /* dma_attr_flags */
 299 };


 353         0xffffffffull,          /* dma_attr_count_max i.e. for one cookie */
 354         0x80ull,                /* dma_attr_align: 128-byte aligned */
 355         1,                      /* dma_attr_burstsizes */
 356         1,                      /* dma_attr_minxfer */
 357         0xffffffffull,          /* dma_attr_maxxfer i.e. includes all cookies */
 358         0xffffffffull,          /* dma_attr_seg */
 359         1,                      /* dma_attr_sgllen */
 360         1,                      /* dma_attr_granular */
 361         0,                      /* dma_attr_flags */
 362 };
 363 
 364 
 365 /* Device access attributes */
 366 static ddi_device_acc_attr_t accattr = {
 367         DDI_DEVICE_ATTR_V1,
 368         DDI_STRUCTURE_LE_ACC,
 369         DDI_STRICTORDER_ACC,
 370         DDI_DEFAULT_ACC
 371 };
 372 

 373 static struct dev_ops ahcictl_dev_ops = {
 374         DEVO_REV,               /* devo_rev */
 375         0,                      /* refcnt  */
 376         ahci_getinfo,           /* info */
 377         nulldev,                /* identify */
 378         nulldev,                /* probe */
 379         ahci_attach,            /* attach */
 380         ahci_detach,            /* detach */
 381         nodev,                  /* no reset */
 382         NULL,                   /* driver operations */
 383         NULL,                   /* bus operations */
 384         NULL,                   /* power */
 385         ahci_quiesce,           /* quiesce */
 386 };
 387 
 388 static sata_tran_hotplug_ops_t ahci_tran_hotplug_ops = {
 389         SATA_TRAN_HOTPLUG_OPS_REV_1,
 390         ahci_tran_hotplug_port_activate,
 391         ahci_tran_hotplug_port_deactivate
 392 };
 393 
 394 extern struct mod_ops mod_driverops;
 395 
 396 static  struct modldrv modldrv = {
 397         &mod_driverops,             /* driverops */
 398         ahci_ident,             /* short description */
 399         &ahcictl_dev_ops,   /* driver ops */
 400 };
 401 
 402 static  struct modlinkage modlinkage = {


 447  *      PxCLBU (upper 32-bits for the command list base physical address)
 448  *      PxFBU (upper 32-bits for the received FIS base physical address)
 449  *      CTBAU (upper 32-bits of command table base)
 450  */
 451 boolean_t ahci_commu_64bit_dma = B_TRUE;
 452 
 453 /*
 454  * By default, 64-bit dma for data buffer will be disabled for AMD/ATI SB600
 455  * chipset. If the users want to have a try with 64-bit dma, please change
 456  * the below variable value to enable it.
 457  */
 458 boolean_t sb600_buf_64bit_dma_disable = B_TRUE;
 459 
 460 /*
 461  * By default, 64-bit dma for command buffer will be disabled for AMD/ATI
 462  * SB600/700/710/750/800. If the users want to have a try with 64-bit dma,
 463  * please change the below value to enable it.
 464  */
 465 boolean_t sbxxx_commu_64bit_dma_disable = B_TRUE;
 466 
 467 /*
 468  * These values control the default delay and default number of times to wait
 469  * for an enclosure message to complete.
 470  */
 471 uint_t  ahci_em_reset_delay_ms = 1;
 472 uint_t  ahci_em_reset_delay_count = 1000;
 473 uint_t  ahci_em_tx_delay_ms = 1;
 474 uint_t  ahci_em_tx_delay_count = 1000;
 475 
 476 
 477 /*
 478  * End of global tunable variable definition
 479  */
 480 
 481 #if AHCI_DEBUG
 482 uint32_t ahci_debug_flags = 0;
 483 #else
 484 uint32_t ahci_debug_flags = (AHCIDBG_ERRS|AHCIDBG_TIMEOUT);
 485 #endif
 486 
 487 
 488 #if AHCI_DEBUG
 489 /* The following is needed for ahci_log() */
 490 static kmutex_t ahci_log_mutex;
 491 static char ahci_log_buf[512];
 492 #endif
 493 
 494 /* Opaque state pointer initialized by ddi_soft_state_init() */
 495 static void *ahci_statep = NULL;
 496 


 626                         ahci_ctlp->ahcictl_timeout_id = timeout(
 627                             (void (*)(void *))ahci_watchdog_handler,
 628                             (caddr_t)ahci_ctlp, ahci_watchdog_tick);
 629 
 630                 mutex_exit(&ahci_ctlp->ahcictl_mutex);
 631 
 632                 /*
 633                  * Re-initialize the controller and enable the interrupts and
 634                  * restart all the ports.
 635                  *
 636                  * Note that so far we don't support hot-plug during
 637                  * suspend/resume.
 638                  */
 639                 if (ahci_initialize_controller(ahci_ctlp) != AHCI_SUCCESS) {
 640                         AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PM, ahci_ctlp,
 641                             "Failed to initialize the controller "
 642                             "during DDI_RESUME", NULL);
 643                         return (DDI_FAILURE);
 644                 }
 645 
 646                 /*
 647                  * Reset the enclosure services.
 648                  */
 649                 ahci_em_resume(ahci_ctlp);
 650 
 651                 mutex_enter(&ahci_ctlp->ahcictl_mutex);
 652                 ahci_ctlp->ahcictl_flags &= ~AHCI_SUSPEND;
 653                 mutex_exit(&ahci_ctlp->ahcictl_mutex);
 654 
 655                 return (DDI_SUCCESS);
 656 
 657         default:
 658                 return (DDI_FAILURE);
 659         }
 660 
 661         attach_state = AHCI_ATTACH_STATE_NONE;
 662 
 663         /* Allocate soft state */
 664         status = ddi_soft_state_zalloc(ahci_statep, instance);
 665         if (status != DDI_SUCCESS) {
 666                 cmn_err(CE_WARN, "!ahci%d: Cannot allocate soft state",
 667                     instance);
 668                 goto err_out;
 669         }
 670 


 765 
 766         /* Get the HBA capabilities information */
 767         cap_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
 768             (uint32_t *)AHCI_GLOBAL_CAP(ahci_ctlp));
 769 
 770         AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba capabilities = 0x%x",
 771             cap_status);
 772 
 773         /* CAP2 (HBA Capabilities Extended) is available since AHCI spec 1.2 */
 774         if (ahci_version >= 0x00010200) {
 775                 uint32_t cap2_status;
 776 
 777                 /* Get the HBA capabilities extended information */
 778                 cap2_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
 779                     (uint32_t *)AHCI_GLOBAL_CAP2(ahci_ctlp));
 780 
 781                 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
 782                     "hba capabilities extended = 0x%x", cap2_status);
 783         }
 784 
 785         if (cap_status & AHCI_HBA_CAP_EMS) {
 786                 ahci_ctlp->ahcictl_cap |= AHCI_CAP_EMS;
 787                 ahci_ctlp->ahcictl_em_loc =
 788                     ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
 789                     (uint32_t *)AHCI_GLOBAL_EM_LOC(ahci_ctlp));
 790                 ahci_ctlp->ahcictl_em_ctl =
 791                     ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
 792                     (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp));
 793         }
 794 
 795 #if AHCI_DEBUG
 796         /* Get the interface speed supported by the HBA */
 797         speed = (cap_status & AHCI_HBA_CAP_ISS) >> AHCI_HBA_CAP_ISS_SHIFT;
 798         if (speed == 0x01) {
 799                 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
 800                     "hba interface speed support: Gen 1 (1.5Gbps)", NULL);
 801         } else if (speed == 0x10) {
 802                 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
 803                     "hba interface speed support: Gen 2 (3 Gbps)", NULL);
 804         } else if (speed == 0x11) {
 805                 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
 806                     "hba interface speed support: Gen 3 (6 Gbps)", NULL);
 807         }
 808 #endif
 809 
 810         /* Get the number of command slots supported by the HBA */
 811         ahci_ctlp->ahcictl_num_cmd_slots =
 812             ((cap_status & AHCI_HBA_CAP_NCS) >>
 813             AHCI_HBA_CAP_NCS_SHIFT) + 1;
 814 


1026 
1027         /*
1028          * Initialize the controller and ports.
1029          */
1030         status = ahci_initialize_controller(ahci_ctlp);
1031         if (status != AHCI_SUCCESS) {
1032                 cmn_err(CE_WARN, "!ahci%d: HBA initialization failed",
1033                     instance);
1034                 goto err_out;
1035         }
1036 
1037         attach_state |= AHCI_ATTACH_STATE_HW_INIT;
1038 
1039         /* Start one thread to check packet timeouts */
1040         ahci_ctlp->ahcictl_timeout_id = timeout(
1041             (void (*)(void *))ahci_watchdog_handler,
1042             (caddr_t)ahci_ctlp, ahci_watchdog_tick);
1043 
1044         attach_state |= AHCI_ATTACH_STATE_TIMEOUT_ENABLED;
1045 
1046         if (!ahci_em_init(ahci_ctlp)) {
1047                 cmn_err(CE_WARN, "!ahci%d: failed to initialize enclosure "
1048                     "services", instance);
1049                 goto err_out;
1050         }
1051         attach_state |= AHCI_ATTACH_STATE_ENCLOSURE;
1052 
1053         if (ahci_register_sata_hba_tran(ahci_ctlp, cap_status)) {
1054                 cmn_err(CE_WARN, "!ahci%d: sata hba tran registration failed",
1055                     instance);
1056                 goto err_out;
1057         }
1058 
1059         /* Check all handles at the end of the attach operation. */
1060         if (ahci_check_all_handle(ahci_ctlp) != DDI_SUCCESS) {
1061                 cmn_err(CE_WARN, "!ahci%d: invalid dma/acc handles",
1062                     instance);
1063                 goto err_out;
1064         }
1065 
1066         ahci_ctlp->ahcictl_flags &= ~AHCI_ATTACH;
1067 
1068         AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "ahci_attach success!", NULL);
1069 
1070         return (DDI_SUCCESS);
1071 
1072 err_out:
1073         /* FMA message */
1074         ahci_fm_ereport(ahci_ctlp, DDI_FM_DEVICE_NO_RESPONSE);
1075         ddi_fm_service_impact(ahci_ctlp->ahcictl_dip, DDI_SERVICE_LOST);
1076 
1077         if (attach_state & AHCI_ATTACH_STATE_ENCLOSURE) {
1078                 ahci_em_fini(ahci_ctlp);
1079         }
1080 
1081         if (attach_state & AHCI_ATTACH_STATE_TIMEOUT_ENABLED) {
1082                 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1083                 (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1084                 ahci_ctlp->ahcictl_timeout_id = 0;
1085                 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1086         }
1087 
1088         if (attach_state & AHCI_ATTACH_STATE_HW_INIT) {
1089                 ahci_uninitialize_controller(ahci_ctlp);
1090         }
1091 
1092         if (attach_state & AHCI_ATTACH_STATE_PORT_ALLOC) {
1093                 ahci_dealloc_ports_state(ahci_ctlp);
1094         }
1095 
1096         if (attach_state & AHCI_ATTACH_STATE_MUTEX_INIT) {
1097                 mutex_destroy(&ahci_ctlp->ahcictl_mutex);
1098         }
1099 
1100         if (attach_state & AHCI_ATTACH_STATE_INTR_ADDED) {


1135 
1136         AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_detach enter", NULL);
1137 
1138         switch (cmd) {
1139         case DDI_DETACH:
1140 
1141                 /* disable the interrupts for an uninterrupted detach */
1142                 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1143                 ahci_disable_all_intrs(ahci_ctlp);
1144                 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1145 
1146                 /* unregister from the sata framework. */
1147                 ret = ahci_unregister_sata_hba_tran(ahci_ctlp);
1148                 if (ret != AHCI_SUCCESS) {
1149                         mutex_enter(&ahci_ctlp->ahcictl_mutex);
1150                         ahci_enable_all_intrs(ahci_ctlp);
1151                         mutex_exit(&ahci_ctlp->ahcictl_mutex);
1152                         return (DDI_FAILURE);
1153                 }
1154 
1155                 ahci_em_fini(ahci_ctlp);
1156 
1157                 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1158 
1159                 /* stop the watchdog handler */
1160                 (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1161                 ahci_ctlp->ahcictl_timeout_id = 0;
1162 
1163                 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1164 
1165                 /* uninitialize the controller */
1166                 ahci_uninitialize_controller(ahci_ctlp);
1167 
1168                 /* remove the interrupts */
1169                 ahci_rem_intrs(ahci_ctlp);
1170 
1171                 /* deallocate the ports structures */
1172                 ahci_dealloc_ports_state(ahci_ctlp);
1173 
1174                 /* destroy mutex */
1175                 mutex_destroy(&ahci_ctlp->ahcictl_mutex);
1176 


1186                 /* free the soft state. */
1187                 ddi_soft_state_free(ahci_statep, instance);
1188 
1189                 return (DDI_SUCCESS);
1190 
1191         case DDI_SUSPEND:
1192 
1193                 /*
1194                  * The steps associated with suspension must include putting
1195                  * the underlying device into a quiescent state so that it
1196                  * will not generate interrupts or modify or access memory.
1197                  */
1198                 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1199                 if (ahci_ctlp->ahcictl_flags & AHCI_SUSPEND) {
1200                         mutex_exit(&ahci_ctlp->ahcictl_mutex);
1201                         return (DDI_SUCCESS);
1202                 }
1203 
1204                 ahci_ctlp->ahcictl_flags |= AHCI_SUSPEND;
1205 
1206                 ahci_em_suspend(ahci_ctlp);
1207 
1208                 /* stop the watchdog handler */
1209                 if (ahci_ctlp->ahcictl_timeout_id) {
1210                         (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1211                         ahci_ctlp->ahcictl_timeout_id = 0;
1212                 }
1213 
1214                 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1215 
1216                 /*
1217                  * drain the taskq
1218                  */
1219                 ahci_drain_ports_taskq(ahci_ctlp);
1220 
1221                 /*
1222                  * Disable the interrupts and stop all the ports.
1223                  */
1224                 ahci_uninitialize_controller(ahci_ctlp);
1225 
1226                 return (DDI_SUCCESS);
1227 


1338                             SATA_CTLF_PMULT_FBS;
1339                 }
1340         }
1341 
1342         /* Report the number of command slots */
1343         sata_hba_tran->sata_tran_hba_qdepth = ahci_ctlp->ahcictl_num_cmd_slots;
1344 
1345         sata_hba_tran->sata_tran_probe_port = ahci_tran_probe_port;
1346         sata_hba_tran->sata_tran_start = ahci_tran_start;
1347         sata_hba_tran->sata_tran_abort = ahci_tran_abort;
1348         sata_hba_tran->sata_tran_reset_dport = ahci_tran_reset_dport;
1349         sata_hba_tran->sata_tran_hotplug_ops = &ahci_tran_hotplug_ops;
1350 #ifdef __lock_lint
1351         sata_hba_tran->sata_tran_selftest = ahci_selftest;
1352 #endif
1353         /*
1354          * When SATA framework adds support for pwrmgt the
1355          * pwrmgt_ops needs to be updated
1356          */
1357         sata_hba_tran->sata_tran_pwrmgt_ops = NULL;
1358         sata_hba_tran->sata_tran_ioctl = ahci_em_ioctl;
1359 
1360         ahci_ctlp->ahcictl_sata_hba_tran = sata_hba_tran;
1361 
1362         mutex_exit(&ahci_ctlp->ahcictl_mutex);
1363 
1364         /* Attach it to SATA framework */
1365         if (sata_hba_attach(ahci_ctlp->ahcictl_dip, sata_hba_tran, DDI_ATTACH)
1366             != DDI_SUCCESS) {
1367                 kmem_free((void *)sata_hba_tran, sizeof (sata_hba_tran_t));
1368                 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1369                 ahci_ctlp->ahcictl_sata_hba_tran = NULL;
1370                 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1371                 return (AHCI_FAILURE);
1372         }
1373 
1374         return (AHCI_SUCCESS);
1375 }
1376 
1377 /*
1378  * Unregisters the ahci with sata framework.


1891         int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
1892         uint8_t port = addrp->aa_port;
1893 
1894         ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
1895 
1896         AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_do_sync_start enter: "
1897             "port %d:%d spkt 0x%p", port, addrp->aa_pmport, spkt);
1898 
1899         if (spkt->satapkt_op_mode & SATA_OPMODE_POLLING) {
1900                 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_POLLING;
1901                 if ((rval = ahci_deliver_satapkt(ahci_ctlp, ahci_portp,
1902                     addrp, spkt)) == AHCI_FAILURE) {
1903                         ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_POLLING;
1904                         return (rval);
1905                 }
1906 
1907                 pkt_timeout_ticks =
1908                     drv_usectohz((clock_t)spkt->satapkt_time * 1000000);
1909 
1910                 while (spkt->satapkt_reason == SATA_PKT_BUSY) {


1911                         /* Simulate the interrupt */
1912                         mutex_exit(&ahci_portp->ahciport_mutex);
1913                         ahci_port_intr(ahci_ctlp, ahci_portp, port);
1914                         mutex_enter(&ahci_portp->ahciport_mutex);
1915 
1916                         if (spkt->satapkt_reason != SATA_PKT_BUSY)
1917                                 break;
1918 
1919                         mutex_exit(&ahci_portp->ahciport_mutex);
1920                         drv_usecwait(AHCI_1MS_USECS);
1921                         mutex_enter(&ahci_portp->ahciport_mutex);
1922 
1923                         pkt_timeout_ticks -= AHCI_1MS_TICKS;
1924                         if (pkt_timeout_ticks < 0) {
1925                                 cmn_err(CE_WARN, "!ahci%d: ahci_do_sync_start "
1926                                     "port %d satapkt 0x%p timed out\n",
1927                                     instance, port, (void *)spkt);
1928                                 timeout_tags = (0x1 << rval);
1929                                 mutex_exit(&ahci_portp->ahciport_mutex);
1930                                 ahci_timeout_pkts(ahci_ctlp, ahci_portp,
1931                                     port, timeout_tags);
1932                                 mutex_enter(&ahci_portp->ahciport_mutex);
1933                         }
1934                 }
1935 
1936                 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_POLLING;
1937                 return (AHCI_SUCCESS);
1938 
1939         } else {
1940                 if ((rval = ahci_deliver_satapkt(ahci_ctlp, ahci_portp,
1941                     addrp, spkt)) == AHCI_FAILURE)
1942                         return (rval);
1943 
1944 #if AHCI_DEBUG
1945                 /*
1946                  * Note that the driver always uses the slot 0 to deliver
1947                  * REQUEST SENSE or READ LOG EXT command
1948                  */
1949                 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
1950                         ASSERT(rval == 0);
1951 #endif
1952 
1953                 while (spkt->satapkt_reason == SATA_PKT_BUSY)
1954                         cv_wait(&ahci_portp->ahciport_cv,
1955                             &ahci_portp->ahciport_mutex);


9555 out:
9556         AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9557             "ahci_fatal_error_recovery_handler: port %d fatal error "
9558             "occurred slot_status = 0x%x, pending_tags = 0x%x, "
9559             "pending_ncq_tags = 0x%x failed_tags = 0x%x",
9560             port, slot_status, ahci_portp->ahciport_pending_tags,
9561             ahci_portp->ahciport_pending_ncq_tags, failed_tags);
9562 
9563         ahci_mop_commands(ahci_ctlp,
9564             ahci_portp,
9565             slot_status,
9566             failed_tags, /* failed tags */
9567             0, /* timeout tags */
9568             0, /* aborted tags */
9569             0); /* reset tags */
9570 }
9571 
9572 /*
9573  * Used to recovery a PMULT pmport fatal error under FIS-based switching.
9574  *      1. device specific.PxFBS.SDE=1
9575  *      2. Non Device specific.
9576  * Nothing will be done when Command-based switching is employed.
9577  *
9578  * Currently code is neither completed nor tested.
9579  */
9580 static void
9581 ahci_pmult_error_recovery_handler(ahci_ctl_t *ahci_ctlp,
9582     ahci_port_t *ahci_portp, uint8_t port, uint32_t intr_status)
9583 {
9584 #ifndef __lock_lint
9585         _NOTE(ARGUNUSED(intr_status))
9586 #endif
9587         uint32_t        port_fbs_ctrl;
9588         int loop_count = 0;
9589         ahci_addr_t     addr;
9590 
9591         ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
9592 
9593         /* Nothing will be done under Command-based switching. */
9594         if (!(ahci_ctlp->ahcictl_cap & AHCI_CAP_PMULT_FBSS))
9595                 return;


10069 
10070 static void
10071 ahci_dump_commands(ahci_ctl_t *ahci_ctlp, uint8_t port,
10072     uint32_t slot_tags)
10073 {
10074         ahci_port_t *ahci_portp;
10075         int tmp_slot;
10076         sata_pkt_t *spkt;
10077         sata_cmd_t cmd;
10078 
10079         ahci_portp = ahci_ctlp->ahcictl_ports[port];
10080         ASSERT(ahci_portp != NULL);
10081 
10082         while (slot_tags) {
10083                 tmp_slot = ddi_ffs(slot_tags) - 1;
10084                 if (tmp_slot == -1) {
10085                         break;
10086                 }
10087 
10088                 spkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
10089                 if (spkt != NULL) {
10090                         cmd = spkt->satapkt_cmd;
10091 
10092                         cmn_err(CE_WARN, "!satapkt 0x%p: cmd_reg = 0x%x "
10093                             "features_reg = 0x%x sec_count_msb = 0x%x "
10094                             "lba_low_msb = 0x%x lba_mid_msb = 0x%x "
10095                             "lba_high_msb = 0x%x sec_count_lsb = 0x%x "
10096                             "lba_low_lsb = 0x%x lba_mid_lsb = 0x%x "
10097                             "lba_high_lsb = 0x%x device_reg = 0x%x "
10098                             "addr_type = 0x%x cmd_flags = 0x%x", (void *)spkt,
10099                             cmd.satacmd_cmd_reg, cmd.satacmd_features_reg,
10100                             cmd.satacmd_sec_count_msb, cmd.satacmd_lba_low_msb,
10101                             cmd.satacmd_lba_mid_msb, cmd.satacmd_lba_high_msb,
10102                             cmd.satacmd_sec_count_lsb, cmd.satacmd_lba_low_lsb,
10103                             cmd.satacmd_lba_mid_lsb, cmd.satacmd_lba_high_lsb,
10104                             cmd.satacmd_device_reg, cmd.satacmd_addr_type,
10105                             *((uint32_t *)&(cmd.satacmd_flags)));
10106                 }
10107 
10108                 CLEAR_BIT(slot_tags, tmp_slot);
10109         }
10110 }
10111 
10112 /*
10113  * Dump the serror message to the log.
10114  */
10115 static void
10116 ahci_log_serror_message(ahci_ctl_t *ahci_ctlp, uint8_t port,
10117     uint32_t port_serror, int debug_only)
10118 {
10119         static char err_buf[512];
10120         static char err_msg_header[16];
10121         char *err_msg = err_buf;
10122 
10123         *err_buf = '\0';
10124         *err_msg_header = '\0';
10125 
10126         if (port_serror & SERROR_DATA_ERR_FIXED) {


10286                 (void) sprintf(name, "ahci%d: ",
10287                     ddi_get_instance(ahci_ctlp->ahcictl_dip));
10288         } else {
10289                 (void) sprintf(name, "ahci: ");
10290         }
10291 
10292         (void) vsprintf(ahci_log_buf, fmt, ap);
10293         va_end(ap);
10294 
10295         cmn_err(level, "%s%s", name, ahci_log_buf);
10296 
10297         mutex_exit(&ahci_log_mutex);
10298 }
10299 #endif
10300 
10301 /*
10302  * quiesce(9E) entry point.
10303  *
10304  * This function is called when the system is single-threaded at high
10305  * PIL with preemption disabled. Therefore, this function must not be
10306  * blocked. Because no taskqs are running, there is no need for us to
10307  * take any action for enclosure services which are running in the
10308  * taskq context, especially as no interrupts are generated by it nor
10309  * are any messages expected to come in.
10310  *
10311  * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
10312  * DDI_FAILURE indicates an error condition and should almost never happen.
10313  */
10314 static int
10315 ahci_quiesce(dev_info_t *dip)
10316 {
10317         ahci_ctl_t *ahci_ctlp;
10318         ahci_port_t *ahci_portp;
10319         int instance, port;
10320 
10321         instance = ddi_get_instance(dip);
10322         ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
10323 
10324         if (ahci_ctlp == NULL)
10325                 return (DDI_FAILURE);
10326 
10327 #if AHCI_DEBUG
10328         ahci_debug_flags = 0;
10329 #endif


10406                 satapkt = ahci_portp->ahciport_doneq;
10407 
10408                 ahci_portp->ahciport_doneq = NULL;
10409                 ahci_portp->ahciport_doneqtail = &ahci_portp->ahciport_doneq;
10410                 ahci_portp->ahciport_doneq_len = 0;
10411 
10412                 mutex_exit(&ahci_portp->ahciport_mutex);
10413 
10414                 while (satapkt != NULL) {
10415                         next = satapkt->satapkt_hba_driver_private;
10416                         satapkt->satapkt_hba_driver_private = NULL;
10417 
10418                         /* Call the callback */
10419                         (*satapkt->satapkt_comp)(satapkt);
10420 
10421                         satapkt = next;
10422                 }
10423 
10424                 mutex_enter(&ahci_portp->ahciport_mutex);
10425         }
10426 }
10427 
10428 /*
10429  * Sets the state for the specified port on the controller to desired state.
10430  * This must be run in the context of the enclosure taskq which ensures that
10431  * only one event is outstanding at any time.
10432  */
10433 static boolean_t
10434 ahci_em_set_led(ahci_ctl_t *ahci_ctlp, uint8_t port, ahci_em_led_state_t desire)
10435 {
10436         ahci_em_led_msg_t msg;
10437         ahci_em_msg_hdr_t hdr;
10438         uint32_t msgval, hdrval;
10439         uint_t i, max_delay = ahci_em_tx_delay_count;
10440 
10441         msg.alm_hba = port;
10442         msg.alm_pminfo = 0;
10443         msg.alm_value = 0;
10444 
10445         if (desire & AHCI_EM_LED_IDENT_ENABLE) {
10446                 msg.alm_value |= AHCI_LED_ON << AHCI_LED_IDENT_OFF;
10447         }
10448 
10449         if (desire & AHCI_EM_LED_FAULT_ENABLE) {
10450                 msg.alm_value |= AHCI_LED_ON << AHCI_LED_FAULT_OFF;
10451         }
10452 
10453         if ((ahci_ctlp->ahcictl_em_ctl & AHCI_HBA_EM_CTL_ATTR_ALHD) == 0 &&
10454             (desire & AHCI_EM_LED_ACTIVITY_DISABLE) == 0) {
10455                 msg.alm_value |= AHCI_LED_ON << AHCI_LED_ACTIVITY_OFF;
10456         }
10457 
10458         hdr.aemh_rsvd = 0;
10459         hdr.aemh_mlen = sizeof (ahci_em_led_msg_t);
10460         hdr.aemh_dlen = 0;
10461         hdr.aemh_mtype = AHCI_EM_MSG_TYPE_LED;
10462 
10463         bcopy(&msg, &msgval, sizeof (msgval));
10464         bcopy(&hdr, &hdrval, sizeof (hdrval));
10465 
10466         /*
10467          * First, make sure we can transmit. We should not have been placed in a
10468          * situation where an outstanding transmission is going on.
10469          */
10470         for (i = 0; i < max_delay; i++) {
10471                 uint32_t val;
10472 
10473                 val = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
10474                     (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp));
10475                 if ((val & AHCI_HBA_EM_CTL_CTL_TM) == 0)
10476                         break;
10477 
10478                 delay(drv_usectohz(ahci_em_tx_delay_ms * 1000));
10479         }
10480 
10481         if (i == max_delay)
10482                 return (B_FALSE);
10483 
10484         ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
10485             (uint32_t *)ahci_ctlp->ahcictl_em_tx_off, hdrval);
10486         ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
10487             (uint32_t *)(ahci_ctlp->ahcictl_em_tx_off + 4), msgval);
10488         ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
10489             (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp), AHCI_HBA_EM_CTL_CTL_TM);
10490 
10491         for (i = 0; i < max_delay; i++) {
10492                 uint32_t val;
10493 
10494                 val = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
10495                     (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp));
10496                 if ((val & AHCI_HBA_EM_CTL_CTL_TM) == 0)
10497                         break;
10498 
10499                 delay(drv_usectohz(ahci_em_tx_delay_ms * 1000));
10500         }
10501 
10502         if (i == max_delay)
10503                 return (B_FALSE);
10504 
10505         return (B_TRUE);
10506 }
10507 
10508 typedef struct ahci_em_led_task_arg {
10509         ahci_ctl_t              *aelta_ctl;
10510         uint8_t                 aelta_port;
10511         uint_t                  aelta_op;
10512         ahci_em_led_state_t     aelta_state;
10513         uint_t                  aelta_ret;
10514         kcondvar_t              aelta_cv;
10515         uint_t                  aelta_ref;
10516 } ahci_em_led_task_arg_t;
10517 
10518 static void
10519 ahci_em_led_task_free(ahci_em_led_task_arg_t *task)
10520 {
10521         ASSERT3U(task->aelta_ref, ==, 0);
10522         cv_destroy(&task->aelta_cv);
10523         kmem_free(task, sizeof (*task));
10524 }
10525 
10526 static void
10527 ahci_em_led_task(void *arg)
10528 {
10529         boolean_t ret, cleanup = B_FALSE;
10530         ahci_em_led_task_arg_t *led = arg;
10531         ahci_em_led_state_t state;
10532 
10533         mutex_enter(&led->aelta_ctl->ahcictl_mutex);
10534         if (led->aelta_ctl->ahcictl_em_flags != AHCI_EM_USABLE) {
10535                 led->aelta_ret = EIO;
10536                 mutex_exit(&led->aelta_ctl->ahcictl_mutex);
10537                 return;
10538         }
10539 
10540         state = led->aelta_ctl->ahcictl_em_state[led->aelta_port];
10541         mutex_exit(&led->aelta_ctl->ahcictl_mutex);
10542 
10543         switch (led->aelta_op) {
10544         case AHCI_EM_IOC_SET_OP_ADD:
10545                 state |= led->aelta_state;
10546                 break;
10547         case AHCI_EM_IOC_SET_OP_REM:
10548                 state &= ~led->aelta_state;
10549                 break;
10550         case AHCI_EM_IOC_SET_OP_SET:
10551                 state = led->aelta_state;
10552                 break;
10553         default:
10554                 led->aelta_ret = ENOTSUP;
10555                 return;
10556         }
10557 
10558         ret = ahci_em_set_led(led->aelta_ctl, led->aelta_port, state);
10559 
10560         mutex_enter(&led->aelta_ctl->ahcictl_mutex);
10561         if (ret) {
10562                 led->aelta_ctl->ahcictl_em_state[led->aelta_port] =
10563                     led->aelta_state;
10564                 led->aelta_ret = 0;
10565         } else {
10566                 led->aelta_ret = EIO;
10567                 led->aelta_ctl->ahcictl_em_flags |= AHCI_EM_TIMEOUT;
10568         }
10569         led->aelta_ref--;
10570         if (led->aelta_ref > 0) {
10571                 cv_signal(&led->aelta_cv);
10572         } else {
10573                 cleanup = B_TRUE;
10574         }
10575         mutex_exit(&led->aelta_ctl->ahcictl_mutex);
10576 
10577         if (cleanup) {
10578                 ahci_em_led_task_free(led);
10579         }
10580 }
10581 
10582 static void
10583 ahci_em_reset(void *arg)
10584 {
10585         uint_t i, max_delay = ahci_em_reset_delay_count;
10586         ahci_ctl_t *ahci_ctlp = arg;
10587 
10588         /*
10589          * We've been asked to reset the device. The caller should have set the
10590          * resetting flag. Make sure that we don't have a request to quiesce.
10591          */
10592         mutex_enter(&ahci_ctlp->ahcictl_mutex);
10593         ASSERT(ahci_ctlp->ahcictl_em_flags & AHCI_EM_RESETTING);
10594         if (ahci_ctlp->ahcictl_em_flags & AHCI_EM_QUIESCE) {
10595                 ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_RESETTING;
10596                 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10597                 return;
10598         }
10599         mutex_exit(&ahci_ctlp->ahcictl_mutex);
10600 
10601         ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
10602             (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp), AHCI_HBA_EM_CTL_CTL_RST);
10603         for (i = 0; i < max_delay; i++) {
10604                 uint32_t val;
10605 
10606                 val = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
10607                     (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp));
10608                 if ((val & AHCI_HBA_EM_CTL_CTL_RST) == 0)
10609                         break;
10610 
10611                 delay(drv_usectohz(ahci_em_reset_delay_ms * 1000));
10612         }
10613 
10614         if (i == max_delay) {
10615                 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10616                 ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_RESETTING;
10617                 ahci_ctlp->ahcictl_em_flags |= AHCI_EM_TIMEOUT;
10618                 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10619                 cmn_err(CE_WARN, "!ahci%d: enclosure timed out resetting",
10620                     ddi_get_instance(ahci_ctlp->ahcictl_dip));
10621                 return;
10622         }
10623 
10624         for (i = 0; i < ahci_ctlp->ahcictl_num_ports; i++) {
10625 
10626                 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, i))
10627                         continue;
10628 
10629                 /*
10630                  * Try to flush all the LEDs as part of reset. If it fails,
10631                  * drive on.
10632                  */
10633                 if (!ahci_em_set_led(ahci_ctlp, i,
10634                     ahci_ctlp->ahcictl_em_state[i])) {
10635                         mutex_enter(&ahci_ctlp->ahcictl_mutex);
10636                         ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_RESETTING;
10637                         ahci_ctlp->ahcictl_em_flags |= AHCI_EM_TIMEOUT;
10638                         mutex_exit(&ahci_ctlp->ahcictl_mutex);
10639                         cmn_err(CE_WARN, "!ahci%d: enclosure timed out "
10640                             "setting port %u",
10641                             ddi_get_instance(ahci_ctlp->ahcictl_dip), i);
10642                         return;
10643                 }
10644         }
10645 
10646         mutex_enter(&ahci_ctlp->ahcictl_mutex);
10647         ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_RESETTING;
10648         ahci_ctlp->ahcictl_em_flags |= AHCI_EM_READY;
10649         mutex_exit(&ahci_ctlp->ahcictl_mutex);
10650 }
10651 
10652 static boolean_t
10653 ahci_em_init(ahci_ctl_t *ahci_ctlp)
10654 {
10655         char name[128];
10656 
10657         /*
10658          * First make sure we actually have enclosure services and if so, that
10659          * we have the hardware support that we care about for this.
10660          */
10661         if (ahci_ctlp->ahcictl_em_loc == 0 ||
10662             (ahci_ctlp->ahcictl_em_ctl & AHCI_HBA_EM_CTL_SUPP_LED) == 0)
10663                 return (B_TRUE);
10664 
10665         /*
10666          * Next, make sure that the buffer is large enough for us. We need two
10667          * dwords or 8 bytes. The location register is stored in dwords.
10668          */
10669         if ((ahci_ctlp->ahcictl_em_loc & AHCI_HBA_EM_LOC_SZ_MASK) <
10670             AHCI_EM_BUFFER_MIN) {
10671                 return (B_TRUE);
10672         }
10673 
10674         ahci_ctlp->ahcictl_em_flags |= AHCI_EM_PRESENT;
10675 
10676         ahci_ctlp->ahcictl_em_tx_off = ((ahci_ctlp->ahcictl_em_loc &
10677             AHCI_HBA_EM_LOC_OFST_MASK) >> AHCI_HBA_EM_LOC_OFST_SHIFT) * 4;
10678         ahci_ctlp->ahcictl_em_tx_off += ahci_ctlp->ahcictl_ahci_addr;
10679 
10680         bzero(ahci_ctlp->ahcictl_em_state,
10681             sizeof (ahci_ctlp->ahcictl_em_state));
10682 
10683         (void) snprintf(name, sizeof (name), "ahcti_em_taskq%d",
10684             ddi_get_instance(ahci_ctlp->ahcictl_dip));
10685         if ((ahci_ctlp->ahcictl_em_taskq =
10686             ddi_taskq_create(ahci_ctlp->ahcictl_dip, name, 1,
10687             TASKQ_DEFAULTPRI, 0)) == NULL) {
10688                 cmn_err(CE_WARN, "!ahci%d: ddi_tasq_create failed for em "
10689                     "services", ddi_get_instance(ahci_ctlp->ahcictl_dip));
10690                 return (B_FALSE);
10691         }
10692 
10693         mutex_enter(&ahci_ctlp->ahcictl_mutex);
10694         ahci_ctlp->ahcictl_em_flags |= AHCI_EM_RESETTING;
10695         mutex_exit(&ahci_ctlp->ahcictl_mutex);
10696         (void) ddi_taskq_dispatch(ahci_ctlp->ahcictl_em_taskq, ahci_em_reset,
10697             ahci_ctlp, DDI_SLEEP);
10698 
10699         return (B_TRUE);
10700 }
10701 
10702 static int
10703 ahci_em_ioctl_get(ahci_ctl_t *ahci_ctlp, intptr_t arg)
10704 {
10705         int i;
10706         ahci_ioc_em_get_t get;
10707 
10708         bzero(&get, sizeof (get));
10709         get.aiemg_nports = ahci_ctlp->ahcictl_ports_implemented;
10710         if ((ahci_ctlp->ahcictl_em_ctl & AHCI_HBA_EM_CTL_ATTR_ALHD) == 0) {
10711                 get.aiemg_flags |= AHCI_EM_FLAG_CONTROL_ACTIVITY;
10712         }
10713 
10714         mutex_enter(&ahci_ctlp->ahcictl_mutex);
10715         for (i = 0; i < ahci_ctlp->ahcictl_num_ports; i++) {
10716                 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, i)) {
10717                         continue;
10718                 }
10719                 get.aiemg_status[i] = ahci_ctlp->ahcictl_em_state[i];
10720         }
10721         mutex_exit(&ahci_ctlp->ahcictl_mutex);
10722 
10723         if (ddi_copyout(&get, (void *)arg, sizeof (get), 0) != 0)
10724                 return (EFAULT);
10725 
10726         return (0);
10727 }
10728 
10729 static int
10730 ahci_em_ioctl_set(ahci_ctl_t *ahci_ctlp, intptr_t arg)
10731 {
10732         int ret;
10733         ahci_ioc_em_set_t set;
10734         ahci_em_led_task_arg_t *task;
10735         boolean_t signal, cleanup;
10736 
10737         if (ddi_copyin((void *)arg, &set, sizeof (set), 0) != 0)
10738                 return (EFAULT);
10739 
10740         if (set.aiems_port > ahci_ctlp->ahcictl_num_ports)
10741                 return (EINVAL);
10742 
10743         if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, set.aiems_port)) {
10744                 return (EINVAL);
10745         }
10746 
10747         if ((set.aiems_leds & ~(AHCI_EM_LED_IDENT_ENABLE |
10748             AHCI_EM_LED_FAULT_ENABLE |
10749             AHCI_EM_LED_ACTIVITY_DISABLE)) != 0) {
10750                 return (EINVAL);
10751         }
10752 
10753         switch (set.aiems_op) {
10754         case AHCI_EM_IOC_SET_OP_ADD:
10755         case AHCI_EM_IOC_SET_OP_REM:
10756         case AHCI_EM_IOC_SET_OP_SET:
10757                 break;
10758         default:
10759                 return (EINVAL);
10760         }
10761 
10762         if ((set.aiems_leds & AHCI_EM_LED_ACTIVITY_DISABLE) != 0 &&
10763             ((ahci_ctlp->ahcictl_em_ctl & AHCI_HBA_EM_CTL_ATTR_ALHD) != 0)) {
10764                 return (ENOTSUP);
10765         }
10766 
10767         task = kmem_alloc(sizeof (*task), KM_NOSLEEP | KM_NORMALPRI);
10768         if (task == NULL) {
10769                 return (ENOMEM);
10770         }
10771 
10772         task->aelta_ctl = ahci_ctlp;
10773         task->aelta_port = (uint8_t)set.aiems_port;
10774         task->aelta_op = set.aiems_op;
10775         task->aelta_state = set.aiems_leds;
10776 
10777         cv_init(&task->aelta_cv, NULL, CV_DRIVER, NULL);
10778 
10779         /*
10780          * Initialize the reference count to two. One for us and one for the
10781          * taskq. This will be used in case we get canceled.
10782          */
10783         task->aelta_ref = 2;
10784 
10785         /*
10786          * Once dispatched, the task state is protected by our global mutex.
10787          */
10788         (void) ddi_taskq_dispatch(ahci_ctlp->ahcictl_em_taskq,
10789             ahci_em_led_task, task, DDI_SLEEP);
10790 
10791         signal = B_FALSE;
10792         mutex_enter(&ahci_ctlp->ahcictl_mutex);
10793         while (task->aelta_ref > 1) {
10794                 if (cv_wait_sig(&task->aelta_cv, &ahci_ctlp->ahcictl_mutex) ==
10795                     0) {
10796                         signal = B_TRUE;
10797                         break;
10798                 }
10799         }
10800 
10801         /*
10802          * Remove our reference count. If we were woken up because of a signal
10803          * then the taskq may still be dispatched. In which case we shouldn't
10804          * free this memory until it is done. In that case, the taskq will take
10805          * care of it.
10806          */
10807         task->aelta_ref--;
10808         cleanup = (task->aelta_ref == 0);
10809         if (signal) {
10810                 ret = EINTR;
10811         } else {
10812                 ret = task->aelta_ret;
10813         }
10814         mutex_exit(&ahci_ctlp->ahcictl_mutex);
10815 
10816         if (cleanup) {
10817                 ahci_em_led_task_free(task);
10818         }
10819 
10820         return (ret);
10821 }
10822 
10823 static int
10824 ahci_em_ioctl(dev_info_t *dip, int cmd, intptr_t arg)
10825 {
10826         int inst;
10827         ahci_ctl_t *ahci_ctlp;
10828 
10829         inst = ddi_get_instance(dip);
10830         if ((ahci_ctlp = ddi_get_soft_state(ahci_statep, inst)) == NULL) {
10831                 return (ENXIO);
10832         }
10833 
10834         switch (cmd) {
10835         case AHCI_EM_IOC_GET:
10836                 return (ahci_em_ioctl_get(ahci_ctlp, arg));
10837         case AHCI_EM_IOC_SET:
10838                 return (ahci_em_ioctl_set(ahci_ctlp, arg));
10839         default:
10840                 return (ENOTTY);
10841         }
10842 
10843 }
10844 
10845 static void
10846 ahci_em_quiesce(ahci_ctl_t *ahci_ctlp)
10847 {
10848         ASSERT(ahci_ctlp->ahcictl_em_flags & AHCI_EM_PRESENT);
10849 
10850         mutex_enter(&ahci_ctlp->ahcictl_mutex);
10851         ahci_ctlp->ahcictl_em_flags |= AHCI_EM_QUIESCE;
10852         mutex_exit(&ahci_ctlp->ahcictl_mutex);
10853 
10854         ddi_taskq_wait(ahci_ctlp->ahcictl_em_taskq);
10855 }
10856 
10857 static void
10858 ahci_em_suspend(ahci_ctl_t *ahci_ctlp)
10859 {
10860         ahci_em_quiesce(ahci_ctlp);
10861 
10862         mutex_enter(&ahci_ctlp->ahcictl_mutex);
10863         ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_READY;
10864         mutex_exit(&ahci_ctlp->ahcictl_mutex);
10865 }
10866 
10867 static void
10868 ahci_em_resume(ahci_ctl_t *ahci_ctlp)
10869 {
10870         mutex_enter(&ahci_ctlp->ahcictl_mutex);
10871         ahci_ctlp->ahcictl_em_flags |= AHCI_EM_RESETTING;
10872         mutex_exit(&ahci_ctlp->ahcictl_mutex);
10873 
10874         (void) ddi_taskq_dispatch(ahci_ctlp->ahcictl_em_taskq, ahci_em_reset,
10875             ahci_ctlp, DDI_SLEEP);
10876 }
10877 
10878 static void
10879 ahci_em_fini(ahci_ctl_t *ahci_ctlp)
10880 {
10881         if ((ahci_ctlp->ahcictl_em_flags & AHCI_EM_PRESENT) == 0) {
10882                 return;
10883         }
10884 
10885         ahci_em_quiesce(ahci_ctlp);
10886         ddi_taskq_destroy(ahci_ctlp->ahcictl_em_taskq);
10887         ahci_ctlp->ahcictl_em_taskq = NULL;
10888 }