Print this page
    
5513 KM_NORMALPRI should be documented in kmem_alloc(9f) and kmem_cache_create(9f) man pages
14465 Present KM_NOSLEEP_LAZY as documented interface
Change-Id: I002ec28ddf390650f1fcba1ca94f6abfdb241439
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/io/sata/adapters/ahci/ahci.c
          +++ new/usr/src/uts/common/io/sata/adapters/ahci/ahci.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  25   25   * Copyright (c) 2018, Joyent, Inc.
  26   26   * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  27   27   */
  28   28  
  29   29  /*
  30   30   * AHCI (Advanced Host Controller Interface) SATA HBA Driver
  31   31   *
  32   32   * Power Management Support
  33   33   * ------------------------
  34   34   *
  35   35   * At the moment, the ahci driver only implements suspend/resume to
  36   36   * support Suspend to RAM on X86 feature. Device power management isn't
  37   37   * implemented, link power management is disabled, and hot plug isn't
  38   38   * allowed during the period from suspend to resume.
  39   39   *
  40   40   * For s/r support, the ahci driver only need to implement DDI_SUSPEND
  41   41   * and DDI_RESUME entries, and don't need to take care of new requests
  42   42   * sent down after suspend because the target driver (sd) has already
  43   43   * handled these conditions, and blocked these requests. For the detailed
  44   44   * information, please check with sdopen, sdclose and sdioctl routines.
  45   45   *
  46   46   *
  47   47   * Enclosure Management Support
  48   48   * ----------------------------
  49   49   *
  50   50   * The ahci driver has basic support for AHCI Enclosure Management (EM)
  51   51   * services. The AHCI specification provides an area in the primary ahci BAR for
  52   52   * posting data to send out to the enclosure management and provides a register
  53   53   * that provides both information and control about this. While the
  54   54   * specification allows for multiple forms of enclosure management, the only
  55   55   * supported, and commonly found form, is the AHCI specified LED format. The LED
  56   56   * format is often implemented as a one-way communication mechanism. Software
  57   57   * can write out what it cares about into the aforementioned data buffer and
  58   58   * then we wait for the transmission to be sent.
  59   59   *
  60   60   * This has some drawbacks. It means that we cannot know whether or not it has
  61   61   * succeeded. This means we cannot ask hardware what it thinks the LEDs are
  62   62   * set to. There's also the added unfortunate reality that firmware on the
  63   63   * microcontroller driving this will often not show the LEDs if no drive is
  64   64   * present and that actions taken may potentially cause this to get out of sync
  65   65   * with what we expect it to be. For example, the specification does not
  66   66   * describe what should happen if a drive is removed from the enclosure while
  67   67   * this is set and what should happen when it returns. We can only infer that it
  68   68   * should be the same.
  69   69   *
  70   70   * Because only a single command can be sent at any time and we don't want to
  71   71   * interfere with controller I/O, we create a taskq dedicated to this that has a
  72   72   * single thread. Both resets (which occur on attach and resume) and normal
  73   73   * changes to the LED state will be driven through this taskq. Because the taskq
  74   74   * has a single thread, this guarantees serial processing.
  75   75   *
  76   76   * Each userland-submitted task (basically not resets) has a reference counted
  77   77   * task structure. This allows the thread that called it to be cancelled and
  78   78   * have the system clean itself up. The user thread in ioctl blocks on a CV that
  79   79   * can receive signals as it waits for completion.  Note, there is no guarantee
  80   80   * provided by the kernel that the first thread to enter the kernel will be the
  81   81   * first one to change state.
  82   82   */
  83   83  
  84   84  #include <sys/note.h>
  85   85  #include <sys/scsi/scsi.h>
  86   86  #include <sys/pci.h>
  87   87  #include <sys/disp.h>
  88   88  #include <sys/sata/sata_hba.h>
  89   89  #include <sys/sata/adapters/ahci/ahcireg.h>
  90   90  #include <sys/sata/adapters/ahci/ahcivar.h>
  91   91  
  92   92  /*
  93   93   * FMA header files
  94   94   */
  95   95  #include <sys/ddifm.h>
  96   96  #include <sys/fm/protocol.h>
  97   97  #include <sys/fm/util.h>
  98   98  #include <sys/fm/io/ddi.h>
  99   99  
 100  100  /*
 101  101   * EM Control header files
 102  102   */
 103  103  #include <sys/types.h>
 104  104  #include <sys/file.h>
 105  105  #include <sys/errno.h>
 106  106  #include <sys/open.h>
 107  107  #include <sys/cred.h>
 108  108  #include <sys/ddi.h>
 109  109  #include <sys/sunddi.h>
 110  110  
 111  111  /*
 112  112   * This is the string displayed by modinfo, etc.
 113  113   */
 114  114  static char ahci_ident[] = "ahci driver";
 115  115  
 116  116  /*
 117  117   * Function prototypes for driver entry points
 118  118   */
 119  119  static  int ahci_attach(dev_info_t *, ddi_attach_cmd_t);
 120  120  static  int ahci_detach(dev_info_t *, ddi_detach_cmd_t);
 121  121  static  int ahci_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
 122  122  static  int ahci_quiesce(dev_info_t *);
 123  123  
 124  124  /*
 125  125   * Function prototypes for SATA Framework interfaces
 126  126   */
 127  127  static  int ahci_register_sata_hba_tran(ahci_ctl_t *, uint32_t);
 128  128  static  int ahci_unregister_sata_hba_tran(ahci_ctl_t *);
 129  129  
 130  130  static  int ahci_tran_probe_port(dev_info_t *, sata_device_t *);
 131  131  static  int ahci_tran_start(dev_info_t *, sata_pkt_t *spkt);
 132  132  static  int ahci_tran_abort(dev_info_t *, sata_pkt_t *, int);
 133  133  static  int ahci_tran_reset_dport(dev_info_t *, sata_device_t *);
 134  134  static  int ahci_tran_hotplug_port_activate(dev_info_t *, sata_device_t *);
 135  135  static  int ahci_tran_hotplug_port_deactivate(dev_info_t *, sata_device_t *);
 136  136  #if defined(__lock_lint)
 137  137  static  int ahci_selftest(dev_info_t *, sata_device_t *);
 138  138  #endif
 139  139  
 140  140  /*
 141  141   * FMA Prototypes
 142  142   */
 143  143  static  void ahci_fm_init(ahci_ctl_t *);
 144  144  static  void ahci_fm_fini(ahci_ctl_t *);
 145  145  static  int ahci_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void*);
 146  146  int     ahci_check_acc_handle(ddi_acc_handle_t);
 147  147  int     ahci_check_dma_handle(ddi_dma_handle_t);
 148  148  void    ahci_fm_ereport(ahci_ctl_t *, char *);
 149  149  static  int ahci_check_all_handle(ahci_ctl_t *);
 150  150  static  int ahci_check_ctl_handle(ahci_ctl_t *);
 151  151  static  int ahci_check_port_handle(ahci_ctl_t *, int);
 152  152  static  int ahci_check_slot_handle(ahci_port_t *, int);
 153  153  
 154  154  /*
 155  155   * Local function prototypes
 156  156   */
 157  157  static  int ahci_setup_port_base_addresses(ahci_ctl_t *, ahci_port_t *);
 158  158  static  int ahci_alloc_ports_state(ahci_ctl_t *);
 159  159  static  void ahci_dealloc_ports_state(ahci_ctl_t *);
 160  160  static  int ahci_alloc_port_state(ahci_ctl_t *, uint8_t);
 161  161  static  void ahci_dealloc_port_state(ahci_ctl_t *, uint8_t);
 162  162  static  int ahci_alloc_rcvd_fis(ahci_ctl_t *, ahci_port_t *);
 163  163  static  void ahci_dealloc_rcvd_fis(ahci_port_t *);
 164  164  static  int ahci_alloc_cmd_list(ahci_ctl_t *, ahci_port_t *);
 165  165  static  void ahci_dealloc_cmd_list(ahci_ctl_t *, ahci_port_t *);
 166  166  static  int ahci_alloc_cmd_tables(ahci_ctl_t *, ahci_port_t *);
 167  167  static  void ahci_dealloc_cmd_tables(ahci_ctl_t *, ahci_port_t *);
 168  168  static  void ahci_alloc_pmult(ahci_ctl_t *, ahci_port_t *);
 169  169  static  void ahci_dealloc_pmult(ahci_ctl_t *, ahci_port_t *);
 170  170  
 171  171  static  int ahci_initialize_controller(ahci_ctl_t *);
 172  172  static  void ahci_uninitialize_controller(ahci_ctl_t *);
 173  173  static  int ahci_initialize_port(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
 174  174  static  int ahci_config_space_init(ahci_ctl_t *);
 175  175  static  void ahci_staggered_spin_up(ahci_ctl_t *, uint8_t);
 176  176  
 177  177  static  void ahci_drain_ports_taskq(ahci_ctl_t *);
 178  178  static  int ahci_rdwr_pmult(ahci_ctl_t *, ahci_addr_t *, uint8_t, uint32_t *,
 179  179      uint8_t);
 180  180  static  int ahci_read_pmult(ahci_ctl_t *, ahci_addr_t *, uint8_t, uint32_t *);
 181  181  static  int ahci_write_pmult(ahci_ctl_t *, ahci_addr_t *, uint8_t, uint32_t);
 182  182  static  int ahci_update_pmult_pscr(ahci_ctl_t *, ahci_addr_t *,
 183  183      sata_device_t *);
 184  184  static  int ahci_update_pmult_gscr(ahci_ctl_t *, ahci_addr_t *,
 185  185      sata_pmult_gscr_t *);
 186  186  static  int ahci_initialize_pmult(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *,
 187  187      sata_device_t *);
 188  188  static  int ahci_initialize_pmport(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
 189  189  static  int ahci_probe_pmult(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
 190  190  static  int ahci_probe_pmport(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *,
 191  191      sata_device_t *);
 192  192  
 193  193  static  void ahci_disable_interface_pm(ahci_ctl_t *, uint8_t);
 194  194  static  int ahci_start_port(ahci_ctl_t *, ahci_port_t *, uint8_t);
 195  195  static  void ahci_find_dev_signature(ahci_ctl_t *, ahci_port_t *,
 196  196      ahci_addr_t *);
 197  197  static  void ahci_update_sata_registers(ahci_ctl_t *, uint8_t, sata_device_t *);
 198  198  static  int ahci_deliver_satapkt(ahci_ctl_t *, ahci_port_t *,
 199  199      ahci_addr_t *, sata_pkt_t *);
 200  200  static  int ahci_do_sync_start(ahci_ctl_t *, ahci_port_t *,
 201  201      ahci_addr_t *, sata_pkt_t *);
 202  202  static  int ahci_claim_free_slot(ahci_ctl_t *, ahci_port_t *,
 203  203      ahci_addr_t *, int);
 204  204  static  void ahci_copy_err_cnxt(sata_cmd_t *, ahci_fis_d2h_register_t *);
 205  205  static  void ahci_copy_ncq_err_page(sata_cmd_t *,
 206  206      struct sata_ncq_error_recovery_page *);
 207  207  static  void ahci_copy_out_regs(sata_cmd_t *, ahci_fis_d2h_register_t *);
 208  208  static  void ahci_add_doneq(ahci_port_t *, sata_pkt_t *, int);
 209  209  static  void ahci_flush_doneq(ahci_port_t *);
 210  210  
 211  211  static  int ahci_software_reset(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
 212  212  static  int ahci_hba_reset(ahci_ctl_t *);
 213  213  static  int ahci_port_reset(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
 214  214  static  int ahci_pmport_reset(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
 215  215  static  void ahci_reject_all_abort_pkts(ahci_ctl_t *, ahci_port_t *, uint8_t);
 216  216  static  int ahci_reset_device_reject_pkts(ahci_ctl_t *, ahci_port_t *,
 217  217      ahci_addr_t *);
 218  218  static  int ahci_reset_pmdevice_reject_pkts(ahci_ctl_t *, ahci_port_t *,
 219  219      ahci_addr_t *);
 220  220  static  int ahci_reset_port_reject_pkts(ahci_ctl_t *, ahci_port_t *,
 221  221      ahci_addr_t *);
 222  222  static  int ahci_reset_hba_reject_pkts(ahci_ctl_t *);
 223  223  static  int ahci_put_port_into_notrunning_state(ahci_ctl_t *, ahci_port_t *,
 224  224      uint8_t);
 225  225  static  int ahci_restart_port_wait_till_ready(ahci_ctl_t *, ahci_port_t *,
 226  226      uint8_t, int, int *);
 227  227  static  void ahci_mop_commands(ahci_ctl_t *, ahci_port_t *, uint32_t,
 228  228      uint32_t, uint32_t, uint32_t, uint32_t);
 229  229  static  uint32_t ahci_get_rdlogext_data(ahci_ctl_t *, ahci_port_t *, uint8_t);
 230  230  static void ahci_get_rqsense_data(ahci_ctl_t *, ahci_port_t *,
 231  231      uint8_t, sata_pkt_t *);
 232  232  static  void ahci_fatal_error_recovery_handler(ahci_ctl_t *, ahci_port_t *,
 233  233      ahci_addr_t *, uint32_t);
 234  234  static  void ahci_pmult_error_recovery_handler(ahci_ctl_t *, ahci_port_t *,
 235  235      uint8_t, uint32_t);
 236  236  static  void ahci_timeout_pkts(ahci_ctl_t *, ahci_port_t *,
 237  237      uint8_t, uint32_t);
 238  238  static  void ahci_events_handler(void *);
 239  239  static  void ahci_watchdog_handler(ahci_ctl_t *);
 240  240  
 241  241  static  uint_t ahci_intr(caddr_t, caddr_t);
 242  242  static  void ahci_port_intr(ahci_ctl_t *, ahci_port_t *, uint8_t);
 243  243  static  int ahci_add_intrs(ahci_ctl_t *, int);
 244  244  static  void ahci_rem_intrs(ahci_ctl_t *);
 245  245  static  void ahci_enable_all_intrs(ahci_ctl_t *);
 246  246  static  void ahci_disable_all_intrs(ahci_ctl_t *);
 247  247  static  void ahci_enable_port_intrs(ahci_ctl_t *, uint8_t);
 248  248  static  void ahci_disable_port_intrs(ahci_ctl_t *, uint8_t);
 249  249  
 250  250  static  int ahci_intr_cmd_cmplt(ahci_ctl_t *, ahci_port_t *, uint8_t);
 251  251  static  int ahci_intr_set_device_bits(ahci_ctl_t *, ahci_port_t *, uint8_t);
 252  252  static  int ahci_intr_ncq_events(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
 253  253  static  int ahci_intr_pmult_sntf_events(ahci_ctl_t *, ahci_port_t *, uint8_t);
 254  254  static  int ahci_intr_port_connect_change(ahci_ctl_t *, ahci_port_t *, uint8_t);
 255  255  static  int ahci_intr_device_mechanical_presence_status(ahci_ctl_t *,
 256  256      ahci_port_t *, uint8_t);
 257  257  static  int ahci_intr_phyrdy_change(ahci_ctl_t *, ahci_port_t *, uint8_t);
 258  258  static  int ahci_intr_non_fatal_error(ahci_ctl_t *, ahci_port_t *,
 259  259      uint8_t, uint32_t);
 260  260  static  int ahci_intr_fatal_error(ahci_ctl_t *, ahci_port_t *,
 261  261      uint8_t, uint32_t);
 262  262  static  int ahci_intr_cold_port_detect(ahci_ctl_t *, ahci_port_t *, uint8_t);
 263  263  
 264  264  static  void ahci_get_ahci_addr(ahci_ctl_t *, sata_device_t *, ahci_addr_t *);
 265  265  static  int ahci_get_num_implemented_ports(uint32_t);
 266  266  static  void ahci_log_fatal_error_message(ahci_ctl_t *, uint8_t, uint32_t);
 267  267  static  void ahci_dump_commands(ahci_ctl_t *, uint8_t, uint32_t);
 268  268  static  void ahci_log_serror_message(ahci_ctl_t *, uint8_t, uint32_t, int);
 269  269  #if AHCI_DEBUG
 270  270  static  void ahci_log(ahci_ctl_t *, uint_t, char *, ...);
 271  271  #endif
 272  272  
 273  273  static  boolean_t ahci_em_init(ahci_ctl_t *);
 274  274  static  void ahci_em_fini(ahci_ctl_t *);
 275  275  static  void ahci_em_suspend(ahci_ctl_t *);
 276  276  static  void ahci_em_resume(ahci_ctl_t *);
 277  277  static  int ahci_em_ioctl(dev_info_t *, int, intptr_t);
 278  278  
 279  279  
 280  280  /*
 281  281   * DMA attributes for the data buffer
 282  282   *
 283  283   * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
 284  284   * does not support 64-bit addressing
 285  285   */
 286  286  static ddi_dma_attr_t buffer_dma_attr = {
 287  287          DMA_ATTR_V0,            /* dma_attr_version */
 288  288          0x0ull,                 /* dma_attr_addr_lo: lowest bus address */
 289  289          0xffffffffffffffffull,  /* dma_attr_addr_hi: highest bus address */
 290  290          0x3fffffull,            /* dma_attr_count_max i.e. for one cookie */
 291  291          0x2ull,                 /* dma_attr_align: word aligned */
 292  292          1,                      /* dma_attr_burstsizes */
 293  293          1,                      /* dma_attr_minxfer */
 294  294          0xffffffffull,          /* dma_attr_maxxfer i.e. includes all cookies */
 295  295          0xffffffffull,          /* dma_attr_seg */
 296  296          AHCI_PRDT_NUMBER,       /* dma_attr_sgllen */
 297  297          512,                    /* dma_attr_granular */
 298  298          0,                      /* dma_attr_flags */
 299  299  };
 300  300  
 301  301  /*
 302  302   * DMA attributes for the rcvd FIS
 303  303   *
 304  304   * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
 305  305   * does not support 64-bit addressing
 306  306   */
 307  307  static ddi_dma_attr_t rcvd_fis_dma_attr = {
 308  308          DMA_ATTR_V0,            /* dma_attr_version */
 309  309          0x0ull,                 /* dma_attr_addr_lo: lowest bus address */
 310  310          0xffffffffffffffffull,  /* dma_attr_addr_hi: highest bus address */
 311  311          0xffffffffull,          /* dma_attr_count_max i.e. for one cookie */
 312  312          0x100ull,               /* dma_attr_align: 256-byte aligned */
 313  313          1,                      /* dma_attr_burstsizes */
 314  314          1,                      /* dma_attr_minxfer */
 315  315          0xffffffffull,          /* dma_attr_maxxfer i.e. includes all cookies */
 316  316          0xffffffffull,          /* dma_attr_seg */
 317  317          1,                      /* dma_attr_sgllen */
 318  318          1,                      /* dma_attr_granular */
 319  319          0,                      /* dma_attr_flags */
 320  320  };
 321  321  
 322  322  /*
 323  323   * DMA attributes for the command list
 324  324   *
 325  325   * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
 326  326   * does not support 64-bit addressing
 327  327   */
 328  328  static ddi_dma_attr_t cmd_list_dma_attr = {
 329  329          DMA_ATTR_V0,            /* dma_attr_version */
 330  330          0x0ull,                 /* dma_attr_addr_lo: lowest bus address */
 331  331          0xffffffffffffffffull,  /* dma_attr_addr_hi: highest bus address */
 332  332          0xffffffffull,          /* dma_attr_count_max i.e. for one cookie */
 333  333          0x400ull,               /* dma_attr_align: 1K-byte aligned */
 334  334          1,                      /* dma_attr_burstsizes */
 335  335          1,                      /* dma_attr_minxfer */
 336  336          0xffffffffull,          /* dma_attr_maxxfer i.e. includes all cookies */
 337  337          0xffffffffull,          /* dma_attr_seg */
 338  338          1,                      /* dma_attr_sgllen */
 339  339          1,                      /* dma_attr_granular */
 340  340          0,                      /* dma_attr_flags */
 341  341  };
 342  342  
 343  343  /*
 344  344   * DMA attributes for cmd tables
 345  345   *
 346  346   * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
 347  347   * does not support 64-bit addressing
 348  348   */
 349  349  static ddi_dma_attr_t cmd_table_dma_attr = {
 350  350          DMA_ATTR_V0,            /* dma_attr_version */
 351  351          0x0ull,                 /* dma_attr_addr_lo: lowest bus address */
 352  352          0xffffffffffffffffull,  /* dma_attr_addr_hi: highest bus address */
 353  353          0xffffffffull,          /* dma_attr_count_max i.e. for one cookie */
 354  354          0x80ull,                /* dma_attr_align: 128-byte aligned */
 355  355          1,                      /* dma_attr_burstsizes */
 356  356          1,                      /* dma_attr_minxfer */
 357  357          0xffffffffull,          /* dma_attr_maxxfer i.e. includes all cookies */
 358  358          0xffffffffull,          /* dma_attr_seg */
 359  359          1,                      /* dma_attr_sgllen */
 360  360          1,                      /* dma_attr_granular */
 361  361          0,                      /* dma_attr_flags */
 362  362  };
 363  363  
 364  364  
 365  365  /* Device access attributes */
 366  366  static ddi_device_acc_attr_t accattr = {
 367  367          DDI_DEVICE_ATTR_V1,
 368  368          DDI_STRUCTURE_LE_ACC,
 369  369          DDI_STRICTORDER_ACC,
 370  370          DDI_DEFAULT_ACC
 371  371  };
 372  372  
 373  373  static struct dev_ops ahcictl_dev_ops = {
 374  374          DEVO_REV,               /* devo_rev */
 375  375          0,                      /* refcnt  */
 376  376          ahci_getinfo,           /* info */
 377  377          nulldev,                /* identify */
 378  378          nulldev,                /* probe */
 379  379          ahci_attach,            /* attach */
 380  380          ahci_detach,            /* detach */
 381  381          nodev,                  /* no reset */
 382  382          NULL,                   /* driver operations */
 383  383          NULL,                   /* bus operations */
 384  384          NULL,                   /* power */
 385  385          ahci_quiesce,           /* quiesce */
 386  386  };
 387  387  
 388  388  static sata_tran_hotplug_ops_t ahci_tran_hotplug_ops = {
 389  389          SATA_TRAN_HOTPLUG_OPS_REV_1,
 390  390          ahci_tran_hotplug_port_activate,
 391  391          ahci_tran_hotplug_port_deactivate
 392  392  };
 393  393  
 394  394  extern struct mod_ops mod_driverops;
 395  395  
 396  396  static  struct modldrv modldrv = {
 397  397          &mod_driverops,         /* driverops */
 398  398          ahci_ident,             /* short description */
 399  399          &ahcictl_dev_ops,       /* driver ops */
 400  400  };
 401  401  
 402  402  static  struct modlinkage modlinkage = {
 403  403          MODREV_1,
 404  404          &modldrv,
 405  405          NULL
 406  406  };
 407  407  
 408  408  /* The following variables are watchdog handler related */
 409  409  static clock_t ahci_watchdog_timeout = 5; /* 5 seconds */
 410  410  static clock_t ahci_watchdog_tick;
 411  411  
 412  412  /*
 413  413   * This static variable indicates the size of command table,
 414  414   * and it's changeable with prdt number, which ahci_dma_prdt_number
 415  415   * indicates.
 416  416   */
 417  417  static size_t ahci_cmd_table_size;
 418  418  
 419  419  /*
 420  420   * The below global variables are tunable via /etc/system
 421  421   *
 422  422   *      ahci_dma_prdt_number
 423  423   *      ahci_msi_enabled
 424  424   *      ahci_buf_64bit_dma
 425  425   *      ahci_commu_64bit_dma
 426  426   */
 427  427  
 428  428  /* The number of Physical Region Descriptor Table(PRDT) in Command Table */
 429  429  int ahci_dma_prdt_number = AHCI_PRDT_NUMBER;
 430  430  
 431  431  /* AHCI MSI is tunable */
 432  432  boolean_t ahci_msi_enabled = B_TRUE;
 433  433  
 434  434  /*
 435  435   * 64-bit dma addressing for data buffer is tunable
 436  436   *
 437  437   * The variable controls only the below value:
 438  438   *      DBAU (upper 32-bits physical address of data block)
 439  439   */
 440  440  boolean_t ahci_buf_64bit_dma = B_TRUE;
 441  441  
 442  442  /*
 443  443   * 64-bit dma addressing for communication system descriptors is tunable
 444  444   *
 445  445   * The variable controls the below three values:
 446  446   *
 447  447   *      PxCLBU (upper 32-bits for the command list base physical address)
 448  448   *      PxFBU (upper 32-bits for the received FIS base physical address)
 449  449   *      CTBAU (upper 32-bits of command table base)
 450  450   */
 451  451  boolean_t ahci_commu_64bit_dma = B_TRUE;
 452  452  
 453  453  /*
 454  454   * By default, 64-bit dma for data buffer will be disabled for AMD/ATI SB600
 455  455   * chipset. If the users want to have a try with 64-bit dma, please change
 456  456   * the below variable value to enable it.
 457  457   */
 458  458  boolean_t sb600_buf_64bit_dma_disable = B_TRUE;
 459  459  
 460  460  /*
 461  461   * By default, 64-bit dma for command buffer will be disabled for AMD/ATI
 462  462   * SB600/700/710/750/800. If the users want to have a try with 64-bit dma,
 463  463   * please change the below value to enable it.
 464  464   */
 465  465  boolean_t sbxxx_commu_64bit_dma_disable = B_TRUE;
 466  466  
 467  467  /*
 468  468   * These values control the default delay and default number of times to wait
 469  469   * for an enclosure message to complete.
 470  470   */
 471  471  uint_t  ahci_em_reset_delay_ms = 1;
 472  472  uint_t  ahci_em_reset_delay_count = 1000;
 473  473  uint_t  ahci_em_tx_delay_ms = 1;
 474  474  uint_t  ahci_em_tx_delay_count = 1000;
 475  475  
 476  476  
 477  477  /*
 478  478   * End of global tunable variable definition
 479  479   */
 480  480  
 481  481  #if AHCI_DEBUG
 482  482  uint32_t ahci_debug_flags = 0;
 483  483  #else
 484  484  uint32_t ahci_debug_flags = (AHCIDBG_ERRS|AHCIDBG_TIMEOUT);
 485  485  #endif
 486  486  
 487  487  
 488  488  #if AHCI_DEBUG
 489  489  /* The following is needed for ahci_log() */
 490  490  static kmutex_t ahci_log_mutex;
 491  491  static char ahci_log_buf[512];
 492  492  #endif
 493  493  
 494  494  /* Opaque state pointer initialized by ddi_soft_state_init() */
 495  495  static void *ahci_statep = NULL;
 496  496  
 497  497  /*
 498  498   *  ahci module initialization.
 499  499   */
 500  500  int
 501  501  _init(void)
 502  502  {
 503  503          int     ret;
 504  504  
 505  505          ret = ddi_soft_state_init(&ahci_statep, sizeof (ahci_ctl_t), 0);
 506  506          if (ret != 0) {
 507  507                  goto err_out;
 508  508          }
 509  509  
 510  510  #if AHCI_DEBUG
 511  511          mutex_init(&ahci_log_mutex, NULL, MUTEX_DRIVER, NULL);
 512  512  #endif
 513  513  
 514  514          if ((ret = sata_hba_init(&modlinkage)) != 0) {
 515  515  #if AHCI_DEBUG
 516  516                  mutex_destroy(&ahci_log_mutex);
 517  517  #endif
 518  518                  ddi_soft_state_fini(&ahci_statep);
 519  519                  goto err_out;
 520  520          }
 521  521  
 522  522          /* watchdog tick */
 523  523          ahci_watchdog_tick = drv_usectohz(
 524  524              (clock_t)ahci_watchdog_timeout * 1000000);
 525  525  
 526  526          ret = mod_install(&modlinkage);
 527  527          if (ret != 0) {
 528  528                  sata_hba_fini(&modlinkage);
 529  529  #if AHCI_DEBUG
 530  530                  mutex_destroy(&ahci_log_mutex);
 531  531  #endif
 532  532                  ddi_soft_state_fini(&ahci_statep);
 533  533                  goto err_out;
 534  534          }
 535  535  
 536  536          return (ret);
 537  537  
 538  538  err_out:
 539  539          cmn_err(CE_WARN, "!ahci: Module init failed");
 540  540          return (ret);
 541  541  }
 542  542  
 543  543  /*
 544  544   * ahci module uninitialize.
 545  545   */
 546  546  int
 547  547  _fini(void)
 548  548  {
 549  549          int     ret;
 550  550  
 551  551          ret = mod_remove(&modlinkage);
 552  552          if (ret != 0) {
 553  553                  return (ret);
 554  554          }
 555  555  
 556  556          /* Remove the resources allocated in _init(). */
 557  557          sata_hba_fini(&modlinkage);
 558  558  #if AHCI_DEBUG
 559  559          mutex_destroy(&ahci_log_mutex);
 560  560  #endif
 561  561          ddi_soft_state_fini(&ahci_statep);
 562  562  
 563  563          return (ret);
 564  564  }
 565  565  
 566  566  /*
 567  567   * _info entry point
 568  568   */
 569  569  int
 570  570  _info(struct modinfo *modinfop)
 571  571  {
 572  572          return (mod_info(&modlinkage, modinfop));
 573  573  }
 574  574  
 575  575  /*
 576  576   * The attach entry point for dev_ops.
 577  577   */
 578  578  static int
 579  579  ahci_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 580  580  {
 581  581          ahci_ctl_t *ahci_ctlp = NULL;
 582  582          int instance = ddi_get_instance(dip);
 583  583          int status;
 584  584          int attach_state;
 585  585          uint32_t cap_status, ahci_version;
 586  586          uint32_t ghc_control;
 587  587          int intr_types;
 588  588          int i;
 589  589          pci_regspec_t *regs;
 590  590          int regs_length;
 591  591          int rnumber;
 592  592  #if AHCI_DEBUG
 593  593          int speed;
 594  594  #endif
 595  595  
 596  596          AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp, "ahci_attach enter",
 597  597              NULL);
 598  598  
 599  599          switch (cmd) {
 600  600          case DDI_ATTACH:
 601  601                  break;
 602  602  
 603  603          case DDI_RESUME:
 604  604  
 605  605                  /*
 606  606                   * During DDI_RESUME, the hardware state of the device
 607  607                   * (power may have been removed from the device) must be
 608  608                   * restored, allow pending requests to continue, and
 609  609                   * service new requests.
 610  610                   */
 611  611                  ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
 612  612                  mutex_enter(&ahci_ctlp->ahcictl_mutex);
 613  613  
 614  614                  /*
 615  615                   * GHC.AE must be set to 1 before any other AHCI register
 616  616                   * is accessed
 617  617                   */
 618  618                  ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
 619  619                      (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
 620  620                  ghc_control |= AHCI_HBA_GHC_AE;
 621  621                  ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
 622  622                      (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
 623  623  
 624  624                  /* Restart watch thread */
 625  625                  if (ahci_ctlp->ahcictl_timeout_id == 0)
 626  626                          ahci_ctlp->ahcictl_timeout_id = timeout(
 627  627                              (void (*)(void *))ahci_watchdog_handler,
 628  628                              (caddr_t)ahci_ctlp, ahci_watchdog_tick);
 629  629  
 630  630                  mutex_exit(&ahci_ctlp->ahcictl_mutex);
 631  631  
 632  632                  /*
 633  633                   * Re-initialize the controller and enable the interrupts and
 634  634                   * restart all the ports.
 635  635                   *
 636  636                   * Note that so far we don't support hot-plug during
 637  637                   * suspend/resume.
 638  638                   */
 639  639                  if (ahci_initialize_controller(ahci_ctlp) != AHCI_SUCCESS) {
 640  640                          AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PM, ahci_ctlp,
 641  641                              "Failed to initialize the controller "
 642  642                              "during DDI_RESUME", NULL);
 643  643                          return (DDI_FAILURE);
 644  644                  }
 645  645  
 646  646                  /*
 647  647                   * Reset the enclosure services.
 648  648                   */
 649  649                  ahci_em_resume(ahci_ctlp);
 650  650  
 651  651                  mutex_enter(&ahci_ctlp->ahcictl_mutex);
 652  652                  ahci_ctlp->ahcictl_flags &= ~AHCI_SUSPEND;
 653  653                  mutex_exit(&ahci_ctlp->ahcictl_mutex);
 654  654  
 655  655                  return (DDI_SUCCESS);
 656  656  
 657  657          default:
 658  658                  return (DDI_FAILURE);
 659  659          }
 660  660  
 661  661          attach_state = AHCI_ATTACH_STATE_NONE;
 662  662  
 663  663          /* Allocate soft state */
 664  664          status = ddi_soft_state_zalloc(ahci_statep, instance);
 665  665          if (status != DDI_SUCCESS) {
 666  666                  cmn_err(CE_WARN, "!ahci%d: Cannot allocate soft state",
 667  667                      instance);
 668  668                  goto err_out;
 669  669          }
 670  670  
 671  671          ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
 672  672          ahci_ctlp->ahcictl_flags |= AHCI_ATTACH;
 673  673          ahci_ctlp->ahcictl_dip = dip;
 674  674  
 675  675          /* Initialize the cport/port mapping */
 676  676          for (i = 0; i < AHCI_MAX_PORTS; i++) {
 677  677                  ahci_ctlp->ahcictl_port_to_cport[i] = 0xff;
 678  678                  ahci_ctlp->ahcictl_cport_to_port[i] = 0xff;
 679  679          }
 680  680  
 681  681          attach_state |= AHCI_ATTACH_STATE_STATEP_ALLOC;
 682  682  
 683  683          /* Initialize FMA properties */
 684  684          ahci_fm_init(ahci_ctlp);
 685  685  
 686  686          attach_state |= AHCI_ATTACH_STATE_FMA;
 687  687  
 688  688          /*
 689  689           * Now map the AHCI base address; which includes global
 690  690           * registers and port control registers
 691  691           *
 692  692           * According to the spec, the AHCI Base Address is BAR5,
 693  693           * but BAR0-BAR4 are optional, so we need to check which
 694  694           * rnumber is used for BAR5.
 695  695           */
 696  696  
 697  697          /*
 698  698           * search through DDI "reg" property for the AHCI register set
 699  699           */
 700  700          if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
 701  701              DDI_PROP_DONTPASS, "reg", (int **)®s,
 702  702              (uint_t *)®s_length) != DDI_PROP_SUCCESS) {
 703  703                  cmn_err(CE_WARN, "!ahci%d: Cannot lookup reg property",
 704  704                      instance);
 705  705                  goto err_out;
 706  706          }
 707  707  
 708  708          /* AHCI Base Address is located at 0x24 offset */
 709  709          for (rnumber = 0; rnumber < regs_length; ++rnumber) {
 710  710                  if ((regs[rnumber].pci_phys_hi & PCI_REG_REG_M)
 711  711                      == AHCI_PCI_RNUM)
 712  712                          break;
 713  713          }
 714  714  
 715  715          ddi_prop_free(regs);
 716  716  
 717  717          if (rnumber == regs_length) {
 718  718                  cmn_err(CE_WARN, "!ahci%d: Cannot find AHCI register set",
 719  719                      instance);
 720  720                  goto err_out;
 721  721          }
 722  722  
 723  723          AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "rnumber = %d", rnumber);
 724  724  
 725  725          status = ddi_regs_map_setup(dip,
 726  726              rnumber,
 727  727              (caddr_t *)&ahci_ctlp->ahcictl_ahci_addr,
 728  728              0,
 729  729              0,
 730  730              &accattr,
 731  731              &ahci_ctlp->ahcictl_ahci_acc_handle);
 732  732          if (status != DDI_SUCCESS) {
 733  733                  cmn_err(CE_WARN, "!ahci%d: Cannot map register space",
 734  734                      instance);
 735  735                  goto err_out;
 736  736          }
 737  737  
 738  738          attach_state |= AHCI_ATTACH_STATE_REG_MAP;
 739  739  
 740  740          /*
 741  741           * GHC.AE must be set to 1 before any other AHCI register
 742  742           * is accessed
 743  743           */
 744  744          ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
 745  745              (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
 746  746          ghc_control |= AHCI_HBA_GHC_AE;
 747  747          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
 748  748              (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
 749  749  
 750  750          /* Get the AHCI version information */
 751  751          ahci_version = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
 752  752              (uint32_t *)AHCI_GLOBAL_VS(ahci_ctlp));
 753  753  
 754  754          cmn_err(CE_NOTE, "!ahci%d: hba AHCI version = %x.%x", instance,
 755  755              (ahci_version & 0xffff0000) >> 16,
 756  756              ((ahci_version & 0x0000ff00) >> 4 |
 757  757              (ahci_version & 0x000000ff)));
 758  758  
 759  759          /* We don't support controllers whose versions are lower than 1.0 */
 760  760          if (!(ahci_version & 0xffff0000)) {
 761  761                  cmn_err(CE_WARN, "ahci%d: Don't support AHCI HBA with lower "
 762  762                      "than version 1.0", instance);
 763  763                  goto err_out;
 764  764          }
 765  765  
 766  766          /* Get the HBA capabilities information */
 767  767          cap_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
 768  768              (uint32_t *)AHCI_GLOBAL_CAP(ahci_ctlp));
 769  769  
 770  770          AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba capabilities = 0x%x",
 771  771              cap_status);
 772  772  
 773  773          /* CAP2 (HBA Capabilities Extended) is available since AHCI spec 1.2 */
 774  774          if (ahci_version >= 0x00010200) {
 775  775                  uint32_t cap2_status;
 776  776  
 777  777                  /* Get the HBA capabilities extended information */
 778  778                  cap2_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
 779  779                      (uint32_t *)AHCI_GLOBAL_CAP2(ahci_ctlp));
 780  780  
 781  781                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
 782  782                      "hba capabilities extended = 0x%x", cap2_status);
 783  783          }
 784  784  
 785  785          if (cap_status & AHCI_HBA_CAP_EMS) {
 786  786                  ahci_ctlp->ahcictl_cap |= AHCI_CAP_EMS;
 787  787                  ahci_ctlp->ahcictl_em_loc =
 788  788                      ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
 789  789                      (uint32_t *)AHCI_GLOBAL_EM_LOC(ahci_ctlp));
 790  790                  ahci_ctlp->ahcictl_em_ctl =
 791  791                      ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
 792  792                      (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp));
 793  793          }
 794  794  
 795  795  #if AHCI_DEBUG
 796  796          /* Get the interface speed supported by the HBA */
 797  797          speed = (cap_status & AHCI_HBA_CAP_ISS) >> AHCI_HBA_CAP_ISS_SHIFT;
 798  798          if (speed == 0x01) {
 799  799                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
 800  800                      "hba interface speed support: Gen 1 (1.5Gbps)", NULL);
 801  801          } else if (speed == 0x10) {
 802  802                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
 803  803                      "hba interface speed support: Gen 2 (3 Gbps)", NULL);
 804  804          } else if (speed == 0x11) {
 805  805                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
 806  806                      "hba interface speed support: Gen 3 (6 Gbps)", NULL);
 807  807          }
 808  808  #endif
 809  809  
 810  810          /* Get the number of command slots supported by the HBA */
 811  811          ahci_ctlp->ahcictl_num_cmd_slots =
 812  812              ((cap_status & AHCI_HBA_CAP_NCS) >>
 813  813              AHCI_HBA_CAP_NCS_SHIFT) + 1;
 814  814  
 815  815          AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba number of cmd slots: %d",
 816  816              ahci_ctlp->ahcictl_num_cmd_slots);
 817  817  
 818  818          /* Get the bit map which indicates ports implemented by the HBA */
 819  819          ahci_ctlp->ahcictl_ports_implemented =
 820  820              ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
 821  821              (uint32_t *)AHCI_GLOBAL_PI(ahci_ctlp));
 822  822  
 823  823          AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba implementation of ports: 0x%x",
 824  824              ahci_ctlp->ahcictl_ports_implemented);
 825  825  
 826  826          /* Max port number implemented */
 827  827          ahci_ctlp->ahcictl_num_ports =
 828  828              ddi_fls(ahci_ctlp->ahcictl_ports_implemented);
 829  829  
 830  830          AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba number of ports: %d",
 831  831              (cap_status & AHCI_HBA_CAP_NP) + 1);
 832  832  
 833  833          /* Get the number of implemented ports by the HBA */
 834  834          ahci_ctlp->ahcictl_num_implemented_ports =
 835  835              ahci_get_num_implemented_ports(
 836  836              ahci_ctlp->ahcictl_ports_implemented);
 837  837  
 838  838          AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
 839  839              "hba number of implemented ports: %d",
 840  840              ahci_ctlp->ahcictl_num_implemented_ports);
 841  841  
 842  842          /* Check whether HBA supports 64bit DMA addressing */
 843  843          if (!(cap_status & AHCI_HBA_CAP_S64A)) {
 844  844                  ahci_ctlp->ahcictl_cap |= AHCI_CAP_BUF_32BIT_DMA;
 845  845                  ahci_ctlp->ahcictl_cap |= AHCI_CAP_COMMU_32BIT_DMA;
 846  846                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
 847  847                      "hba does not support 64-bit addressing", NULL);
 848  848          }
 849  849  
 850  850          /* Checking for the support of Port Multiplier */
 851  851          if (cap_status & AHCI_HBA_CAP_SPM) {
 852  852                  ahci_ctlp->ahcictl_cap |= AHCI_CAP_PMULT_CBSS;
 853  853                  AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
 854  854                      "hba supports port multiplier (CBSS)", NULL);
 855  855  
 856  856                  /* Support FIS-based switching ? */
 857  857                  if (cap_status & AHCI_HBA_CAP_FBSS) {
 858  858                          ahci_ctlp->ahcictl_cap |= AHCI_CAP_PMULT_FBSS;
 859  859                          AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
 860  860                              "hba supports FIS-based switching (FBSS)", NULL);
 861  861                  }
 862  862          }
 863  863  
 864  864          /* Checking for Support Command List Override */
 865  865          if (cap_status & AHCI_HBA_CAP_SCLO) {
 866  866                  ahci_ctlp->ahcictl_cap |= AHCI_CAP_SCLO;
 867  867                  AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
 868  868                      "hba supports command list override.", NULL);
 869  869          }
 870  870  
 871  871          /* Checking for Asynchronous Notification */
 872  872          if (cap_status & AHCI_HBA_CAP_SSNTF) {
 873  873                  ahci_ctlp->ahcictl_cap |= AHCI_CAP_SNTF;
 874  874                  AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
 875  875                      "hba supports asynchronous notification.", NULL);
 876  876          }
 877  877  
 878  878          if (pci_config_setup(dip, &ahci_ctlp->ahcictl_pci_conf_handle)
 879  879              != DDI_SUCCESS) {
 880  880                  cmn_err(CE_WARN, "!ahci%d: Cannot set up pci configure space",
 881  881                      instance);
 882  882                  goto err_out;
 883  883          }
 884  884  
 885  885          attach_state |= AHCI_ATTACH_STATE_PCICFG_SETUP;
 886  886  
 887  887          /*
 888  888           * Check the pci configuration space, and set caps. We also
 889  889           * handle the hardware defect in this function.
 890  890           *
 891  891           * For example, force ATI SB600 to use 32-bit dma addressing
 892  892           * since it doesn't support 64-bit dma though its CAP register
 893  893           * declares it support.
 894  894           */
 895  895          if (ahci_config_space_init(ahci_ctlp) == AHCI_FAILURE) {
 896  896                  cmn_err(CE_WARN, "!ahci%d: ahci_config_space_init failed",
 897  897                      instance);
 898  898                  goto err_out;
 899  899          }
 900  900  
 901  901          /*
 902  902           * Disable the whole controller interrupts before adding
 903  903           * interrupt handlers(s).
 904  904           */
 905  905          ahci_disable_all_intrs(ahci_ctlp);
 906  906  
 907  907          /* Get supported interrupt types */
 908  908          if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) {
 909  909                  cmn_err(CE_WARN, "!ahci%d: ddi_intr_get_supported_types failed",
 910  910                      instance);
 911  911                  goto err_out;
 912  912          }
 913  913  
 914  914          AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
 915  915              "ddi_intr_get_supported_types() returned: 0x%x",
 916  916              intr_types);
 917  917  
 918  918          if (ahci_msi_enabled && (intr_types & DDI_INTR_TYPE_MSI)) {
 919  919                  /*
 920  920                   * Try MSI first, but fall back to FIXED if failed
 921  921                   */
 922  922                  if (ahci_add_intrs(ahci_ctlp, DDI_INTR_TYPE_MSI) ==
 923  923                      DDI_SUCCESS) {
 924  924                          ahci_ctlp->ahcictl_intr_type = DDI_INTR_TYPE_MSI;
 925  925                          AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
 926  926                              "Using MSI interrupt type", NULL);
 927  927                          goto intr_done;
 928  928                  }
 929  929  
 930  930                  AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
 931  931                      "MSI registration failed, "
 932  932                      "trying FIXED interrupts", NULL);
 933  933          }
 934  934  
 935  935          if (intr_types & DDI_INTR_TYPE_FIXED) {
 936  936                  if (ahci_add_intrs(ahci_ctlp, DDI_INTR_TYPE_FIXED) ==
 937  937                      DDI_SUCCESS) {
 938  938                          ahci_ctlp->ahcictl_intr_type = DDI_INTR_TYPE_FIXED;
 939  939                          AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
 940  940                              "Using FIXED interrupt type", NULL);
 941  941                          goto intr_done;
 942  942                  }
 943  943  
 944  944                  AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
 945  945                      "FIXED interrupt registration failed", NULL);
 946  946          }
 947  947  
 948  948          cmn_err(CE_WARN, "!ahci%d: Interrupt registration failed", instance);
 949  949  
 950  950          goto err_out;
 951  951  
 952  952  intr_done:
 953  953  
 954  954          attach_state |= AHCI_ATTACH_STATE_INTR_ADDED;
 955  955  
 956  956          /* Initialize the controller mutex */
 957  957          mutex_init(&ahci_ctlp->ahcictl_mutex, NULL, MUTEX_DRIVER,
 958  958              (void *)(uintptr_t)ahci_ctlp->ahcictl_intr_pri);
 959  959  
 960  960          attach_state |= AHCI_ATTACH_STATE_MUTEX_INIT;
 961  961  
 962  962          if (ahci_dma_prdt_number < AHCI_MIN_PRDT_NUMBER) {
 963  963                  ahci_dma_prdt_number = AHCI_MIN_PRDT_NUMBER;
 964  964          } else if (ahci_dma_prdt_number > AHCI_MAX_PRDT_NUMBER) {
 965  965                  ahci_dma_prdt_number = AHCI_MAX_PRDT_NUMBER;
 966  966          }
 967  967  
 968  968          ahci_cmd_table_size = (sizeof (ahci_cmd_table_t) +
 969  969              (ahci_dma_prdt_number - AHCI_PRDT_NUMBER) *
 970  970              sizeof (ahci_prdt_item_t));
 971  971  
 972  972          AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
 973  973              "ahci_attach: ahci_dma_prdt_number set by user is 0x%x,"
 974  974              " ahci_cmd_table_size is 0x%x",
 975  975              ahci_dma_prdt_number, ahci_cmd_table_size);
 976  976  
 977  977          if (ahci_dma_prdt_number != AHCI_PRDT_NUMBER)
 978  978                  ahci_ctlp->ahcictl_buffer_dma_attr.dma_attr_sgllen =
 979  979                      ahci_dma_prdt_number;
 980  980  
 981  981          ahci_ctlp->ahcictl_buffer_dma_attr = buffer_dma_attr;
 982  982          ahci_ctlp->ahcictl_rcvd_fis_dma_attr = rcvd_fis_dma_attr;
 983  983          ahci_ctlp->ahcictl_cmd_list_dma_attr = cmd_list_dma_attr;
 984  984          ahci_ctlp->ahcictl_cmd_table_dma_attr = cmd_table_dma_attr;
 985  985  
 986  986          /*
 987  987           * enable 64bit dma for data buffer for SB600 if
 988  988           * sb600_buf_64bit_dma_disable is B_FALSE
 989  989           */
 990  990          if ((ahci_buf_64bit_dma == B_FALSE) ||
 991  991              ((ahci_ctlp->ahcictl_cap & AHCI_CAP_BUF_32BIT_DMA) &&
 992  992              !(sb600_buf_64bit_dma_disable == B_FALSE &&
 993  993              ahci_ctlp->ahcictl_venid == 0x1002 &&
 994  994              ahci_ctlp->ahcictl_devid == 0x4380))) {
 995  995                  ahci_ctlp->ahcictl_buffer_dma_attr.dma_attr_addr_hi =
 996  996                      0xffffffffull;
 997  997          }
 998  998  
 999  999          /*
1000 1000           * enable 64bit dma for command buffer for SB600/700/710/800
1001 1001           * if sbxxx_commu_64bit_dma_disable is B_FALSE
1002 1002           */
1003 1003          if ((ahci_commu_64bit_dma == B_FALSE) ||
1004 1004              ((ahci_ctlp->ahcictl_cap & AHCI_CAP_COMMU_32BIT_DMA) &&
1005 1005              !(sbxxx_commu_64bit_dma_disable == B_FALSE &&
1006 1006              ahci_ctlp->ahcictl_venid == 0x1002 &&
1007 1007              (ahci_ctlp->ahcictl_devid == 0x4380 ||
1008 1008              ahci_ctlp->ahcictl_devid == 0x4391)))) {
1009 1009                  ahci_ctlp->ahcictl_rcvd_fis_dma_attr.dma_attr_addr_hi =
1010 1010                      0xffffffffull;
1011 1011                  ahci_ctlp->ahcictl_cmd_list_dma_attr.dma_attr_addr_hi =
1012 1012                      0xffffffffull;
1013 1013                  ahci_ctlp->ahcictl_cmd_table_dma_attr.dma_attr_addr_hi =
1014 1014                      0xffffffffull;
1015 1015          }
1016 1016  
1017 1017          /* Allocate the ports structure */
1018 1018          status = ahci_alloc_ports_state(ahci_ctlp);
1019 1019          if (status != AHCI_SUCCESS) {
1020 1020                  cmn_err(CE_WARN, "!ahci%d: Cannot allocate ports structure",
1021 1021                      instance);
1022 1022                  goto err_out;
1023 1023          }
1024 1024  
1025 1025          attach_state |= AHCI_ATTACH_STATE_PORT_ALLOC;
1026 1026  
1027 1027          /*
1028 1028           * Initialize the controller and ports.
1029 1029           */
1030 1030          status = ahci_initialize_controller(ahci_ctlp);
1031 1031          if (status != AHCI_SUCCESS) {
1032 1032                  cmn_err(CE_WARN, "!ahci%d: HBA initialization failed",
1033 1033                      instance);
1034 1034                  goto err_out;
1035 1035          }
1036 1036  
1037 1037          attach_state |= AHCI_ATTACH_STATE_HW_INIT;
1038 1038  
1039 1039          /* Start one thread to check packet timeouts */
1040 1040          ahci_ctlp->ahcictl_timeout_id = timeout(
1041 1041              (void (*)(void *))ahci_watchdog_handler,
1042 1042              (caddr_t)ahci_ctlp, ahci_watchdog_tick);
1043 1043  
1044 1044          attach_state |= AHCI_ATTACH_STATE_TIMEOUT_ENABLED;
1045 1045  
1046 1046          if (!ahci_em_init(ahci_ctlp)) {
1047 1047                  cmn_err(CE_WARN, "!ahci%d: failed to initialize enclosure "
1048 1048                      "services", instance);
1049 1049                  goto err_out;
1050 1050          }
1051 1051          attach_state |= AHCI_ATTACH_STATE_ENCLOSURE;
1052 1052  
1053 1053          if (ahci_register_sata_hba_tran(ahci_ctlp, cap_status)) {
1054 1054                  cmn_err(CE_WARN, "!ahci%d: sata hba tran registration failed",
1055 1055                      instance);
1056 1056                  goto err_out;
1057 1057          }
1058 1058  
1059 1059          /* Check all handles at the end of the attach operation. */
1060 1060          if (ahci_check_all_handle(ahci_ctlp) != DDI_SUCCESS) {
1061 1061                  cmn_err(CE_WARN, "!ahci%d: invalid dma/acc handles",
1062 1062                      instance);
1063 1063                  goto err_out;
1064 1064          }
1065 1065  
1066 1066          ahci_ctlp->ahcictl_flags &= ~AHCI_ATTACH;
1067 1067  
1068 1068          AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "ahci_attach success!", NULL);
1069 1069  
1070 1070          return (DDI_SUCCESS);
1071 1071  
1072 1072  err_out:
1073 1073          /* FMA message */
1074 1074          ahci_fm_ereport(ahci_ctlp, DDI_FM_DEVICE_NO_RESPONSE);
1075 1075          ddi_fm_service_impact(ahci_ctlp->ahcictl_dip, DDI_SERVICE_LOST);
1076 1076  
1077 1077          if (attach_state & AHCI_ATTACH_STATE_ENCLOSURE) {
1078 1078                  ahci_em_fini(ahci_ctlp);
1079 1079          }
1080 1080  
1081 1081          if (attach_state & AHCI_ATTACH_STATE_TIMEOUT_ENABLED) {
1082 1082                  mutex_enter(&ahci_ctlp->ahcictl_mutex);
1083 1083                  (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1084 1084                  ahci_ctlp->ahcictl_timeout_id = 0;
1085 1085                  mutex_exit(&ahci_ctlp->ahcictl_mutex);
1086 1086          }
1087 1087  
1088 1088          if (attach_state & AHCI_ATTACH_STATE_HW_INIT) {
1089 1089                  ahci_uninitialize_controller(ahci_ctlp);
1090 1090          }
1091 1091  
1092 1092          if (attach_state & AHCI_ATTACH_STATE_PORT_ALLOC) {
1093 1093                  ahci_dealloc_ports_state(ahci_ctlp);
1094 1094          }
1095 1095  
1096 1096          if (attach_state & AHCI_ATTACH_STATE_MUTEX_INIT) {
1097 1097                  mutex_destroy(&ahci_ctlp->ahcictl_mutex);
1098 1098          }
1099 1099  
1100 1100          if (attach_state & AHCI_ATTACH_STATE_INTR_ADDED) {
1101 1101                  ahci_rem_intrs(ahci_ctlp);
1102 1102          }
1103 1103  
1104 1104          if (attach_state & AHCI_ATTACH_STATE_PCICFG_SETUP) {
1105 1105                  pci_config_teardown(&ahci_ctlp->ahcictl_pci_conf_handle);
1106 1106          }
1107 1107  
1108 1108          if (attach_state & AHCI_ATTACH_STATE_REG_MAP) {
1109 1109                  ddi_regs_map_free(&ahci_ctlp->ahcictl_ahci_acc_handle);
1110 1110          }
1111 1111  
1112 1112          if (attach_state & AHCI_ATTACH_STATE_FMA) {
1113 1113                  ahci_fm_fini(ahci_ctlp);
1114 1114          }
1115 1115  
1116 1116          if (attach_state & AHCI_ATTACH_STATE_STATEP_ALLOC) {
1117 1117                  ddi_soft_state_free(ahci_statep, instance);
1118 1118          }
1119 1119  
1120 1120          return (DDI_FAILURE);
1121 1121  }
1122 1122  
1123 1123  /*
1124 1124   * The detach entry point for dev_ops.
1125 1125   */
1126 1126  static int
1127 1127  ahci_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1128 1128  {
1129 1129          ahci_ctl_t *ahci_ctlp;
1130 1130          int instance;
1131 1131          int ret;
1132 1132  
1133 1133          instance = ddi_get_instance(dip);
1134 1134          ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
1135 1135  
1136 1136          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_detach enter", NULL);
1137 1137  
1138 1138          switch (cmd) {
1139 1139          case DDI_DETACH:
1140 1140  
1141 1141                  /* disable the interrupts for an uninterrupted detach */
1142 1142                  mutex_enter(&ahci_ctlp->ahcictl_mutex);
1143 1143                  ahci_disable_all_intrs(ahci_ctlp);
1144 1144                  mutex_exit(&ahci_ctlp->ahcictl_mutex);
1145 1145  
1146 1146                  /* unregister from the sata framework. */
1147 1147                  ret = ahci_unregister_sata_hba_tran(ahci_ctlp);
1148 1148                  if (ret != AHCI_SUCCESS) {
1149 1149                          mutex_enter(&ahci_ctlp->ahcictl_mutex);
1150 1150                          ahci_enable_all_intrs(ahci_ctlp);
1151 1151                          mutex_exit(&ahci_ctlp->ahcictl_mutex);
1152 1152                          return (DDI_FAILURE);
1153 1153                  }
1154 1154  
1155 1155                  ahci_em_fini(ahci_ctlp);
1156 1156  
1157 1157                  mutex_enter(&ahci_ctlp->ahcictl_mutex);
1158 1158  
1159 1159                  /* stop the watchdog handler */
1160 1160                  (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1161 1161                  ahci_ctlp->ahcictl_timeout_id = 0;
1162 1162  
1163 1163                  mutex_exit(&ahci_ctlp->ahcictl_mutex);
1164 1164  
1165 1165                  /* uninitialize the controller */
1166 1166                  ahci_uninitialize_controller(ahci_ctlp);
1167 1167  
1168 1168                  /* remove the interrupts */
1169 1169                  ahci_rem_intrs(ahci_ctlp);
1170 1170  
1171 1171                  /* deallocate the ports structures */
1172 1172                  ahci_dealloc_ports_state(ahci_ctlp);
1173 1173  
1174 1174                  /* destroy mutex */
1175 1175                  mutex_destroy(&ahci_ctlp->ahcictl_mutex);
1176 1176  
1177 1177                  /* teardown the pci config */
1178 1178                  pci_config_teardown(&ahci_ctlp->ahcictl_pci_conf_handle);
1179 1179  
1180 1180                  /* remove the reg maps. */
1181 1181                  ddi_regs_map_free(&ahci_ctlp->ahcictl_ahci_acc_handle);
1182 1182  
1183 1183                  /* release fma resource */
1184 1184                  ahci_fm_fini(ahci_ctlp);
1185 1185  
1186 1186                  /* free the soft state. */
1187 1187                  ddi_soft_state_free(ahci_statep, instance);
1188 1188  
1189 1189                  return (DDI_SUCCESS);
1190 1190  
1191 1191          case DDI_SUSPEND:
1192 1192  
1193 1193                  /*
1194 1194                   * The steps associated with suspension must include putting
1195 1195                   * the underlying device into a quiescent state so that it
1196 1196                   * will not generate interrupts or modify or access memory.
1197 1197                   */
1198 1198                  mutex_enter(&ahci_ctlp->ahcictl_mutex);
1199 1199                  if (ahci_ctlp->ahcictl_flags & AHCI_SUSPEND) {
1200 1200                          mutex_exit(&ahci_ctlp->ahcictl_mutex);
1201 1201                          return (DDI_SUCCESS);
1202 1202                  }
1203 1203  
1204 1204                  ahci_ctlp->ahcictl_flags |= AHCI_SUSPEND;
1205 1205  
1206 1206                  /* stop the watchdog handler */
1207 1207                  if (ahci_ctlp->ahcictl_timeout_id) {
1208 1208                          (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1209 1209                          ahci_ctlp->ahcictl_timeout_id = 0;
1210 1210                  }
1211 1211  
1212 1212                  mutex_exit(&ahci_ctlp->ahcictl_mutex);
1213 1213  
1214 1214                  ahci_em_suspend(ahci_ctlp);
1215 1215  
1216 1216                  /*
1217 1217                   * drain the taskq
1218 1218                   */
1219 1219                  ahci_drain_ports_taskq(ahci_ctlp);
1220 1220  
1221 1221                  /*
1222 1222                   * Disable the interrupts and stop all the ports.
1223 1223                   */
1224 1224                  ahci_uninitialize_controller(ahci_ctlp);
1225 1225  
1226 1226                  return (DDI_SUCCESS);
1227 1227  
1228 1228          default:
1229 1229                  return (DDI_FAILURE);
1230 1230          }
1231 1231  }
1232 1232  
1233 1233  /*
1234 1234   * The info entry point for dev_ops.
1235 1235   *
1236 1236   */
1237 1237  static int
1238 1238  ahci_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd,
1239 1239      void *arg, void **result)
1240 1240  {
1241 1241  #ifndef __lock_lint
1242 1242          _NOTE(ARGUNUSED(dip))
1243 1243  #endif /* __lock_lint */
1244 1244  
1245 1245          ahci_ctl_t *ahci_ctlp;
1246 1246          int instance;
1247 1247          dev_t dev;
1248 1248  
1249 1249          dev = (dev_t)arg;
1250 1250          instance = getminor(dev);
1251 1251  
1252 1252          switch (infocmd) {
1253 1253                  case DDI_INFO_DEVT2DEVINFO:
1254 1254                          ahci_ctlp = ddi_get_soft_state(ahci_statep,  instance);
1255 1255                          if (ahci_ctlp != NULL) {
1256 1256                                  *result = ahci_ctlp->ahcictl_dip;
1257 1257                                  return (DDI_SUCCESS);
1258 1258                          } else {
1259 1259                                  *result = NULL;
1260 1260                                  return (DDI_FAILURE);
1261 1261                          }
1262 1262                  case DDI_INFO_DEVT2INSTANCE:
1263 1263                          *(int *)result = instance;
1264 1264                          break;
1265 1265                  default:
1266 1266                          break;
1267 1267          }
1268 1268  
1269 1269          return (DDI_SUCCESS);
1270 1270  }
1271 1271  
1272 1272  /*
1273 1273   * Registers the ahci with sata framework.
1274 1274   */
1275 1275  static int
1276 1276  ahci_register_sata_hba_tran(ahci_ctl_t *ahci_ctlp, uint32_t cap_status)
1277 1277  {
1278 1278          struct  sata_hba_tran   *sata_hba_tran;
1279 1279  
1280 1280          AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
1281 1281              "ahci_register_sata_hba_tran enter", NULL);
1282 1282  
1283 1283          mutex_enter(&ahci_ctlp->ahcictl_mutex);
1284 1284  
1285 1285          /* Allocate memory for the sata_hba_tran  */
1286 1286          sata_hba_tran = kmem_zalloc(sizeof (sata_hba_tran_t), KM_SLEEP);
1287 1287  
1288 1288          sata_hba_tran->sata_tran_hba_rev = SATA_TRAN_HBA_REV;
1289 1289          sata_hba_tran->sata_tran_hba_dip = ahci_ctlp->ahcictl_dip;
1290 1290          sata_hba_tran->sata_tran_hba_dma_attr =
1291 1291              &ahci_ctlp->ahcictl_buffer_dma_attr;
1292 1292  
1293 1293          /* Report the number of implemented ports */
1294 1294          sata_hba_tran->sata_tran_hba_num_cports =
1295 1295              ahci_ctlp->ahcictl_num_implemented_ports;
1296 1296  
1297 1297          /* Support ATAPI device */
1298 1298          sata_hba_tran->sata_tran_hba_features_support = SATA_CTLF_ATAPI;
1299 1299  
1300 1300          /* Get the data transfer capability for PIO command by the HBA */
1301 1301          if (cap_status & AHCI_HBA_CAP_PMD) {
1302 1302                  ahci_ctlp->ahcictl_cap |= AHCI_CAP_PIO_MDRQ;
1303 1303                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "HBA supports multiple "
1304 1304                      "DRQ block data transfer for PIO command protocol", NULL);
1305 1305          }
1306 1306  
1307 1307          /*
1308 1308           * According to the AHCI spec, the ATA/ATAPI-7 queued feature set
1309 1309           * is not supported by AHCI (including the READ QUEUED (EXT), WRITE
1310 1310           * QUEUED (EXT), and SERVICE commands). Queued operations are
1311 1311           * supported in AHCI using the READ FPDMA QUEUED and WRITE FPDMA
1312 1312           * QUEUED commands when the HBA and device support native command
1313 1313           * queuing(NCQ).
1314 1314           *
1315 1315           * SATA_CTLF_NCQ will be set to sata_tran_hba_features_support if the
1316 1316           * CAP register of the HBA indicates NCQ is supported.
1317 1317           *
1318 1318           * SATA_CTLF_NCQ cannot be set if AHCI_CAP_NO_MCMDLIST_NONQUEUE is
1319 1319           * set because the previous register content of PxCI can be re-written
1320 1320           * in the register write.
1321 1321           */
1322 1322          if ((cap_status & AHCI_HBA_CAP_SNCQ) &&
1323 1323              !(ahci_ctlp->ahcictl_cap & AHCI_CAP_NO_MCMDLIST_NONQUEUE)) {
1324 1324                  sata_hba_tran->sata_tran_hba_features_support |= SATA_CTLF_NCQ;
1325 1325                  ahci_ctlp->ahcictl_cap |= AHCI_CAP_NCQ;
1326 1326                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "HBA supports Native "
1327 1327                      "Command Queuing", NULL);
1328 1328          }
1329 1329  
1330 1330          /* Support port multiplier? */
1331 1331          if (cap_status & AHCI_HBA_CAP_SPM) {
1332 1332                  sata_hba_tran->sata_tran_hba_features_support |=
1333 1333                      SATA_CTLF_PORT_MULTIPLIER;
1334 1334  
1335 1335                  /* Support FIS-based switching for port multiplier? */
1336 1336                  if (cap_status & AHCI_HBA_CAP_FBSS) {
1337 1337                          sata_hba_tran->sata_tran_hba_features_support |=
1338 1338                              SATA_CTLF_PMULT_FBS;
1339 1339                  }
1340 1340          }
1341 1341  
1342 1342          /* Report the number of command slots */
1343 1343          sata_hba_tran->sata_tran_hba_qdepth = ahci_ctlp->ahcictl_num_cmd_slots;
1344 1344  
1345 1345          sata_hba_tran->sata_tran_probe_port = ahci_tran_probe_port;
1346 1346          sata_hba_tran->sata_tran_start = ahci_tran_start;
1347 1347          sata_hba_tran->sata_tran_abort = ahci_tran_abort;
1348 1348          sata_hba_tran->sata_tran_reset_dport = ahci_tran_reset_dport;
1349 1349          sata_hba_tran->sata_tran_hotplug_ops = &ahci_tran_hotplug_ops;
1350 1350  #ifdef __lock_lint
1351 1351          sata_hba_tran->sata_tran_selftest = ahci_selftest;
1352 1352  #endif
1353 1353          /*
1354 1354           * When SATA framework adds support for pwrmgt the
1355 1355           * pwrmgt_ops needs to be updated
1356 1356           */
1357 1357          sata_hba_tran->sata_tran_pwrmgt_ops = NULL;
1358 1358          sata_hba_tran->sata_tran_ioctl = ahci_em_ioctl;
1359 1359  
1360 1360          ahci_ctlp->ahcictl_sata_hba_tran = sata_hba_tran;
1361 1361  
1362 1362          mutex_exit(&ahci_ctlp->ahcictl_mutex);
1363 1363  
1364 1364          /* Attach it to SATA framework */
1365 1365          if (sata_hba_attach(ahci_ctlp->ahcictl_dip, sata_hba_tran, DDI_ATTACH)
1366 1366              != DDI_SUCCESS) {
1367 1367                  kmem_free((void *)sata_hba_tran, sizeof (sata_hba_tran_t));
1368 1368                  mutex_enter(&ahci_ctlp->ahcictl_mutex);
1369 1369                  ahci_ctlp->ahcictl_sata_hba_tran = NULL;
1370 1370                  mutex_exit(&ahci_ctlp->ahcictl_mutex);
1371 1371                  return (AHCI_FAILURE);
1372 1372          }
1373 1373  
1374 1374          return (AHCI_SUCCESS);
1375 1375  }
1376 1376  
1377 1377  /*
1378 1378   * Unregisters the ahci with sata framework.
1379 1379   */
1380 1380  static int
1381 1381  ahci_unregister_sata_hba_tran(ahci_ctl_t *ahci_ctlp)
1382 1382  {
1383 1383          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
1384 1384              "ahci_unregister_sata_hba_tran enter", NULL);
1385 1385  
1386 1386          /* Detach from the SATA framework. */
1387 1387          if (sata_hba_detach(ahci_ctlp->ahcictl_dip, DDI_DETACH) !=
1388 1388              DDI_SUCCESS) {
1389 1389                  return (AHCI_FAILURE);
1390 1390          }
1391 1391  
1392 1392          /* Deallocate sata_hba_tran. */
1393 1393          kmem_free((void *)ahci_ctlp->ahcictl_sata_hba_tran,
1394 1394              sizeof (sata_hba_tran_t));
1395 1395  
1396 1396          mutex_enter(&ahci_ctlp->ahcictl_mutex);
1397 1397          ahci_ctlp->ahcictl_sata_hba_tran = NULL;
1398 1398          mutex_exit(&ahci_ctlp->ahcictl_mutex);
1399 1399  
1400 1400          return (AHCI_SUCCESS);
1401 1401  }
1402 1402  
1403 1403  #define SET_PORTSTR(str, addrp)                                         \
1404 1404          if (AHCI_ADDR_IS_PORT(addrp))                                   \
1405 1405                  (void) sprintf((str), "%d", (addrp)->aa_port);          \
1406 1406          else if (AHCI_ADDR_IS_PMULT(addrp))                             \
1407 1407                  (void) sprintf((str), "%d (pmult)", (addrp)->aa_port);  \
1408 1408          else                                                            \
1409 1409                  (void) sprintf((str), "%d:%d", (addrp)->aa_port,        \
1410 1410                      (addrp)->aa_pmport);
1411 1411  
1412 1412  /*
1413 1413   * ahci_tran_probe_port is called by SATA framework. It returns port state,
1414 1414   * port status registers and an attached device type via sata_device
1415 1415   * structure.
1416 1416   *
1417 1417   * We return the cached information from a previous hardware probe. The
1418 1418   * actual hardware probing itself was done either from within
1419 1419   * ahci_initialize_controller() during the driver attach or from a phy
1420 1420   * ready change interrupt handler.
1421 1421   */
1422 1422  static int
1423 1423  ahci_tran_probe_port(dev_info_t *dip, sata_device_t *sd)
1424 1424  {
1425 1425          ahci_ctl_t *ahci_ctlp;
1426 1426          ahci_port_t *ahci_portp;
1427 1427          ahci_addr_t addr, pmult_addr;
1428 1428          uint8_t cport = sd->satadev_addr.cport;
1429 1429          char portstr[10];
1430 1430          uint8_t device_type;
1431 1431          uint32_t port_state;
1432 1432          uint8_t port;
1433 1433          int rval = SATA_SUCCESS, rval_init;
1434 1434  
1435 1435          port_state = 0;
1436 1436          ahci_ctlp = ddi_get_soft_state(ahci_statep, ddi_get_instance(dip));
1437 1437          port = ahci_ctlp->ahcictl_cport_to_port[cport];
1438 1438  
1439 1439          ahci_portp = ahci_ctlp->ahcictl_ports[port];
1440 1440  
1441 1441          mutex_enter(&ahci_portp->ahciport_mutex);
1442 1442  
1443 1443          ahci_get_ahci_addr(ahci_ctlp, sd, &addr);
1444 1444          ASSERT(AHCI_ADDR_IS_VALID(&addr));
1445 1445          SET_PORTSTR(portstr, &addr);
1446 1446  
1447 1447          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
1448 1448              "ahci_tran_probe_port enter: port %s", portstr);
1449 1449  
1450 1450          if ((AHCI_ADDR_IS_PMULT(&addr) || AHCI_ADDR_IS_PMPORT(&addr)) &&
1451 1451              (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT ||
1452 1452              ahci_portp->ahciport_pmult_info == NULL)) {
1453 1453                  /* port mutliplier is removed. */
1454 1454                  AHCIDBG(AHCIDBG_PMULT, ahci_ctlp,
1455 1455                      "ahci_tran_probe_port: "
1456 1456                      "pmult is removed from port %s", portstr);
1457 1457                  mutex_exit(&ahci_portp->ahciport_mutex);
1458 1458                  return (SATA_FAILURE);
1459 1459          }
1460 1460  
1461 1461          /*
1462 1462           * The sata_device may refer to
1463 1463           * 1. A controller port.
1464 1464           *    A controller port should be ready here.
1465 1465           * 2. A port multiplier.
1466 1466           *    SATA_ADDR_PMULT_SPEC - if it is not initialized yet, initialize
1467 1467           *    it and register the port multiplier to the framework.
1468 1468           *    SATA_ADDR_PMULT - check the status of all its device ports.
1469 1469           * 3. A port multiplier port.
1470 1470           *    If it has not been initialized, initialized it.
1471 1471           *
1472 1472           * A port multiplier or a port multiplier port may require some
1473 1473           * initialization because we cannot do these time-consuming jobs in an
1474 1474           * interrupt context.
1475 1475           */
1476 1476          if (sd->satadev_addr.qual & SATA_ADDR_PMULT_SPEC) {
1477 1477                  AHCI_ADDR_SET_PMULT(&pmult_addr, port);
1478 1478                  /* Initialize registers on a port multiplier */
1479 1479                  rval_init = ahci_initialize_pmult(ahci_ctlp,
1480 1480                      ahci_portp, &pmult_addr, sd);
1481 1481                  if (rval_init != AHCI_SUCCESS) {
1482 1482                          AHCIDBG(AHCIDBG_PMULT, ahci_ctlp,
1483 1483                              "ahci_tran_probe_port: "
1484 1484                              "pmult initialization failed.", NULL);
1485 1485                          mutex_exit(&ahci_portp->ahciport_mutex);
1486 1486                          return (SATA_FAILURE);
1487 1487                  }
1488 1488          } else if (sd->satadev_addr.qual & SATA_ADDR_PMULT) {
1489 1489                  /* Check pmports hotplug events */
1490 1490                  (void) ahci_probe_pmult(ahci_ctlp, ahci_portp, &addr);
1491 1491          } else if (sd->satadev_addr.qual & (SATA_ADDR_PMPORT |
1492 1492              SATA_ADDR_DPMPORT)) {
1493 1493                  if (ahci_probe_pmport(ahci_ctlp, ahci_portp,
1494 1494                      &addr, sd) != AHCI_SUCCESS) {
1495 1495                          rval = SATA_FAILURE;
1496 1496                          goto out;
1497 1497                  }
1498 1498          }
1499 1499  
1500 1500          /* Update port state and device type */
1501 1501          port_state = AHCIPORT_GET_STATE(ahci_portp, &addr);
1502 1502  
1503 1503          switch (port_state) {
1504 1504  
1505 1505          case SATA_PSTATE_FAILED:
1506 1506                  sd->satadev_state = SATA_PSTATE_FAILED;
1507 1507                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1508 1508                      "ahci_tran_probe_port: port %s PORT FAILED", portstr);
1509 1509                  goto out;
1510 1510  
1511 1511          case SATA_PSTATE_SHUTDOWN:
1512 1512                  sd->satadev_state = SATA_PSTATE_SHUTDOWN;
1513 1513                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1514 1514                      "ahci_tran_probe_port: port %s PORT SHUTDOWN", portstr);
1515 1515                  goto out;
1516 1516  
1517 1517          case SATA_PSTATE_PWROFF:
1518 1518                  sd->satadev_state = SATA_PSTATE_PWROFF;
1519 1519                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1520 1520                      "ahci_tran_probe_port: port %s PORT PWROFF", portstr);
1521 1521                  goto out;
1522 1522  
1523 1523          case SATA_PSTATE_PWRON:
1524 1524                  sd->satadev_state = SATA_PSTATE_PWRON;
1525 1525                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1526 1526                      "ahci_tran_probe_port: port %s PORT PWRON", portstr);
1527 1527                  break;
1528 1528  
1529 1529          default:
1530 1530                  sd->satadev_state = port_state;
1531 1531                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1532 1532                      "ahci_tran_probe_port: port %s PORT NORMAL %x",
1533 1533                      portstr, port_state);
1534 1534                  break;
1535 1535          }
1536 1536  
1537 1537          device_type = AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr);
1538 1538  
1539 1539          switch (device_type) {
1540 1540  
1541 1541          case SATA_DTYPE_ATADISK:
1542 1542                  sd->satadev_type = SATA_DTYPE_ATADISK;
1543 1543                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1544 1544                      "ahci_tran_probe_port: port %s DISK found", portstr);
1545 1545                  break;
1546 1546  
1547 1547          case SATA_DTYPE_ATAPI:
1548 1548                  /*
1549 1549                   * HBA driver only knows it's an ATAPI device, and don't know
1550 1550                   * it's CD/DVD, tape or ATAPI disk because the ATAPI device
1551 1551                   * type need to be determined by checking IDENTIFY PACKET
1552 1552                   * DEVICE data
1553 1553                   */
1554 1554                  sd->satadev_type = SATA_DTYPE_ATAPI;
1555 1555                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1556 1556                      "ahci_tran_probe_port: port %s ATAPI found", portstr);
1557 1557                  break;
1558 1558  
1559 1559          case SATA_DTYPE_PMULT:
1560 1560                  ASSERT(AHCI_ADDR_IS_PORT(&addr) || AHCI_ADDR_IS_PMULT(&addr));
1561 1561                  sd->satadev_type = SATA_DTYPE_PMULT;
1562 1562  
1563 1563                  /* Update the number of pmports. */
1564 1564                  ASSERT(ahci_portp->ahciport_pmult_info != NULL);
1565 1565                  sd->satadev_add_info = ahci_portp->
1566 1566                      ahciport_pmult_info->ahcipmi_num_dev_ports;
1567 1567  
1568 1568                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1569 1569                      "ahci_tran_probe_port: port %s Port Multiplier found",
1570 1570                      portstr);
1571 1571                  break;
1572 1572  
1573 1573          case SATA_DTYPE_UNKNOWN:
1574 1574                  sd->satadev_type = SATA_DTYPE_UNKNOWN;
1575 1575                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1576 1576                      "ahci_tran_probe_port: port %s Unknown device found",
1577 1577                      portstr);
1578 1578                  break;
1579 1579  
1580 1580          default:
1581 1581                  /* we don't support any other device types */
1582 1582                  sd->satadev_type = SATA_DTYPE_NONE;
1583 1583                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1584 1584                      "ahci_tran_probe_port: port %s No device found", portstr);
1585 1585                  break;
1586 1586          }
1587 1587  
1588 1588  out:
1589 1589          /* Register update only fails while probing a pmult/pmport */
1590 1590          if (AHCI_ADDR_IS_PORT(&addr) || AHCI_ADDR_IS_PMULT(&addr)) {
1591 1591                  ahci_update_sata_registers(ahci_ctlp, port, sd);
1592 1592          } else if (AHCI_ADDR_IS_PMPORT(&addr)) {
1593 1593                  if (port_state & SATA_STATE_READY)
1594 1594                          if (ahci_update_pmult_pscr(ahci_ctlp,
1595 1595                              &addr, sd) != AHCI_SUCCESS)
1596 1596                                  rval = SATA_FAILURE;
1597 1597          }
1598 1598  
1599 1599          /* Check handles for the sata registers access */
1600 1600          if ((ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) ||
1601 1601              (ahci_check_port_handle(ahci_ctlp, port) != DDI_SUCCESS)) {
1602 1602                  ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
1603 1603                      DDI_SERVICE_UNAFFECTED);
1604 1604                  rval = SATA_FAILURE;
1605 1605          }
1606 1606  
1607 1607          mutex_exit(&ahci_portp->ahciport_mutex);
1608 1608          return (rval);
1609 1609  }
1610 1610  
1611 1611  /*
1612 1612   * There are four operation modes in sata framework:
1613 1613   * SATA_OPMODE_INTERRUPTS
1614 1614   * SATA_OPMODE_POLLING
1615 1615   * SATA_OPMODE_ASYNCH
1616 1616   * SATA_OPMODE_SYNCH
1617 1617   *
1618 1618   * Their combined meanings as following:
1619 1619   *
1620 1620   * SATA_OPMODE_SYNCH
1621 1621   * The command has to be completed before sata_tran_start functions returns.
1622 1622   * Either interrupts or polling could be used - it's up to the driver.
1623 1623   * Mode used currently for internal, sata-module initiated operations.
1624 1624   *
1625 1625   * SATA_OPMODE_SYNCH | SATA_OPMODE_INTERRUPTS
1626 1626   * It is the same as the one above.
1627 1627   *
1628 1628   * SATA_OPMODE_SYNCH | SATA_OPMODE_POLLING
1629 1629   * The command has to be completed before sata_tran_start function returns.
1630 1630   * No interrupt used, polling only. This should be the mode used for scsi
1631 1631   * packets with FLAG_NOINTR.
1632 1632   *
1633 1633   * SATA_OPMODE_ASYNCH | SATA_OPMODE_INTERRUPTS
1634 1634   * The command may be queued (callback function specified). Interrupts could
1635 1635   * be used. It's normal operation mode.
1636 1636   */
1637 1637  /*
1638 1638   * Called by sata framework to transport a sata packet down stream.
1639 1639   */
1640 1640  static int
1641 1641  ahci_tran_start(dev_info_t *dip, sata_pkt_t *spkt)
1642 1642  {
1643 1643          ahci_ctl_t *ahci_ctlp;
1644 1644          ahci_port_t *ahci_portp;
1645 1645          ahci_addr_t addr;
1646 1646          uint8_t cport = spkt->satapkt_device.satadev_addr.cport;
1647 1647          uint8_t port;
1648 1648          char portstr[10];
1649 1649  
1650 1650          ahci_ctlp = ddi_get_soft_state(ahci_statep, ddi_get_instance(dip));
1651 1651          port = ahci_ctlp->ahcictl_cport_to_port[cport];
1652 1652  
1653 1653          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
1654 1654              "ahci_tran_start enter: cport %d satapkt 0x%p",
1655 1655              cport, (void *)spkt);
1656 1656  
1657 1657          ahci_portp = ahci_ctlp->ahcictl_ports[port];
1658 1658  
1659 1659          mutex_enter(&ahci_portp->ahciport_mutex);
1660 1660          ahci_get_ahci_addr(ahci_ctlp, &spkt->satapkt_device, &addr);
1661 1661          SET_PORTSTR(portstr, &addr);
1662 1662  
1663 1663          /* Sanity check */
1664 1664          if (AHCI_ADDR_IS_PMPORT(&addr)) {
1665 1665                  if (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT ||
1666 1666                      ahci_portp->ahciport_pmult_info == NULL) {
1667 1667  
1668 1668                          spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1669 1669                          spkt->satapkt_device.satadev_type = SATA_DTYPE_NONE;
1670 1670                          spkt->satapkt_device.satadev_state = SATA_STATE_UNKNOWN;
1671 1671                          ahci_update_sata_registers(ahci_ctlp, port,
1672 1672                              &spkt->satapkt_device);
1673 1673                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1674 1674                              "ahci_tran_start returning PORT_ERROR while "
1675 1675                              "pmult removed: port: %s", portstr);
1676 1676                          mutex_exit(&ahci_portp->ahciport_mutex);
1677 1677                          return (SATA_TRAN_PORT_ERROR);
1678 1678                  }
1679 1679  
1680 1680                  if (!(AHCIPORT_GET_STATE(ahci_portp, &addr) &
1681 1681                      SATA_STATE_READY)) {
1682 1682                          if (!ddi_in_panic() ||
1683 1683                              ahci_initialize_pmport(ahci_ctlp,
1684 1684                              ahci_portp, &addr) != AHCI_SUCCESS) {
1685 1685                                  spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1686 1686                                  spkt->satapkt_device.satadev_type =
1687 1687                                      AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr);
1688 1688                                  spkt->satapkt_device.satadev_state =
1689 1689                                      AHCIPORT_GET_STATE(ahci_portp, &addr);
1690 1690                                  ahci_update_sata_registers(ahci_ctlp, port,
1691 1691                                      &spkt->satapkt_device);
1692 1692                                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1693 1693                                      "ahci_tran_start returning PORT_ERROR "
1694 1694                                      "while sub-link is not initialized "
1695 1695                                      "at port: %s", portstr);
1696 1696                                  mutex_exit(&ahci_portp->ahciport_mutex);
1697 1697                                  return (SATA_TRAN_PORT_ERROR);
1698 1698                          }
1699 1699                  }
1700 1700          }
1701 1701  
1702 1702          if (AHCIPORT_GET_STATE(ahci_portp, &addr) & SATA_PSTATE_FAILED ||
1703 1703              AHCIPORT_GET_STATE(ahci_portp, &addr) & SATA_PSTATE_SHUTDOWN||
1704 1704              AHCIPORT_GET_STATE(ahci_portp, &addr) & SATA_PSTATE_PWROFF) {
1705 1705                  /*
1706 1706                   * In case the target driver would send the packet before
1707 1707                   * sata framework can have the opportunity to process those
1708 1708                   * event reports.
1709 1709                   */
1710 1710                  spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1711 1711                  spkt->satapkt_device.satadev_state =
1712 1712                      ahci_portp->ahciport_port_state;
1713 1713                  ahci_update_sata_registers(ahci_ctlp, port,
1714 1714                      &spkt->satapkt_device);
1715 1715                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1716 1716                      "ahci_tran_start returning PORT_ERROR while "
1717 1717                      "port in FAILED/SHUTDOWN/PWROFF state: "
1718 1718                      "port: %s", portstr);
1719 1719                  mutex_exit(&ahci_portp->ahciport_mutex);
1720 1720                  return (SATA_TRAN_PORT_ERROR);
1721 1721          }
1722 1722  
1723 1723          if (AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr) == SATA_DTYPE_NONE) {
1724 1724                  /*
1725 1725                   * ahci_intr_phyrdy_change() may have rendered it to
1726 1726                   * SATA_DTYPE_NONE.
1727 1727                   */
1728 1728                  spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1729 1729                  spkt->satapkt_device.satadev_type = SATA_DTYPE_NONE;
1730 1730                  spkt->satapkt_device.satadev_state =
1731 1731                      ahci_portp->ahciport_port_state;
1732 1732                  ahci_update_sata_registers(ahci_ctlp, port,
1733 1733                      &spkt->satapkt_device);
1734 1734                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1735 1735                      "ahci_tran_start returning PORT_ERROR while "
1736 1736                      "no device attached: port: %s", portstr);
1737 1737                  mutex_exit(&ahci_portp->ahciport_mutex);
1738 1738                  return (SATA_TRAN_PORT_ERROR);
1739 1739          }
1740 1740  
1741 1741          /* R/W PMULT command will occupy the whole HBA port */
1742 1742          if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
1743 1743                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1744 1744                      "ahci_tran_start returning BUSY while "
1745 1745                      "executing READ/WRITE PORT-MULT command: "
1746 1746                      "port: %s", portstr);
1747 1747                  spkt->satapkt_reason = SATA_PKT_BUSY;
1748 1748                  mutex_exit(&ahci_portp->ahciport_mutex);
1749 1749                  return (SATA_TRAN_BUSY);
1750 1750          }
1751 1751  
1752 1752          if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_HOTPLUG) {
1753 1753                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1754 1754                      "ahci_tran_start returning BUSY while "
1755 1755                      "hot-plug in progress: port: %s", portstr);
1756 1756                  spkt->satapkt_reason = SATA_PKT_BUSY;
1757 1757                  mutex_exit(&ahci_portp->ahciport_mutex);
1758 1758                  return (SATA_TRAN_BUSY);
1759 1759          }
1760 1760  
1761 1761          /*
1762 1762           * SATA HBA driver should remember that a device was reset and it
1763 1763           * is supposed to reject any packets which do not specify either
1764 1764           * SATA_IGNORE_DEV_RESET_STATE or SATA_CLEAR_DEV_RESET_STATE.
1765 1765           *
1766 1766           * This is to prevent a race condition when a device was arbitrarily
1767 1767           * reset by the HBA driver (and lost it's setting) and a target
1768 1768           * driver sending some commands to a device before the sata framework
1769 1769           * has a chance to restore the device setting (such as cache enable/
1770 1770           * disable or other resettable stuff).
1771 1771           */
1772 1772          /*
1773 1773           * It is unnecessary to use specific flags to indicate
1774 1774           * reset_in_progress for a pmport. While mopping, all command will be
1775 1775           * mopped so that the entire HBA port is being dealt as a single
1776 1776           * object.
1777 1777           */
1778 1778          if (spkt->satapkt_cmd.satacmd_flags.sata_clear_dev_reset) {
1779 1779                  ahci_portp->ahciport_reset_in_progress = 0;
1780 1780                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1781 1781                      "ahci_tran_start [CLEAR] the "
1782 1782                      "reset_in_progress for port: %d", port);
1783 1783          }
1784 1784  
1785 1785          if (ahci_portp->ahciport_reset_in_progress &&
1786 1786              ! spkt->satapkt_cmd.satacmd_flags.sata_ignore_dev_reset &&
1787 1787              ! ddi_in_panic()) {
1788 1788                  spkt->satapkt_reason = SATA_PKT_BUSY;
1789 1789                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1790 1790                      "ahci_tran_start returning BUSY while "
1791 1791                      "reset in progress: port: %d", port);
1792 1792                  mutex_exit(&ahci_portp->ahciport_mutex);
1793 1793                  return (SATA_TRAN_BUSY);
1794 1794          }
1795 1795  
1796 1796  #ifdef AHCI_DEBUG
1797 1797          if (spkt->satapkt_cmd.satacmd_flags.sata_ignore_dev_reset) {
1798 1798                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1799 1799                      "ahci_tran_start: packet 0x%p [PASSTHRU] at port %d",
1800 1800                      spkt, port);
1801 1801          }
1802 1802  #endif
1803 1803  
1804 1804          if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
1805 1805                  spkt->satapkt_reason = SATA_PKT_BUSY;
1806 1806                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1807 1807                      "ahci_tran_start returning BUSY while "
1808 1808                      "mopping in progress: port: %d", port);
1809 1809                  mutex_exit(&ahci_portp->ahciport_mutex);
1810 1810                  return (SATA_TRAN_BUSY);
1811 1811          }
1812 1812  
1813 1813          if (ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) {
1814 1814                  ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
1815 1815                      DDI_SERVICE_UNAFFECTED);
1816 1816                  mutex_exit(&ahci_portp->ahciport_mutex);
1817 1817                  return (SATA_TRAN_BUSY);
1818 1818          }
1819 1819  
1820 1820          if (spkt->satapkt_op_mode &
1821 1821              (SATA_OPMODE_SYNCH | SATA_OPMODE_POLLING)) {
1822 1822                  /*
1823 1823                   * If a SYNC command to be executed in interrupt context,
1824 1824                   * bounce it back to sata module.
1825 1825                   */
1826 1826                  if (!(spkt->satapkt_op_mode & SATA_OPMODE_POLLING) &&
1827 1827                      servicing_interrupt()) {
1828 1828                          spkt->satapkt_reason = SATA_PKT_BUSY;
1829 1829                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1830 1830                              "ahci_tran_start returning BUSY while "
1831 1831                              "sending SYNC mode under interrupt context: "
1832 1832                              "port : %d", port);
1833 1833                          mutex_exit(&ahci_portp->ahciport_mutex);
1834 1834                          return (SATA_TRAN_BUSY);
1835 1835                  }
1836 1836  
1837 1837                  /* We need to do the sync start now */
1838 1838                  if (ahci_do_sync_start(ahci_ctlp, ahci_portp, &addr,
1839 1839                      spkt) == AHCI_FAILURE) {
1840 1840                          goto fail_out;
1841 1841                  }
1842 1842          } else {
1843 1843                  /* Async start, using interrupt */
1844 1844                  if (ahci_deliver_satapkt(ahci_ctlp, ahci_portp, &addr, spkt)
1845 1845                      == AHCI_FAILURE) {
1846 1846                          spkt->satapkt_reason = SATA_PKT_QUEUE_FULL;
1847 1847                          goto fail_out;
1848 1848                  }
1849 1849          }
1850 1850  
1851 1851          AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "ahci_tran_start "
1852 1852              "sata tran accepted: port %s", portstr);
1853 1853  
1854 1854          mutex_exit(&ahci_portp->ahciport_mutex);
1855 1855          return (SATA_TRAN_ACCEPTED);
1856 1856  
1857 1857  fail_out:
1858 1858          /*
1859 1859           * Failed to deliver packet to the controller.
1860 1860           * Check if it's caused by invalid handles.
1861 1861           */
1862 1862          if (ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS ||
1863 1863              ahci_check_port_handle(ahci_ctlp, port) != DDI_SUCCESS) {
1864 1864                  spkt->satapkt_device.satadev_type =
1865 1865                      AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr);
1866 1866                  spkt->satapkt_device.satadev_state =
1867 1867                      AHCIPORT_GET_STATE(ahci_portp, &addr);
1868 1868                  spkt->satapkt_reason = SATA_PKT_DEV_ERROR;
1869 1869                  mutex_exit(&ahci_portp->ahciport_mutex);
1870 1870                  return (SATA_TRAN_PORT_ERROR);
1871 1871          }
1872 1872  
1873 1873          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_tran_start "
1874 1874              "return QUEUE_FULL: port %d", port);
1875 1875          mutex_exit(&ahci_portp->ahciport_mutex);
1876 1876          return (SATA_TRAN_QUEUE_FULL);
1877 1877  }
1878 1878  
1879 1879  /*
1880 1880   * SATA_OPMODE_SYNCH flag is set
1881 1881   *
1882 1882   * If SATA_OPMODE_POLLING flag is set, then we must poll the command
1883 1883   * without interrupt, otherwise we can still use the interrupt.
1884 1884   */
1885 1885  static int
1886 1886  ahci_do_sync_start(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
1887 1887      ahci_addr_t *addrp, sata_pkt_t *spkt)
1888 1888  {
1889 1889          int pkt_timeout_ticks;
1890 1890          uint32_t timeout_tags;
1891 1891          int rval;
1892 1892          int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
1893 1893          uint8_t port = addrp->aa_port;
1894 1894  
1895 1895          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
1896 1896  
1897 1897          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_do_sync_start enter: "
1898 1898              "port %d:%d spkt 0x%p", port, addrp->aa_pmport, spkt);
1899 1899  
1900 1900          if (spkt->satapkt_op_mode & SATA_OPMODE_POLLING) {
1901 1901                  ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_POLLING;
1902 1902                  if ((rval = ahci_deliver_satapkt(ahci_ctlp, ahci_portp,
1903 1903                      addrp, spkt)) == AHCI_FAILURE) {
1904 1904                          ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_POLLING;
1905 1905                          return (rval);
1906 1906                  }
1907 1907  
1908 1908                  pkt_timeout_ticks =
1909 1909                      drv_usectohz((clock_t)spkt->satapkt_time * 1000000);
1910 1910  
1911 1911                  while (spkt->satapkt_reason == SATA_PKT_BUSY) {
1912 1912                          /* Simulate the interrupt */
1913 1913                          mutex_exit(&ahci_portp->ahciport_mutex);
1914 1914                          ahci_port_intr(ahci_ctlp, ahci_portp, port);
1915 1915                          mutex_enter(&ahci_portp->ahciport_mutex);
1916 1916  
1917 1917                          if (spkt->satapkt_reason != SATA_PKT_BUSY)
1918 1918                                  break;
1919 1919  
1920 1920                          mutex_exit(&ahci_portp->ahciport_mutex);
1921 1921                          drv_usecwait(AHCI_1MS_USECS);
1922 1922                          mutex_enter(&ahci_portp->ahciport_mutex);
1923 1923  
1924 1924                          pkt_timeout_ticks -= AHCI_1MS_TICKS;
1925 1925                          if (pkt_timeout_ticks < 0) {
1926 1926                                  cmn_err(CE_WARN, "!ahci%d: ahci_do_sync_start "
1927 1927                                      "port %d satapkt 0x%p timed out\n",
1928 1928                                      instance, port, (void *)spkt);
1929 1929                                  timeout_tags = (0x1 << rval);
1930 1930                                  mutex_exit(&ahci_portp->ahciport_mutex);
1931 1931                                  ahci_timeout_pkts(ahci_ctlp, ahci_portp,
1932 1932                                      port, timeout_tags);
1933 1933                                  mutex_enter(&ahci_portp->ahciport_mutex);
1934 1934                          }
1935 1935                  }
1936 1936  
1937 1937                  ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_POLLING;
1938 1938                  return (AHCI_SUCCESS);
1939 1939  
1940 1940          } else {
1941 1941                  if ((rval = ahci_deliver_satapkt(ahci_ctlp, ahci_portp,
1942 1942                      addrp, spkt)) == AHCI_FAILURE)
1943 1943                          return (rval);
1944 1944  
1945 1945  #if AHCI_DEBUG
1946 1946                  /*
1947 1947                   * Note that the driver always uses the slot 0 to deliver
1948 1948                   * REQUEST SENSE or READ LOG EXT command
1949 1949                   */
1950 1950                  if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
1951 1951                          ASSERT(rval == 0);
1952 1952  #endif
1953 1953  
1954 1954                  while (spkt->satapkt_reason == SATA_PKT_BUSY)
1955 1955                          cv_wait(&ahci_portp->ahciport_cv,
1956 1956                              &ahci_portp->ahciport_mutex);
1957 1957  
1958 1958                  return (AHCI_SUCCESS);
1959 1959          }
1960 1960  }
1961 1961  
1962 1962  /*
1963 1963   * Searches for and claims a free command slot.
1964 1964   *
1965 1965   * Returns value:
1966 1966   *
1967 1967   * AHCI_FAILURE returned only if
1968 1968   *      1. No empty slot left
1969 1969   *      2. Non-queued command requested while queued command(s) is outstanding
1970 1970   *      3. Queued command requested while non-queued command(s) is outstanding
1971 1971   *      4. HBA doesn't support multiple-use of command list while already a
1972 1972   *         non-queued command is oustanding
1973 1973   *      5. Queued command requested while some queued command(s) has been
1974 1974   *         outstanding on a different port multiplier port. (AHCI spec 1.2,
1975 1975   *         9.1.2)
1976 1976   *
1977 1977   * claimed slot number returned if succeeded
1978 1978   *
1979 1979   * NOTE: it will always return slot 0 for following commands to simplify the
1980 1980   * algorithm.
1981 1981   *      1. REQUEST SENSE or READ LOG EXT command during error recovery process
1982 1982   *      2. READ/WRITE PORTMULT command
1983 1983   */
1984 1984  static int
1985 1985  ahci_claim_free_slot(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
1986 1986      ahci_addr_t *addrp, int command_type)
1987 1987  {
1988 1988          uint32_t port_cmd_issue;
1989 1989          uint32_t free_slots;
1990 1990          int slot;
1991 1991  
1992 1992          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
1993 1993  
1994 1994          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_claim_free_slot enter "
1995 1995              "ahciport_pending_tags = 0x%x "
1996 1996              "ahciport_pending_ncq_tags = 0x%x",
1997 1997              ahci_portp->ahciport_pending_tags,
1998 1998              ahci_portp->ahciport_pending_ncq_tags);
1999 1999  
2000 2000          free_slots = 0;
2001 2001          /*
2002 2002           * According to the AHCI spec, system software is responsible to
2003 2003           * ensure that queued and non-queued commands are not mixed in
2004 2004           * the command list.
2005 2005           */
2006 2006          if (command_type == AHCI_NON_NCQ_CMD) {
2007 2007                  /* Non-NCQ command request */
2008 2008                  if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2009 2009                          AHCIDBG(AHCIDBG_INFO|AHCIDBG_NCQ, ahci_ctlp,
2010 2010                              "ahci_claim_free_slot: there is still pending "
2011 2011                              "queued command(s) in the command list, "
2012 2012                              "so no available slot for the non-queued "
2013 2013                              "command", NULL);
2014 2014                          return (AHCI_FAILURE);
2015 2015                  }
2016 2016                  if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
2017 2017                          AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
2018 2018                              "ahci_claim_free_slot: there is still pending "
2019 2019                              "read/write port-mult command(s) in command list, "
2020 2020                              "so no available slot for the non-queued command",
2021 2021                              NULL);
2022 2022                          return (AHCI_FAILURE);
2023 2023                  }
2024 2024                  if ((ahci_ctlp->ahcictl_cap & AHCI_CAP_NO_MCMDLIST_NONQUEUE) &&
2025 2025                      NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2026 2026                          AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2027 2027                              "ahci_claim_free_slot: HBA cannot support multiple-"
2028 2028                              "use of the command list for non-queued commands",
2029 2029                              NULL);
2030 2030                          return (AHCI_FAILURE);
2031 2031                  }
2032 2032                  free_slots = (~ahci_portp->ahciport_pending_tags) &
2033 2033                      AHCI_SLOT_MASK(ahci_ctlp);
2034 2034          } else if (command_type == AHCI_NCQ_CMD) {
2035 2035                  /* NCQ command request */
2036 2036                  if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2037 2037                          AHCIDBG(AHCIDBG_INFO|AHCIDBG_NCQ, ahci_ctlp,
2038 2038                              "ahci_claim_free_slot: there is still pending "
2039 2039                              "non-queued command(s) in the command list, "
2040 2040                              "so no available slot for the queued command",
2041 2041                              NULL);
2042 2042                          return (AHCI_FAILURE);
2043 2043                  }
2044 2044  
2045 2045                  /*
2046 2046                   * NCQ commands cannot be sent to different port multiplier
2047 2047                   * ports in Command-Based Switching mode
2048 2048                   */
2049 2049                  /*
2050 2050                   * NOTE: In Command-Based Switching mode, AHCI controller
2051 2051                   * usually reports a 'Handshake Error' when multiple NCQ
2052 2052                   * commands are outstanding simultaneously.
2053 2053                   */
2054 2054                  if (AHCIPORT_DEV_TYPE(ahci_portp, addrp) == SATA_DTYPE_PMULT) {
2055 2055                          ASSERT(ahci_portp->ahciport_pmult_info != NULL);
2056 2056                          if (!(ahci_ctlp->ahcictl_cap & AHCI_CAP_PMULT_FBSS) &&
2057 2057                              NCQ_CMD_IN_PROGRESS(ahci_portp) &&
2058 2058                              AHCIPORT_NCQ_PMPORT(ahci_portp) !=
2059 2059                              addrp->aa_pmport) {
2060 2060                                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2061 2061                                      "ahci_claim_free_slot: there is still "
2062 2062                                      "pending queued command(s) in the "
2063 2063                                      "command list for another Port Multiplier "
2064 2064                                      "port, so no available slot.", NULL);
2065 2065                                  return (AHCI_FAILURE);
2066 2066                          }
2067 2067                  }
2068 2068  
2069 2069                  free_slots = (~ahci_portp->ahciport_pending_ncq_tags) &
2070 2070                      AHCI_NCQ_SLOT_MASK(ahci_portp);
2071 2071          } else if (command_type == AHCI_ERR_RETRI_CMD) {
2072 2072                  /* Error retrieval command request */
2073 2073                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2074 2074                      "ahci_claim_free_slot: slot 0 is allocated for REQUEST "
2075 2075                      "SENSE or READ LOG EXT command", NULL);
2076 2076                  slot = 0;
2077 2077                  goto out;
2078 2078          } else if (command_type == AHCI_RDWR_PMULT_CMD) {
2079 2079                  /*
2080 2080                   * An extra check on PxCI. Sometimes PxCI bits may not be
2081 2081                   * cleared during hot-plug or error recovery process.
2082 2082                   */
2083 2083                  port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2084 2084                      (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, addrp->aa_port));
2085 2085  
2086 2086                  if (port_cmd_issue != 0) {
2087 2087                          AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
2088 2088                              "ahci_claim_free_slot: there is still pending "
2089 2089                              "command(s) in command list (0x%x/0x%x, PxCI %x),"
2090 2090                              "so no available slot for R/W PMULT command.",
2091 2091                              NON_NCQ_CMD_IN_PROGRESS(ahci_portp),
2092 2092                              NCQ_CMD_IN_PROGRESS(ahci_portp),
2093 2093                              port_cmd_issue);
2094 2094                          return (AHCI_FAILURE);
2095 2095                  }
2096 2096  
2097 2097                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2098 2098                      "ahci_claim_free_slot: slot 0 is allocated for "
2099 2099                      "READ/WRITE PORTMULT command", NULL);
2100 2100                  slot = 0;
2101 2101                  goto out;
2102 2102          }
2103 2103  
2104 2104          slot = ddi_ffs(free_slots) - 1;
2105 2105          if (slot == -1) {
2106 2106                  AHCIDBG(AHCIDBG_VERBOSE, ahci_ctlp,
2107 2107                      "ahci_claim_free_slot: no empty slots", NULL);
2108 2108                  return (AHCI_FAILURE);
2109 2109          }
2110 2110  
2111 2111          /*
2112 2112           * According to the AHCI spec, to allow a simple mechanism for the
2113 2113           * HBA to map command list slots to queue entries, software must
2114 2114           * match the tag number it uses to the slot it is placing the command
2115 2115           * in. For example, if a queued command is placed in slot 5, the tag
2116 2116           * for that command must be 5.
2117 2117           */
2118 2118          if (command_type == AHCI_NCQ_CMD) {
2119 2119                  ahci_portp->ahciport_pending_ncq_tags |= (0x1 << slot);
2120 2120                  if (AHCI_ADDR_IS_PMPORT(addrp)) {
2121 2121                          ASSERT(ahci_portp->ahciport_pmult_info != NULL);
2122 2122                          AHCIPORT_NCQ_PMPORT(ahci_portp) = addrp->aa_pmport;
2123 2123                  }
2124 2124          }
2125 2125  
2126 2126          ahci_portp->ahciport_pending_tags |= (0x1 << slot);
2127 2127  
2128 2128  out:
2129 2129          AHCIDBG(AHCIDBG_VERBOSE, ahci_ctlp,
2130 2130              "ahci_claim_free_slot: found slot: 0x%x", slot);
2131 2131  
2132 2132          return (slot);
2133 2133  }
2134 2134  
2135 2135  /*
2136 2136   * Builds the Command Table for the sata packet and delivers it to controller.
2137 2137   *
2138 2138   * Returns:
2139 2139   *      slot number if we can obtain a slot successfully
2140 2140   *      otherwise, return AHCI_FAILURE
2141 2141   */
2142 2142  static int
2143 2143  ahci_deliver_satapkt(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
2144 2144      ahci_addr_t *addrp, sata_pkt_t *spkt)
2145 2145  {
2146 2146          int cmd_slot;
2147 2147          sata_cmd_t *scmd;
2148 2148          ahci_fis_h2d_register_t *h2d_register_fisp;
2149 2149          ahci_cmd_table_t *cmd_table;
2150 2150          ahci_cmd_header_t *cmd_header;
2151 2151          int ncookies;
2152 2152          int i;
2153 2153          int command_type = AHCI_NON_NCQ_CMD;
2154 2154          int ncq_qdepth;
2155 2155          int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
2156 2156          uint8_t port, pmport;
2157 2157  #if AHCI_DEBUG
2158 2158          uint32_t *ptr;
2159 2159          uint8_t *ptr2;
2160 2160  #endif
2161 2161  
2162 2162          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
2163 2163  
2164 2164          port = addrp->aa_port;
2165 2165          pmport = addrp->aa_pmport;
2166 2166  
2167 2167          spkt->satapkt_reason = SATA_PKT_BUSY;
2168 2168  
2169 2169          scmd = &spkt->satapkt_cmd;
2170 2170  
2171 2171          /* Check if the command is a NCQ command */
2172 2172          if (scmd->satacmd_cmd_reg == SATAC_READ_FPDMA_QUEUED ||
2173 2173              scmd->satacmd_cmd_reg == SATAC_WRITE_FPDMA_QUEUED) {
2174 2174                  command_type = AHCI_NCQ_CMD;
2175 2175  
2176 2176                  /*
2177 2177                   * When NCQ is support, system software must determine the
2178 2178                   * maximum tag allowed by the device and the HBA, and it
2179 2179                   * must use a value not beyond of the lower bound of the two.
2180 2180                   *
2181 2181                   * Sata module is going to calculate the qdepth and send
2182 2182                   * down to HBA driver via sata_cmd.
2183 2183                   */
2184 2184                  ncq_qdepth = scmd->satacmd_flags.sata_max_queue_depth + 1;
2185 2185  
2186 2186                  /*
2187 2187                   * At the moment, the driver doesn't support the dynamic
2188 2188                   * setting of the maximum ncq depth, and the value can be
2189 2189                   * set either during the attach or after hot-plug insertion.
2190 2190                   */
2191 2191                  if (ahci_portp->ahciport_max_ncq_tags == 0) {
2192 2192                          ahci_portp->ahciport_max_ncq_tags = ncq_qdepth;
2193 2193                          AHCIDBG(AHCIDBG_NCQ, ahci_ctlp,
2194 2194                              "ahci_deliver_satapkt: port %d the max tags for "
2195 2195                              "NCQ command is %d", port, ncq_qdepth);
2196 2196                  } else {
2197 2197                          if (ncq_qdepth != ahci_portp->ahciport_max_ncq_tags) {
2198 2198                                  cmn_err(CE_WARN, "!ahci%d: ahci_deliver_satapkt"
2199 2199                                      " port %d the max tag for NCQ command is "
2200 2200                                      "requested to change from %d to %d, at the"
2201 2201                                      " moment the driver doesn't support the "
2202 2202                                      "dynamic change so it's going to "
2203 2203                                      "still use the previous tag value",
2204 2204                                      instance, port,
2205 2205                                      ahci_portp->ahciport_max_ncq_tags,
2206 2206                                      ncq_qdepth);
2207 2207                          }
2208 2208                  }
2209 2209          }
2210 2210  
2211 2211          /* Check if the command is an error retrieval command */
2212 2212          if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
2213 2213                  command_type = AHCI_ERR_RETRI_CMD;
2214 2214  
2215 2215          /* Check if the command is an read/write pmult command */
2216 2216          if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp))
2217 2217                  command_type = AHCI_RDWR_PMULT_CMD;
2218 2218  
2219 2219          /* Check if there is an empty command slot */
2220 2220          cmd_slot = ahci_claim_free_slot(ahci_ctlp, ahci_portp,
2221 2221              addrp, command_type);
2222 2222          if (cmd_slot == AHCI_FAILURE) {
2223 2223                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "no free command slot", NULL);
2224 2224                  return (AHCI_FAILURE);
2225 2225          }
2226 2226  
2227 2227          AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INFO, ahci_ctlp,
2228 2228              "ahci_deliver_satapkt enter: cmd_reg: 0x%x, cmd_slot: 0x%x, "
2229 2229              "port: %d, satapkt: 0x%p", scmd->satacmd_cmd_reg,
2230 2230              cmd_slot, port, (void *)spkt);
2231 2231  
2232 2232          cmd_table = ahci_portp->ahciport_cmd_tables[cmd_slot];
2233 2233          bzero((void *)cmd_table, ahci_cmd_table_size);
2234 2234  
2235 2235          /* For data transfer operations, it is the H2D Register FIS */
2236 2236          h2d_register_fisp =
2237 2237              &(cmd_table->ahcict_command_fis.ahcifc_fis.ahcifc_h2d_register);
2238 2238  
2239 2239          SET_FIS_TYPE(h2d_register_fisp, AHCI_H2D_REGISTER_FIS_TYPE);
2240 2240  
2241 2241          /*
2242 2242           * PMP field only make sense when target is a port multiplier or a
2243 2243           * device behind a port multiplier. Otherwise should set it to 0.
2244 2244           */
2245 2245          if (AHCI_ADDR_IS_PMULT(addrp) || AHCI_ADDR_IS_PMPORT(addrp))
2246 2246                  SET_FIS_PMP(h2d_register_fisp, pmport);
2247 2247  
2248 2248          SET_FIS_CDMDEVCTL(h2d_register_fisp, 1);
2249 2249          SET_FIS_COMMAND(h2d_register_fisp, scmd->satacmd_cmd_reg);
2250 2250          SET_FIS_FEATURES(h2d_register_fisp, scmd->satacmd_features_reg);
2251 2251          SET_FIS_SECTOR_COUNT(h2d_register_fisp, scmd->satacmd_sec_count_lsb);
2252 2252  
2253 2253          switch (scmd->satacmd_addr_type) {
2254 2254  
2255 2255          case 0:
2256 2256                  /*
2257 2257                   * satacmd_addr_type will be 0 for the commands below:
2258 2258                   *      ATAPI command
2259 2259                   *      SATAC_IDLE_IM
2260 2260                   *      SATAC_STANDBY_IM
2261 2261                   *      SATAC_DOWNLOAD_MICROCODE
2262 2262                   *      SATAC_FLUSH_CACHE
2263 2263                   *      SATAC_SET_FEATURES
2264 2264                   *      SATAC_SMART
2265 2265                   *      SATAC_ID_PACKET_DEVICE
2266 2266                   *      SATAC_ID_DEVICE
2267 2267                   *      SATAC_READ_PORTMULT
2268 2268                   *      SATAC_WRITE_PORTMULT
2269 2269                   */
2270 2270                  /* FALLTHRU */
2271 2271  
2272 2272          case ATA_ADDR_LBA:
2273 2273                  /* FALLTHRU */
2274 2274  
2275 2275          case ATA_ADDR_LBA28:
2276 2276                  /* LBA[7:0] */
2277 2277                  SET_FIS_SECTOR(h2d_register_fisp, scmd->satacmd_lba_low_lsb);
2278 2278  
2279 2279                  /* LBA[15:8] */
2280 2280                  SET_FIS_CYL_LOW(h2d_register_fisp, scmd->satacmd_lba_mid_lsb);
2281 2281  
2282 2282                  /* LBA[23:16] */
2283 2283                  SET_FIS_CYL_HI(h2d_register_fisp, scmd->satacmd_lba_high_lsb);
2284 2284  
2285 2285                  /* LBA [27:24] (also called dev_head) */
2286 2286                  SET_FIS_DEV_HEAD(h2d_register_fisp, scmd->satacmd_device_reg);
2287 2287  
2288 2288                  break;
2289 2289  
2290 2290          case ATA_ADDR_LBA48:
2291 2291                  /* LBA[7:0] */
2292 2292                  SET_FIS_SECTOR(h2d_register_fisp, scmd->satacmd_lba_low_lsb);
2293 2293  
2294 2294                  /* LBA[15:8] */
2295 2295                  SET_FIS_CYL_LOW(h2d_register_fisp, scmd->satacmd_lba_mid_lsb);
2296 2296  
2297 2297                  /* LBA[23:16] */
2298 2298                  SET_FIS_CYL_HI(h2d_register_fisp, scmd->satacmd_lba_high_lsb);
2299 2299  
2300 2300                  /* LBA [31:24] */
2301 2301                  SET_FIS_SECTOR_EXP(h2d_register_fisp,
2302 2302                      scmd->satacmd_lba_low_msb);
2303 2303  
2304 2304                  /* LBA [39:32] */
2305 2305                  SET_FIS_CYL_LOW_EXP(h2d_register_fisp,
2306 2306                      scmd->satacmd_lba_mid_msb);
2307 2307  
2308 2308                  /* LBA [47:40] */
2309 2309                  SET_FIS_CYL_HI_EXP(h2d_register_fisp,
2310 2310                      scmd->satacmd_lba_high_msb);
2311 2311  
2312 2312                  /* Set dev_head */
2313 2313                  SET_FIS_DEV_HEAD(h2d_register_fisp,
2314 2314                      scmd->satacmd_device_reg);
2315 2315  
2316 2316                  /* Set the extended sector count and features */
2317 2317                  SET_FIS_SECTOR_COUNT_EXP(h2d_register_fisp,
2318 2318                      scmd->satacmd_sec_count_msb);
2319 2319                  SET_FIS_FEATURES_EXP(h2d_register_fisp,
2320 2320                      scmd->satacmd_features_reg_ext);
2321 2321                  break;
2322 2322          }
2323 2323  
2324 2324          /*
2325 2325           * For NCQ command (READ/WRITE FPDMA QUEUED), sector count 7:0 is
2326 2326           * filled into features field, and sector count 8:15 is filled into
2327 2327           * features (exp) field. The hba driver doesn't need to anything
2328 2328           * special with regard to this, since sata framework has already
2329 2329           * done so.
2330 2330           *
2331 2331           * However the driver needs to make sure TAG is filled into sector
2332 2332           * field.
2333 2333           */
2334 2334          if (command_type == AHCI_NCQ_CMD) {
2335 2335                  SET_FIS_SECTOR_COUNT(h2d_register_fisp,
2336 2336                      (cmd_slot << SATA_TAG_QUEUING_SHIFT));
2337 2337          }
2338 2338  
2339 2339          ncookies = scmd->satacmd_num_dma_cookies;
2340 2340          AHCIDBG(AHCIDBG_PRDT, ahci_ctlp,
2341 2341              "ncookies = 0x%x, ahci_dma_prdt_number = 0x%x",
2342 2342              ncookies, ahci_dma_prdt_number);
2343 2343  
2344 2344          ASSERT(ncookies <= ahci_dma_prdt_number);
2345 2345          ahci_portp->ahciport_prd_bytecounts[cmd_slot] = 0;
2346 2346  
2347 2347          /* *** now fill the scatter gather list ******* */
2348 2348          for (i = 0; i < ncookies; i++) {
2349 2349                  cmd_table->ahcict_prdt[i].ahcipi_data_base_addr =
2350 2350                      scmd->satacmd_dma_cookie_list[i]._dmu._dmac_la[0];
2351 2351                  cmd_table->ahcict_prdt[i].ahcipi_data_base_addr_upper =
2352 2352                      scmd->satacmd_dma_cookie_list[i]._dmu._dmac_la[1];
2353 2353                  cmd_table->ahcict_prdt[i].ahcipi_descr_info =
2354 2354                      scmd->satacmd_dma_cookie_list[i].dmac_size - 1;
2355 2355                  ahci_portp->ahciport_prd_bytecounts[cmd_slot] +=
2356 2356                      scmd->satacmd_dma_cookie_list[i].dmac_size;
2357 2357          }
2358 2358  
2359 2359          AHCIDBG(AHCIDBG_PRDT, ahci_ctlp,
2360 2360              "ahciport_prd_bytecounts 0x%x for cmd_slot 0x%x",
2361 2361              ahci_portp->ahciport_prd_bytecounts[cmd_slot], cmd_slot);
2362 2362  
2363 2363          /* The ACMD field is filled in for ATAPI command */
2364 2364          if (scmd->satacmd_cmd_reg == SATAC_PACKET) {
2365 2365                  bcopy(scmd->satacmd_acdb, cmd_table->ahcict_atapi_cmd,
2366 2366                      SATA_ATAPI_MAX_CDB_LEN);
2367 2367          }
2368 2368  
2369 2369          /* Set Command Header in Command List */
2370 2370          cmd_header = &ahci_portp->ahciport_cmd_list[cmd_slot];
2371 2371          BZERO_DESCR_INFO(cmd_header);
2372 2372          BZERO_PRD_BYTE_COUNT(cmd_header);
2373 2373  
2374 2374          /* Set the number of entries in the PRD table */
2375 2375          SET_PRD_TABLE_LENGTH(cmd_header, ncookies);
2376 2376  
2377 2377          /* Set the length of the command in the CFIS area */
2378 2378          SET_COMMAND_FIS_LENGTH(cmd_header, AHCI_H2D_REGISTER_FIS_LENGTH);
2379 2379  
2380 2380          /*
2381 2381           * PMP field only make sense when target is a port multiplier or a
2382 2382           * device behind a port multiplier. Otherwise should set it to 0.
2383 2383           */
2384 2384          if (AHCI_ADDR_IS_PMULT(addrp) || AHCI_ADDR_IS_PMPORT(addrp))
2385 2385                  SET_PORT_MULTI_PORT(cmd_header, pmport);
2386 2386  
2387 2387          AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "command data direction is "
2388 2388              "sata_data_direction = 0x%x",
2389 2389              scmd->satacmd_flags.sata_data_direction);
2390 2390  
2391 2391          /* Set A bit if it is an ATAPI command */
2392 2392          if (scmd->satacmd_cmd_reg == SATAC_PACKET)
2393 2393                  SET_ATAPI(cmd_header, AHCI_CMDHEAD_ATAPI);
2394 2394  
2395 2395          /* Set W bit if data is going to the device */
2396 2396          if (scmd->satacmd_flags.sata_data_direction == SATA_DIR_WRITE)
2397 2397                  SET_WRITE(cmd_header, AHCI_CMDHEAD_DATA_WRITE);
2398 2398  
2399 2399          /*
2400 2400           * Set the prefetchable bit - this bit is only valid if the PRDTL
2401 2401           * field is non-zero or the ATAPI 'A' bit is set in the command
2402 2402           * header. This bit cannot be set when using native command
2403 2403           * queuing commands or when using FIS-based switching with a Port
2404 2404           * multiplier.
2405 2405           */
2406 2406          if (command_type != AHCI_NCQ_CMD)
2407 2407                  SET_PREFETCHABLE(cmd_header, AHCI_CMDHEAD_PREFETCHABLE);
2408 2408  
2409 2409          /*
2410 2410           * Now remember the sata packet in ahciport_slot_pkts[].
2411 2411           * Error retrieval command and r/w port multiplier command will
2412 2412           * be stored specifically for each port.
2413 2413           */
2414 2414          if (!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&
2415 2415              !RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp))
2416 2416                  ahci_portp->ahciport_slot_pkts[cmd_slot] = spkt;
2417 2417  
2418 2418          /*
2419 2419           * Keep the timeout value
2420 2420           */
2421 2421          ahci_portp->ahciport_slot_timeout[cmd_slot] = spkt->satapkt_time;
2422 2422  
2423 2423          /*
2424 2424           * If the intial timout is less than 1 tick, then make it longer by
2425 2425           * 1 tick to avoid immediate timeout
2426 2426           */
2427 2427          if (ahci_portp->ahciport_slot_timeout[cmd_slot] <=
2428 2428              ahci_watchdog_timeout)
2429 2429                  ahci_portp->ahciport_slot_timeout[cmd_slot] +=
2430 2430                      ahci_watchdog_timeout;
2431 2431  
2432 2432  #if AHCI_DEBUG
2433 2433          if (ahci_debug_flags & AHCIDBG_ATACMD &&
2434 2434              scmd->satacmd_cmd_reg != SATAC_PACKET ||
2435 2435              ahci_debug_flags & AHCIDBG_ATAPICMD &&
2436 2436              scmd->satacmd_cmd_reg == SATAC_PACKET) {
2437 2437  
2438 2438                  /* Dump the command header and table */
2439 2439                  ahci_log(ahci_ctlp, CE_WARN, "\n");
2440 2440                  ahci_log(ahci_ctlp, CE_WARN, "Command header&table for spkt "
2441 2441                      "0x%p cmd_reg 0x%x port %d", spkt,
2442 2442                      scmd->satacmd_cmd_reg, port);
2443 2443                  ptr = (uint32_t *)cmd_header;
2444 2444                  ahci_log(ahci_ctlp, CE_WARN,
2445 2445                      "  Command Header:%8x %8x %8x %8x",
2446 2446                      ptr[0], ptr[1], ptr[2], ptr[3]);
2447 2447  
2448 2448                  /* Dump the H2D register FIS */
2449 2449                  ptr = (uint32_t *)h2d_register_fisp;
2450 2450                  ahci_log(ahci_ctlp, CE_WARN,
2451 2451                      "  Command FIS:   %8x %8x %8x %8x",
2452 2452                      ptr[0], ptr[1], ptr[2], ptr[3]);
2453 2453  
2454 2454                  /* Dump the ACMD register FIS */
2455 2455                  ptr2 = (uint8_t *)&(cmd_table->ahcict_atapi_cmd);
2456 2456                  for (i = 0; i < SATA_ATAPI_MAX_CDB_LEN/8; i++)
2457 2457                          if (ahci_debug_flags & AHCIDBG_ATAPICMD)
2458 2458                                  ahci_log(ahci_ctlp, CE_WARN,
2459 2459                                      "  ATAPI command: %2x %2x %2x %2x "
2460 2460                                      "%2x %2x %2x %2x",
2461 2461                                      ptr2[8 * i], ptr2[8 * i + 1],
2462 2462                                      ptr2[8 * i + 2], ptr2[8 * i + 3],
2463 2463                                      ptr2[8 * i + 4], ptr2[8 * i + 5],
2464 2464                                      ptr2[8 * i + 6], ptr2[8 * i + 7]);
2465 2465  
2466 2466                  /* Dump the PRDT */
2467 2467                  for (i = 0; i < ncookies; i++) {
2468 2468                          ptr = (uint32_t *)&(cmd_table->ahcict_prdt[i]);
2469 2469                          ahci_log(ahci_ctlp, CE_WARN,
2470 2470                              "  Cookie %d:      %8x %8x %8x %8x",
2471 2471                              i, ptr[0], ptr[1], ptr[2], ptr[3]);
2472 2472                  }
2473 2473          }
2474 2474  #endif
2475 2475  
2476 2476          (void) ddi_dma_sync(
2477 2477              ahci_portp->ahciport_cmd_tables_dma_handle[cmd_slot],
2478 2478              0,
2479 2479              ahci_cmd_table_size,
2480 2480              DDI_DMA_SYNC_FORDEV);
2481 2481  
2482 2482          (void) ddi_dma_sync(ahci_portp->ahciport_cmd_list_dma_handle,
2483 2483              cmd_slot * sizeof (ahci_cmd_header_t),
2484 2484              sizeof (ahci_cmd_header_t),
2485 2485              DDI_DMA_SYNC_FORDEV);
2486 2486  
2487 2487          if ((ahci_check_dma_handle(ahci_portp->
2488 2488              ahciport_cmd_tables_dma_handle[cmd_slot]) != DDI_FM_OK) ||
2489 2489              ahci_check_dma_handle(ahci_portp->
2490 2490              ahciport_cmd_list_dma_handle) != DDI_FM_OK) {
2491 2491                  ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
2492 2492                      DDI_SERVICE_UNAFFECTED);
2493 2493                  return (AHCI_FAILURE);
2494 2494          }
2495 2495  
2496 2496          /* Set the corresponding bit in the PxSACT.DS for queued command */
2497 2497          if (command_type == AHCI_NCQ_CMD) {
2498 2498                  ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
2499 2499                      (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port),
2500 2500                      (0x1 << cmd_slot));
2501 2501          }
2502 2502  
2503 2503          /* Indicate to the HBA that a command is active. */
2504 2504          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
2505 2505              (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port),
2506 2506              (0x1 << cmd_slot));
2507 2507  
2508 2508          AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "ahci_deliver_satapkt "
2509 2509              "exit: port %d", port);
2510 2510  
2511 2511          /* Make sure the command is started by the PxSACT/PxCI */
2512 2512          if (ahci_check_acc_handle(ahci_ctlp->
2513 2513              ahcictl_ahci_acc_handle) != DDI_FM_OK) {
2514 2514                  ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
2515 2515                      DDI_SERVICE_UNAFFECTED);
2516 2516                  return (AHCI_FAILURE);
2517 2517          }
2518 2518  
2519 2519          return (cmd_slot);
2520 2520  }
2521 2521  
2522 2522  /*
2523 2523   * Called by the sata framework to abort the previously sent packet(s).
2524 2524   *
2525 2525   * Reset device to abort commands.
2526 2526   */
2527 2527  static int
2528 2528  ahci_tran_abort(dev_info_t *dip, sata_pkt_t *spkt, int flag)
2529 2529  {
2530 2530          ahci_ctl_t *ahci_ctlp;
2531 2531          ahci_port_t *ahci_portp;
2532 2532          uint32_t slot_status = 0;
2533 2533          uint32_t aborted_tags = 0;
2534 2534          uint32_t finished_tags = 0;
2535 2535          uint8_t cport = spkt->satapkt_device.satadev_addr.cport;
2536 2536          uint8_t port;
2537 2537          int tmp_slot;
2538 2538          int instance = ddi_get_instance(dip);
2539 2539  
2540 2540          ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
2541 2541          port = ahci_ctlp->ahcictl_cport_to_port[cport];
2542 2542  
2543 2543          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
2544 2544              "ahci_tran_abort enter: port %d", port);
2545 2545  
2546 2546          ahci_portp = ahci_ctlp->ahcictl_ports[port];
2547 2547          mutex_enter(&ahci_portp->ahciport_mutex);
2548 2548  
2549 2549          /*
2550 2550           * If AHCI_PORT_FLAG_MOPPING flag is set, it means all the pending
2551 2551           * commands are being mopped, therefore there is nothing else to do
2552 2552           */
2553 2553          if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
2554 2554                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2555 2555                      "ahci_tran_abort: port %d is in "
2556 2556                      "mopping process, so just return directly ", port);
2557 2557                  mutex_exit(&ahci_portp->ahciport_mutex);
2558 2558                  return (SATA_SUCCESS);
2559 2559          }
2560 2560  
2561 2561          /*
2562 2562           * If AHCI_PORT_FLAG_RDWR_PMULT flag is set, it means a R/W PMULT
2563 2563           * command is being executed so no other commands is outstanding,
2564 2564           * nothing to do.
2565 2565           */
2566 2566          if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_RDWR_PMULT) {
2567 2567                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2568 2568                      "ahci_tran_abort: port %d is reading/writing "
2569 2569                      "port multiplier, so just return directly ", port);
2570 2570                  mutex_exit(&ahci_portp->ahciport_mutex);
2571 2571                  return (SATA_SUCCESS);
2572 2572          }
2573 2573  
2574 2574          if (ahci_portp->ahciport_port_state & SATA_PSTATE_FAILED |
2575 2575              ahci_portp->ahciport_port_state & SATA_PSTATE_SHUTDOWN |
2576 2576              ahci_portp->ahciport_port_state & SATA_PSTATE_PWROFF) {
2577 2577                  /*
2578 2578                   * In case the targer driver would send the request before
2579 2579                   * sata framework can have the opportunity to process those
2580 2580                   * event reports.
2581 2581                   */
2582 2582                  spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
2583 2583                  spkt->satapkt_device.satadev_state =
2584 2584                      ahci_portp->ahciport_port_state;
2585 2585                  ahci_update_sata_registers(ahci_ctlp, port,
2586 2586                      &spkt->satapkt_device);
2587 2587                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2588 2588                      "ahci_tran_abort returning SATA_FAILURE while "
2589 2589                      "port in FAILED/SHUTDOWN/PWROFF state: "
2590 2590                      "port: %d", port);
2591 2591                  mutex_exit(&ahci_portp->ahciport_mutex);
2592 2592                  return (SATA_FAILURE);
2593 2593          }
2594 2594  
2595 2595          if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
2596 2596                  /*
2597 2597                   * ahci_intr_phyrdy_change() may have rendered it to
2598 2598                   * AHCI_PORT_TYPE_NODEV.
2599 2599                   */
2600 2600                  spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
2601 2601                  spkt->satapkt_device.satadev_type = SATA_DTYPE_NONE;
2602 2602                  spkt->satapkt_device.satadev_state =
2603 2603                      ahci_portp->ahciport_port_state;
2604 2604                  ahci_update_sata_registers(ahci_ctlp, port,
2605 2605                      &spkt->satapkt_device);
2606 2606                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2607 2607                      "ahci_tran_abort returning SATA_FAILURE while "
2608 2608                      "no device attached: port: %d", port);
2609 2609                  mutex_exit(&ahci_portp->ahciport_mutex);
2610 2610                  return (SATA_FAILURE);
2611 2611          }
2612 2612  
2613 2613          if (flag == SATA_ABORT_ALL_PACKETS) {
2614 2614                  if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2615 2615                          aborted_tags = ahci_portp->ahciport_pending_tags;
2616 2616                  else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2617 2617                          aborted_tags = ahci_portp->ahciport_pending_ncq_tags;
2618 2618  
2619 2619                  cmn_err(CE_NOTE, "!ahci%d: ahci port %d abort all packets",
2620 2620                      instance, port);
2621 2621          } else {
2622 2622                  aborted_tags = 0xffffffff;
2623 2623                  /*
2624 2624                   * Aborting one specific packet, first search the
2625 2625                   * ahciport_slot_pkts[] list for matching spkt.
2626 2626                   */
2627 2627                  for (tmp_slot = 0;
2628 2628                      tmp_slot < ahci_ctlp->ahcictl_num_cmd_slots; tmp_slot++) {
2629 2629                          if (ahci_portp->ahciport_slot_pkts[tmp_slot] == spkt) {
2630 2630                                  aborted_tags = (0x1 << tmp_slot);
2631 2631                                  break;
2632 2632                          }
2633 2633                  }
2634 2634  
2635 2635                  if (aborted_tags == 0xffffffff) {
2636 2636                          /* request packet is not on the pending list */
2637 2637                          AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2638 2638                              "Cannot find the aborting pkt 0x%p on the "
2639 2639                              "pending list", (void *)spkt);
2640 2640                          ahci_update_sata_registers(ahci_ctlp, port,
2641 2641                              &spkt->satapkt_device);
2642 2642                          mutex_exit(&ahci_portp->ahciport_mutex);
2643 2643                          return (SATA_FAILURE);
2644 2644                  }
2645 2645                  cmn_err(CE_NOTE, "!ahci%d: ahci port %d abort satapkt 0x%p",
2646 2646                      instance, port, (void *)spkt);
2647 2647          }
2648 2648  
2649 2649          if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2650 2650                  slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2651 2651                      (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
2652 2652          else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2653 2653                  slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2654 2654                      (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
2655 2655  
2656 2656          ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
2657 2657          ahci_portp->ahciport_mop_in_progress++;
2658 2658  
2659 2659          /*
2660 2660           * To abort the packet(s), first we are trying to clear PxCMD.ST
2661 2661           * to stop the port, and if the port can be stopped
2662 2662           * successfully with PxTFD.STS.BSY and PxTFD.STS.DRQ cleared to '0',
2663 2663           * then we just send back the aborted packet(s) with ABORTED flag
2664 2664           * and then restart the port by setting PxCMD.ST and PxCMD.FRE.
2665 2665           * If PxTFD.STS.BSY or PxTFD.STS.DRQ is set to '1', then we
2666 2666           * perform a COMRESET.
2667 2667           */
2668 2668          (void) ahci_restart_port_wait_till_ready(ahci_ctlp,
2669 2669              ahci_portp, port, 0, NULL);
2670 2670  
2671 2671          /*
2672 2672           * Compute which have finished and which need to be retried.
2673 2673           *
2674 2674           * The finished tags are ahciport_pending_tags/ahciport_pending_ncq_tags
2675 2675           * minus the slot_status. The aborted_tags has to be deducted by
2676 2676           * finished_tags since we can't possibly abort a tag which had finished
2677 2677           * already.
2678 2678           */
2679 2679          if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2680 2680                  finished_tags = ahci_portp->ahciport_pending_tags &
2681 2681                      ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2682 2682          else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2683 2683                  finished_tags = ahci_portp->ahciport_pending_ncq_tags &
2684 2684                      ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2685 2685  
2686 2686          aborted_tags &= ~finished_tags;
2687 2687  
2688 2688          ahci_mop_commands(ahci_ctlp,
2689 2689              ahci_portp,
2690 2690              slot_status,
2691 2691              0, /* failed tags */
2692 2692              0, /* timeout tags */
2693 2693              aborted_tags,
2694 2694              0); /* reset tags */
2695 2695  
2696 2696          ahci_update_sata_registers(ahci_ctlp, port, &spkt->satapkt_device);
2697 2697          mutex_exit(&ahci_portp->ahciport_mutex);
2698 2698  
2699 2699          return (SATA_SUCCESS);
2700 2700  }
2701 2701  
2702 2702  /*
2703 2703   * Used to do device reset and reject all the pending packets on a device
2704 2704   * during the reset operation.
2705 2705   *
2706 2706   * NOTE: ONLY called by ahci_tran_reset_dport
2707 2707   */
2708 2708  static int
2709 2709  ahci_reset_device_reject_pkts(ahci_ctl_t *ahci_ctlp,
2710 2710      ahci_port_t *ahci_portp, ahci_addr_t *addrp)
2711 2711  {
2712 2712          uint32_t slot_status = 0;
2713 2713          uint32_t reset_tags = 0;
2714 2714          uint32_t finished_tags = 0;
2715 2715          uint8_t port = addrp->aa_port;
2716 2716          sata_device_t sdevice;
2717 2717          int ret;
2718 2718  
2719 2719          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
2720 2720  
2721 2721          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
2722 2722              "ahci_reset_device_reject_pkts on port: %d", port);
2723 2723  
2724 2724          /*
2725 2725           * If AHCI_PORT_FLAG_MOPPING flag is set, it means all the pending
2726 2726           * commands are being mopped, therefore there is nothing else to do
2727 2727           */
2728 2728          if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
2729 2729                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2730 2730                      "ahci_reset_device_reject_pkts: port %d is in "
2731 2731                      "mopping process, so return directly ", port);
2732 2732                  return (SATA_SUCCESS);
2733 2733          }
2734 2734  
2735 2735          if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2736 2736                  slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2737 2737                      (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
2738 2738                  reset_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2739 2739          } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2740 2740                  slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2741 2741                      (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
2742 2742                  reset_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2743 2743          }
2744 2744  
2745 2745          if (ahci_software_reset(ahci_ctlp, ahci_portp, addrp)
2746 2746              != AHCI_SUCCESS) {
2747 2747                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2748 2748                      "Try to do a port reset after software "
2749 2749                      "reset failed", port);
2750 2750                  ret = ahci_port_reset(ahci_ctlp, ahci_portp, addrp);
2751 2751                  if (ret != AHCI_SUCCESS) {
2752 2752                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2753 2753                              "ahci_reset_device_reject_pkts: port %d "
2754 2754                              "failed", port);
2755 2755                          return (SATA_FAILURE);
2756 2756                  }
2757 2757          }
2758 2758          /* Set the reset in progress flag */
2759 2759          ahci_portp->ahciport_reset_in_progress = 1;
2760 2760  
2761 2761          ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
2762 2762          ahci_portp->ahciport_mop_in_progress++;
2763 2763  
2764 2764          /* Indicate to the framework that a reset has happened */
2765 2765          bzero((void *)&sdevice, sizeof (sata_device_t));
2766 2766          sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
2767 2767          sdevice.satadev_addr.pmport = 0;
2768 2768          sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
2769 2769          sdevice.satadev_state = SATA_DSTATE_RESET |
2770 2770              SATA_DSTATE_PWR_ACTIVE;
2771 2771          mutex_exit(&ahci_portp->ahciport_mutex);
2772 2772          sata_hba_event_notify(
2773 2773              ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
2774 2774              &sdevice,
2775 2775              SATA_EVNT_DEVICE_RESET);
2776 2776          mutex_enter(&ahci_portp->ahciport_mutex);
2777 2777  
2778 2778          AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
2779 2779              "port %d sending event up: SATA_EVNT_DEVICE_RESET", port);
2780 2780  
2781 2781          /* Next try to mop the pending commands */
2782 2782          if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2783 2783                  finished_tags = ahci_portp->ahciport_pending_tags &
2784 2784                      ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2785 2785          else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2786 2786                  finished_tags = ahci_portp->ahciport_pending_ncq_tags &
2787 2787                      ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2788 2788  
2789 2789          reset_tags &= ~finished_tags;
2790 2790  
2791 2791          ahci_mop_commands(ahci_ctlp,
2792 2792              ahci_portp,
2793 2793              slot_status,
2794 2794              0, /* failed tags */
2795 2795              0, /* timeout tags */
2796 2796              0, /* aborted tags */
2797 2797              reset_tags); /* reset tags */
2798 2798  
2799 2799          return (SATA_SUCCESS);
2800 2800  }
2801 2801  
2802 2802  /*
2803 2803   * Used to do device reset and reject all the pending packets on a device
2804 2804   * during the reset operation.
2805 2805   *
2806 2806   * NOTE: ONLY called by ahci_tran_reset_dport
2807 2807   */
2808 2808  static int
2809 2809  ahci_reset_pmdevice_reject_pkts(ahci_ctl_t *ahci_ctlp,
2810 2810      ahci_port_t *ahci_portp, ahci_addr_t *addrp)
2811 2811  {
2812 2812          uint32_t finished_tags = 0, reset_tags = 0, slot_status = 0;
2813 2813          uint8_t port = addrp->aa_port;
2814 2814          uint8_t pmport = addrp->aa_pmport;
2815 2815          sata_device_t sdevice;
2816 2816  
2817 2817          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
2818 2818  
2819 2819          AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_PMULT, ahci_ctlp,
2820 2820              "ahci_reset_pmdevice_reject_pkts at port %d:%d", port, pmport);
2821 2821  
2822 2822          if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
2823 2823                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2824 2824                      "ahci_reset_pmdevice_reject_pkts: port %d is in "
2825 2825                      "mopping process, so return directly ", port);
2826 2826                  return (SATA_SUCCESS);
2827 2827          }
2828 2828  
2829 2829          /* Checking for outstanding commands */
2830 2830          if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2831 2831                  slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2832 2832                      (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
2833 2833                  reset_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2834 2834          } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2835 2835                  slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2836 2836                      (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
2837 2837                  reset_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2838 2838          }
2839 2839  
2840 2840          /* Issue SOFTWARE reset command. */
2841 2841          if (ahci_software_reset(ahci_ctlp, ahci_portp, addrp)
2842 2842              != AHCI_SUCCESS) {
2843 2843                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2844 2844                      "Try to do a port reset after software "
2845 2845                      "reset failed", port);
2846 2846                  return (SATA_FAILURE);
2847 2847          }
2848 2848  
2849 2849          /* Set the reset in progress flag */
2850 2850          ahci_portp->ahciport_reset_in_progress = 1;
2851 2851  
2852 2852          ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
2853 2853          ahci_portp->ahciport_mop_in_progress++;
2854 2854  
2855 2855          /* Indicate to the framework that a reset has happened */
2856 2856          bzero((void *)&sdevice, sizeof (sata_device_t));
2857 2857          sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
2858 2858          sdevice.satadev_addr.pmport = pmport;
2859 2859          if (AHCI_ADDR_IS_PMULT(addrp))
2860 2860                  sdevice.satadev_addr.qual = SATA_ADDR_PMULT;
2861 2861          else
2862 2862                  sdevice.satadev_addr.qual = SATA_ADDR_DPMPORT;
2863 2863          sdevice.satadev_state = SATA_DSTATE_RESET |
2864 2864              SATA_DSTATE_PWR_ACTIVE;
2865 2865          mutex_exit(&ahci_portp->ahciport_mutex);
2866 2866          sata_hba_event_notify(
2867 2867              ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
2868 2868              &sdevice,
2869 2869              SATA_EVNT_DEVICE_RESET);
2870 2870          mutex_enter(&ahci_portp->ahciport_mutex);
2871 2871  
2872 2872          AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
2873 2873              "port %d:%d sending event up: SATA_EVNT_DEVICE_RESET",
2874 2874              port, pmport);
2875 2875  
2876 2876          /* Next try to mop the pending commands */
2877 2877          if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2878 2878                  finished_tags = ahci_portp->ahciport_pending_tags &
2879 2879                      ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2880 2880          else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2881 2881                  finished_tags = ahci_portp->ahciport_pending_ncq_tags &
2882 2882                      ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2883 2883          reset_tags &= ~finished_tags;
2884 2884  
2885 2885          AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
2886 2886              "reset_tags = %x, finished_tags = %x, slot_status = %x",
2887 2887              reset_tags, finished_tags, slot_status);
2888 2888  
2889 2889          /*
2890 2890           * NOTE: Because PxCI be only erased by unset PxCMD.ST bit, so even we
2891 2891           * try to reset a single device behind a port multiplier will
2892 2892           * terminate all the commands on that HBA port. We need mop these
2893 2893           * commands as well.
2894 2894           */
2895 2895          ahci_mop_commands(ahci_ctlp,
2896 2896              ahci_portp,
2897 2897              slot_status,
2898 2898              0, /* failed tags */
2899 2899              0, /* timeout tags */
2900 2900              0, /* aborted tags */
2901 2901              reset_tags); /* reset tags */
2902 2902  
2903 2903          return (SATA_SUCCESS);
2904 2904  }
2905 2905  
2906 2906  /*
2907 2907   * Used to do port reset and reject all the pending packets on a port during
2908 2908   * the reset operation.
2909 2909   */
2910 2910  static int
2911 2911  ahci_reset_port_reject_pkts(ahci_ctl_t *ahci_ctlp,
2912 2912      ahci_port_t *ahci_portp, ahci_addr_t *addrp)
2913 2913  {
2914 2914          uint32_t slot_status = 0;
2915 2915          uint32_t reset_tags = 0;
2916 2916          uint32_t finished_tags = 0;
2917 2917          uint8_t port = addrp->aa_port;
2918 2918  
2919 2919          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
2920 2920  
2921 2921          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
2922 2922              "ahci_reset_port_reject_pkts at port: %d", port);
2923 2923  
2924 2924          /*
2925 2925           * If AHCI_PORT_FLAG_MOPPING flag is set, it means all the pending
2926 2926           * commands are being mopped, therefore there is nothing else to do
2927 2927           */
2928 2928          if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
2929 2929                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2930 2930                      "ahci_reset_port_reject_pkts: port %d is in "
2931 2931                      "mopping process, so return directly ", port);
2932 2932                  return (SATA_SUCCESS);
2933 2933          }
2934 2934  
2935 2935          ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
2936 2936          ahci_portp->ahciport_mop_in_progress++;
2937 2937  
2938 2938          if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2939 2939                  slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2940 2940                      (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
2941 2941                  reset_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2942 2942          } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2943 2943                  slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2944 2944                      (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
2945 2945                  reset_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2946 2946          }
2947 2947  
2948 2948          if (ahci_restart_port_wait_till_ready(ahci_ctlp,
2949 2949              ahci_portp, port, AHCI_PORT_RESET|AHCI_RESET_NO_EVENTS_UP,
2950 2950              NULL) != AHCI_SUCCESS) {
2951 2951  
2952 2952                  /* Clear mop flag */
2953 2953                  ahci_portp->ahciport_mop_in_progress--;
2954 2954                  if (ahci_portp->ahciport_mop_in_progress == 0)
2955 2955                          ahci_portp->ahciport_flags &=
2956 2956                              ~AHCI_PORT_FLAG_MOPPING;
2957 2957                  return (SATA_FAILURE);
2958 2958          }
2959 2959  
2960 2960          if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2961 2961                  finished_tags = ahci_portp->ahciport_pending_tags &
2962 2962                      ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2963 2963          else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2964 2964                  finished_tags = ahci_portp->ahciport_pending_ncq_tags &
2965 2965                      ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2966 2966  
2967 2967          reset_tags &= ~finished_tags;
2968 2968  
2969 2969          ahci_mop_commands(ahci_ctlp,
2970 2970              ahci_portp,
2971 2971              slot_status,
2972 2972              0, /* failed tags */
2973 2973              0, /* timeout tags */
2974 2974              0, /* aborted tags */
2975 2975              reset_tags); /* reset tags */
2976 2976  
2977 2977          return (SATA_SUCCESS);
2978 2978  }
2979 2979  
2980 2980  /*
2981 2981   * Used to do hba reset and reject all the pending packets on all ports
2982 2982   * during the reset operation.
2983 2983   */
2984 2984  static int
2985 2985  ahci_reset_hba_reject_pkts(ahci_ctl_t *ahci_ctlp)
2986 2986  {
2987 2987          ahci_port_t *ahci_portp;
2988 2988          uint32_t slot_status[AHCI_MAX_PORTS];
2989 2989          uint32_t reset_tags[AHCI_MAX_PORTS];
2990 2990          uint32_t finished_tags[AHCI_MAX_PORTS];
2991 2991          int port;
2992 2992          int ret = SATA_SUCCESS;
2993 2993  
2994 2994          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
2995 2995              "ahci_reset_hba_reject_pkts enter", NULL);
2996 2996  
2997 2997          bzero(slot_status, sizeof (slot_status));
2998 2998          bzero(reset_tags, sizeof (reset_tags));
2999 2999          bzero(finished_tags, sizeof (finished_tags));
3000 3000  
3001 3001          for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3002 3002                  if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3003 3003                          continue;
3004 3004                  }
3005 3005  
3006 3006                  ahci_portp = ahci_ctlp->ahcictl_ports[port];
3007 3007  
3008 3008                  mutex_enter(&ahci_portp->ahciport_mutex);
3009 3009                  ahci_portp->ahciport_reset_in_progress = 1;
3010 3010                  if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
3011 3011                          slot_status[port] = ddi_get32(
3012 3012                              ahci_ctlp->ahcictl_ahci_acc_handle,
3013 3013                              (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
3014 3014                          reset_tags[port] = slot_status[port] &
3015 3015                              AHCI_SLOT_MASK(ahci_ctlp);
3016 3016                          AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3017 3017                              "port %d: reset_tags = 0x%x pending_tags = 0x%x",
3018 3018                              port, reset_tags[port],
3019 3019                              ahci_portp->ahciport_pending_tags);
3020 3020                  } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
3021 3021                          slot_status[port] = ddi_get32(
3022 3022                              ahci_ctlp->ahcictl_ahci_acc_handle,
3023 3023                              (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
3024 3024                          reset_tags[port] = slot_status[port] &
3025 3025                              AHCI_NCQ_SLOT_MASK(ahci_portp);
3026 3026                          AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3027 3027                              "port %d: reset_tags = 0x%x pending_tags = 0x%x",
3028 3028                              port, reset_tags[port],
3029 3029                              ahci_portp->ahciport_pending_tags);
3030 3030                  }
3031 3031                  mutex_exit(&ahci_portp->ahciport_mutex);
3032 3032          }
3033 3033  
3034 3034          if (ahci_hba_reset(ahci_ctlp) != AHCI_SUCCESS) {
3035 3035                  ret = SATA_FAILURE;
3036 3036          }
3037 3037  
3038 3038          for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3039 3039                  if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3040 3040                          continue;
3041 3041                  }
3042 3042  
3043 3043                  ahci_portp = ahci_ctlp->ahcictl_ports[port];
3044 3044  
3045 3045                  mutex_enter(&ahci_portp->ahciport_mutex);
3046 3046                  /*
3047 3047                   * To prevent recursive enter to ahci_mop_commands, we need
3048 3048                   * check AHCI_PORT_FLAG_MOPPING flag.
3049 3049                   */
3050 3050                  if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
3051 3051                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3052 3052                              "ahci_reset_hba_reject_pkts: port %d is in "
3053 3053                              "mopping process, so return directly ", port);
3054 3054                          mutex_exit(&ahci_portp->ahciport_mutex);
3055 3055                          continue;
3056 3056                  }
3057 3057  
3058 3058                  ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
3059 3059                  ahci_portp->ahciport_mop_in_progress++;
3060 3060  
3061 3061                  if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
3062 3062                          finished_tags[port]  =
3063 3063                              ahci_portp->ahciport_pending_tags &
3064 3064                              ~slot_status[port] & AHCI_SLOT_MASK(ahci_ctlp);
3065 3065                  else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
3066 3066                          finished_tags[port] =
3067 3067                              ahci_portp->ahciport_pending_ncq_tags &
3068 3068                              ~slot_status[port] & AHCI_NCQ_SLOT_MASK(ahci_portp);
3069 3069  
3070 3070                  reset_tags[port] &= ~finished_tags[port];
3071 3071  
3072 3072                  ahci_mop_commands(ahci_ctlp,
3073 3073                      ahci_portp,
3074 3074                      slot_status[port],
3075 3075                      0, /* failed tags */
3076 3076                      0, /* timeout tags */
3077 3077                      0, /* aborted tags */
3078 3078                      reset_tags[port]); /* reset tags */
3079 3079                  mutex_exit(&ahci_portp->ahciport_mutex);
3080 3080          }
3081 3081  out:
3082 3082          return (ret);
3083 3083  }
3084 3084  
3085 3085  /*
3086 3086   * Called by sata framework to reset a port(s) or device.
3087 3087   */
3088 3088  static int
3089 3089  ahci_tran_reset_dport(dev_info_t *dip, sata_device_t *sd)
3090 3090  {
3091 3091          ahci_ctl_t *ahci_ctlp;
3092 3092          ahci_port_t *ahci_portp;
3093 3093          ahci_addr_t addr;
3094 3094          uint8_t cport = sd->satadev_addr.cport;
3095 3095          uint8_t pmport = sd->satadev_addr.pmport;
3096 3096          uint8_t port;
3097 3097          int ret = SATA_SUCCESS;
3098 3098          int instance = ddi_get_instance(dip);
3099 3099  
3100 3100          ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
3101 3101          port = ahci_ctlp->ahcictl_cport_to_port[cport];
3102 3102          ahci_portp = ahci_ctlp->ahcictl_ports[port];
3103 3103  
3104 3104          ahci_get_ahci_addr(ahci_ctlp, sd, &addr);
3105 3105  
3106 3106          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
3107 3107              "ahci_tran_reset_dport enter: cport %d", cport);
3108 3108  
3109 3109          switch (sd->satadev_addr.qual) {
3110 3110          case SATA_ADDR_PMPORT:
3111 3111                  /*
3112 3112                   * If we want to issue a COMRESET on a pmport, we need to
3113 3113                   * reject the outstanding commands on that pmport. According
3114 3114                   * to AHCI spec, PxCI register could only be cleared by
3115 3115                   * clearing PxCMD.ST, which will halt the controller port - as
3116 3116                   * well as other pmports.
3117 3117                   *
3118 3118                   * Therefore we directly reset the controller port for
3119 3119                   * simplicity. ahci_tran_probe_port() will handle reset stuff
3120 3120                   * like initializing the given pmport.
3121 3121                   */
3122 3122                  /* FALLTHRU */
3123 3123          case SATA_ADDR_CPORT:
3124 3124                  /* Port reset */
3125 3125                  ahci_portp = ahci_ctlp->ahcictl_ports[port];
3126 3126                  cmn_err(CE_NOTE, "!ahci%d: ahci_tran_reset_dport "
3127 3127                      "port %d reset port", instance, port);
3128 3128  
3129 3129                  mutex_enter(&ahci_portp->ahciport_mutex);
3130 3130                  ret = ahci_reset_port_reject_pkts(ahci_ctlp, ahci_portp, &addr);
3131 3131                  mutex_exit(&ahci_portp->ahciport_mutex);
3132 3132  
3133 3133                  break;
3134 3134  
3135 3135          case SATA_ADDR_DPMPORT:
3136 3136                  cmn_err(CE_NOTE, "!ahci%d: ahci_tran_reset_dport "
3137 3137                      "port %d:%d reset device", instance, port, pmport);
3138 3138                  /* FALLTHRU */
3139 3139          case SATA_ADDR_DCPORT:
3140 3140                  /* Device reset */
3141 3141                  if (sd->satadev_addr.qual == SATA_ADDR_DCPORT)
3142 3142                          cmn_err(CE_NOTE, "!ahci%d: ahci_tran_reset_dport "
3143 3143                              "port %d reset device", instance, port);
3144 3144  
3145 3145                  mutex_enter(&ahci_portp->ahciport_mutex);
3146 3146                  /*
3147 3147                   * software reset request must be sent to SATA_PMULT_HOSTPORT
3148 3148                   * if target is a port multiplier:
3149 3149                   */
3150 3150                  if (sd->satadev_addr.qual == SATA_ADDR_DCPORT &&
3151 3151                      ahci_portp->ahciport_device_type == SATA_DTYPE_PMULT)
3152 3152                          AHCI_ADDR_SET_PMULT(&addr, port);
3153 3153  
3154 3154                  if (ahci_portp->ahciport_port_state & SATA_PSTATE_FAILED |
3155 3155                      ahci_portp->ahciport_port_state & SATA_PSTATE_SHUTDOWN |
3156 3156                      ahci_portp->ahciport_port_state & SATA_PSTATE_PWROFF) {
3157 3157                          /*
3158 3158                           * In case the targer driver would send the request
3159 3159                           * before sata framework can have the opportunity to
3160 3160                           * process those event reports.
3161 3161                           */
3162 3162                          sd->satadev_state = ahci_portp->ahciport_port_state;
3163 3163                          ahci_update_sata_registers(ahci_ctlp, port, sd);
3164 3164                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3165 3165                              "ahci_tran_reset_dport returning SATA_FAILURE "
3166 3166                              "while port in FAILED/SHUTDOWN/PWROFF state: "
3167 3167                              "port: %d", port);
3168 3168                          mutex_exit(&ahci_portp->ahciport_mutex);
3169 3169                          ret = SATA_FAILURE;
3170 3170                          break;
3171 3171                  }
3172 3172  
3173 3173                  if (AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr) ==
3174 3174                      SATA_DTYPE_NONE) {
3175 3175                          /*
3176 3176                           * ahci_intr_phyrdy_change() may have rendered it to
3177 3177                           * AHCI_PORT_TYPE_NODEV.
3178 3178                           */
3179 3179                          sd->satadev_type = SATA_DTYPE_NONE;
3180 3180                          sd->satadev_state = AHCIPORT_GET_STATE(ahci_portp,
3181 3181                              &addr);
3182 3182                          ahci_update_sata_registers(ahci_ctlp, port, sd);
3183 3183                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3184 3184                              "ahci_tran_reset_dport returning SATA_FAILURE "
3185 3185                              "while no device attached: port: %d", port);
3186 3186                          mutex_exit(&ahci_portp->ahciport_mutex);
3187 3187                          ret = SATA_FAILURE;
3188 3188                          break;
3189 3189                  }
3190 3190  
3191 3191                  if (AHCI_ADDR_IS_PORT(&addr)) {
3192 3192                          ret = ahci_reset_device_reject_pkts(ahci_ctlp,
3193 3193                              ahci_portp, &addr);
3194 3194                  } else {
3195 3195                          ret = ahci_reset_pmdevice_reject_pkts(ahci_ctlp,
3196 3196                              ahci_portp, &addr);
3197 3197                  }
3198 3198  
3199 3199                  mutex_exit(&ahci_portp->ahciport_mutex);
3200 3200                  break;
3201 3201  
3202 3202          case SATA_ADDR_CNTRL:
3203 3203                  /* Reset the whole controller */
3204 3204                  cmn_err(CE_NOTE, "!ahci%d: ahci_tran_reset_dport "
3205 3205                      "reset the whole hba", instance);
3206 3206                  ret = ahci_reset_hba_reject_pkts(ahci_ctlp);
3207 3207                  break;
3208 3208  
3209 3209          default:
3210 3210                  ret = SATA_FAILURE;
3211 3211          }
3212 3212  
3213 3213          return (ret);
3214 3214  }
3215 3215  
3216 3216  /*
3217 3217   * Called by sata framework to activate a port as part of hotplug.
3218 3218   * (cfgadm -c connect satax/y)
3219 3219   * Support port multiplier.
3220 3220   */
3221 3221  static int
3222 3222  ahci_tran_hotplug_port_activate(dev_info_t *dip, sata_device_t *satadev)
3223 3223  {
3224 3224          ahci_ctl_t *ahci_ctlp;
3225 3225          ahci_port_t *ahci_portp;
3226 3226          ahci_addr_t addr;
3227 3227          uint8_t cport = satadev->satadev_addr.cport;
3228 3228          uint8_t pmport = satadev->satadev_addr.pmport;
3229 3229          uint8_t port;
3230 3230          int instance = ddi_get_instance(dip);
3231 3231  
3232 3232          ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
3233 3233          port = ahci_ctlp->ahcictl_cport_to_port[cport];
3234 3234  
3235 3235          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
3236 3236              "ahci_tran_hotplug_port_activate enter: cport %d", cport);
3237 3237  
3238 3238          ahci_portp = ahci_ctlp->ahcictl_ports[port];
3239 3239  
3240 3240          mutex_enter(&ahci_portp->ahciport_mutex);
3241 3241          ahci_get_ahci_addr(ahci_ctlp, satadev, &addr);
3242 3242          ASSERT(AHCI_ADDR_IS_PORT(&addr) || AHCI_ADDR_IS_PMPORT(&addr));
3243 3243  
3244 3244          if (AHCI_ADDR_IS_PORT(&addr)) {
3245 3245                  cmn_err(CE_NOTE, "!ahci%d: ahci port %d is activated",
3246 3246                      instance, port);
3247 3247  
3248 3248                  /* Enable the interrupts on the port */
3249 3249                  ahci_enable_port_intrs(ahci_ctlp, port);
3250 3250  
3251 3251                  /*
3252 3252                   * Reset the port so that the PHY communication would be
3253 3253                   * re-established.  But this reset is an internal operation
3254 3254                   * and the sata module doesn't need to know about it.
3255 3255                   * Moreover, the port with a device attached will be started
3256 3256                   * too.
3257 3257                   */
3258 3258                  (void) ahci_restart_port_wait_till_ready(ahci_ctlp,
3259 3259                      ahci_portp, port,
3260 3260                      AHCI_PORT_RESET|AHCI_RESET_NO_EVENTS_UP,
3261 3261                      NULL);
3262 3262  
3263 3263                  /*
3264 3264                   * Need to check the link status and device status of the port
3265 3265                   * and consider raising power if the port was in D3 state
3266 3266                   */
3267 3267                  ahci_portp->ahciport_port_state |= SATA_PSTATE_PWRON;
3268 3268                  ahci_portp->ahciport_port_state &= ~SATA_PSTATE_PWROFF;
3269 3269                  ahci_portp->ahciport_port_state &= ~SATA_PSTATE_SHUTDOWN;
3270 3270          } else if (AHCI_ADDR_IS_PMPORT(&addr)) {
3271 3271                  cmn_err(CE_NOTE, "!ahci%d: ahci port %d:%d is activated",
3272 3272                      instance, port, pmport);
3273 3273                  /* AHCI_ADDR_PMPORT */
3274 3274                  AHCIPORT_PMSTATE(ahci_portp, &addr) |= SATA_PSTATE_PWRON;
3275 3275                  AHCIPORT_PMSTATE(ahci_portp, &addr) &=
3276 3276                      ~(SATA_PSTATE_PWROFF|SATA_PSTATE_SHUTDOWN);
3277 3277          }
3278 3278  
3279 3279          satadev->satadev_state = ahci_portp->ahciport_port_state;
3280 3280  
3281 3281          ahci_update_sata_registers(ahci_ctlp, port, satadev);
3282 3282  
3283 3283          mutex_exit(&ahci_portp->ahciport_mutex);
3284 3284          return (SATA_SUCCESS);
3285 3285  }
3286 3286  
3287 3287  /*
3288 3288   * Called by sata framework to deactivate a port as part of hotplug.
3289 3289   * (cfgadm -c disconnect satax/y)
3290 3290   * Support port multiplier.
3291 3291   */
3292 3292  static int
3293 3293  ahci_tran_hotplug_port_deactivate(dev_info_t *dip, sata_device_t *satadev)
3294 3294  {
3295 3295          ahci_ctl_t *ahci_ctlp;
3296 3296          ahci_port_t *ahci_portp;
3297 3297          ahci_addr_t addr;
3298 3298          uint8_t cport = satadev->satadev_addr.cport;
3299 3299          uint8_t pmport = satadev->satadev_addr.pmport;
3300 3300          uint8_t port;
3301 3301          uint32_t port_scontrol;
3302 3302          int instance = ddi_get_instance(dip);
3303 3303  
3304 3304          ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
3305 3305          port = ahci_ctlp->ahcictl_cport_to_port[cport];
3306 3306  
3307 3307          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
3308 3308              "ahci_tran_hotplug_port_deactivate enter: cport %d", cport);
3309 3309  
3310 3310          ahci_portp = ahci_ctlp->ahcictl_ports[port];
3311 3311          mutex_enter(&ahci_portp->ahciport_mutex);
3312 3312          ahci_get_ahci_addr(ahci_ctlp, satadev, &addr);
3313 3313          ASSERT(AHCI_ADDR_IS_PORT(&addr) || AHCI_ADDR_IS_PMPORT(&addr));
3314 3314  
3315 3315          if (AHCI_ADDR_IS_PORT(&addr)) {
3316 3316                  cmn_err(CE_NOTE, "!ahci%d: ahci port %d is deactivated",
3317 3317                      instance, port);
3318 3318  
3319 3319                  /* Disable the interrupts on the port */
3320 3320                  ahci_disable_port_intrs(ahci_ctlp, port);
3321 3321  
3322 3322                  if (ahci_portp->ahciport_device_type != SATA_DTYPE_NONE) {
3323 3323  
3324 3324                          /* First to abort all the pending commands */
3325 3325                          ahci_reject_all_abort_pkts(ahci_ctlp, ahci_portp, port);
3326 3326  
3327 3327                          /* Then stop the port */
3328 3328                          (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
3329 3329                              ahci_portp, port);
3330 3330                  }
3331 3331  
3332 3332                  /* Next put the PHY offline */
3333 3333                  port_scontrol = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3334 3334                      (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port));
3335 3335                  SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_DISABLE);
3336 3336                  ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle, (uint32_t *)
3337 3337                      AHCI_PORT_PxSCTL(ahci_ctlp, port), port_scontrol);
3338 3338          } else if (AHCI_ADDR_IS_PMPORT(&addr)) {
3339 3339                  cmn_err(CE_NOTE, "!ahci%d: ahci port %d:%d is deactivated",
3340 3340                      instance, port, pmport);
3341 3341  
3342 3342                  ahci_disable_port_intrs(ahci_ctlp, port);
3343 3343                  if (AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr)
3344 3344                      != SATA_DTYPE_NONE)
3345 3345                          ahci_reject_all_abort_pkts(ahci_ctlp, ahci_portp, port);
3346 3346  
3347 3347                  /* Re-enable the interrupts for the other pmports */
3348 3348                  ahci_enable_port_intrs(ahci_ctlp, port);
3349 3349          }
3350 3350  
3351 3351          /* Update port state */
3352 3352          AHCIPORT_SET_STATE(ahci_portp, &addr, SATA_PSTATE_SHUTDOWN);
3353 3353          satadev->satadev_state = SATA_PSTATE_SHUTDOWN;
3354 3354  
3355 3355          ahci_update_sata_registers(ahci_ctlp, port, satadev);
3356 3356  
3357 3357          mutex_exit(&ahci_portp->ahciport_mutex);
3358 3358          return (SATA_SUCCESS);
3359 3359  }
3360 3360  
3361 3361  /*
3362 3362   * To be used to mark all the outstanding pkts with SATA_PKT_ABORTED
3363 3363   * when a device is unplugged or a port is deactivated.
3364 3364   */
3365 3365  static void
3366 3366  ahci_reject_all_abort_pkts(ahci_ctl_t *ahci_ctlp,
3367 3367      ahci_port_t *ahci_portp, uint8_t port)
3368 3368  {
3369 3369          uint32_t slot_status = 0;
3370 3370          uint32_t abort_tags = 0;
3371 3371  
3372 3372          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3373 3373  
3374 3374          AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
3375 3375              "ahci_reject_all_abort_pkts at port: %d", port);
3376 3376  
3377 3377          /* Read/write port multiplier command takes highest priority */
3378 3378          if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
3379 3379                  slot_status = 0x1;
3380 3380                  abort_tags = 0x1;
3381 3381                  goto out;
3382 3382          }
3383 3383  
3384 3384          /*
3385 3385           * When AHCI_PORT_FLAG_MOPPING is set, we need to check whether a
3386 3386           * REQUEST SENSE command or READ LOG EXT command is delivered to HBA
3387 3387           * to get the error data, if yes when the device is removed, the
3388 3388           * command needs to be aborted too.
3389 3389           */
3390 3390          if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
3391 3391                  if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
3392 3392                          slot_status = 0x1;
3393 3393                          abort_tags = 0x1;
3394 3394                          goto out;
3395 3395                  } else {
3396 3396                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3397 3397                              "ahci_reject_all_abort_pkts return directly "
3398 3398                              "port %d no needs to reject any outstanding "
3399 3399                              "commands", port);
3400 3400                          return;
3401 3401                  }
3402 3402          }
3403 3403  
3404 3404          if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
3405 3405                  slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3406 3406                      (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
3407 3407                  abort_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
3408 3408          } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
3409 3409                  slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3410 3410                      (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
3411 3411                  abort_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
3412 3412          }
3413 3413  
3414 3414  out:
3415 3415          /* No need to do mop when there is no outstanding commands */
3416 3416          if (slot_status != 0) {
3417 3417                  ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
3418 3418                  ahci_portp->ahciport_mop_in_progress++;
3419 3419  
3420 3420                  ahci_mop_commands(ahci_ctlp,
3421 3421                      ahci_portp,
3422 3422                      slot_status,
3423 3423                      0, /* failed tags */
3424 3424                      0, /* timeout tags */
3425 3425                      abort_tags, /* aborting tags */
3426 3426                      0); /* reset tags */
3427 3427          }
3428 3428  }
3429 3429  
3430 3430  #if defined(__lock_lint)
3431 3431  static int
3432 3432  ahci_selftest(dev_info_t *dip, sata_device_t *device)
3433 3433  {
3434 3434          return (SATA_SUCCESS);
3435 3435  }
3436 3436  #endif
3437 3437  
3438 3438  /*
3439 3439   * Initialize fma capabilities and register with IO fault services.
3440 3440   */
3441 3441  static void
3442 3442  ahci_fm_init(ahci_ctl_t *ahci_ctlp)
3443 3443  {
3444 3444          /*
3445 3445           * Need to change iblock to priority for new MSI intr
3446 3446           */
3447 3447          ddi_iblock_cookie_t fm_ibc;
3448 3448  
3449 3449          ahci_ctlp->ahcictl_fm_cap = ddi_getprop(DDI_DEV_T_ANY,
3450 3450              ahci_ctlp->ahcictl_dip,
3451 3451              DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable",
3452 3452              DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
3453 3453              DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
3454 3454  
3455 3455          /* Only register with IO Fault Services if we have some capability */
3456 3456          if (ahci_ctlp->ahcictl_fm_cap) {
3457 3457                  /* Adjust access and dma attributes for FMA */
3458 3458                  accattr.devacc_attr_access = DDI_FLAGERR_ACC;
3459 3459                  buffer_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3460 3460                  rcvd_fis_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3461 3461                  cmd_list_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3462 3462                  cmd_table_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3463 3463  
3464 3464                  /*
3465 3465                   * Register capabilities with IO Fault Services.
3466 3466                   * ahcictl_fm_cap will be updated to indicate
3467 3467                   * capabilities actually supported (not requested.)
3468 3468                   */
3469 3469                  ddi_fm_init(ahci_ctlp->ahcictl_dip,
3470 3470                      &ahci_ctlp->ahcictl_fm_cap, &fm_ibc);
3471 3471  
3472 3472                  if (ahci_ctlp->ahcictl_fm_cap == DDI_FM_NOT_CAPABLE) {
3473 3473                          cmn_err(CE_WARN, "!ahci%d: fma init failed.",
3474 3474                              ddi_get_instance(ahci_ctlp->ahcictl_dip));
3475 3475                          return;
3476 3476                  }
3477 3477                  /*
3478 3478                   * Initialize pci ereport capabilities if ereport
3479 3479                   * capable (should always be.)
3480 3480                   */
3481 3481                  if (DDI_FM_EREPORT_CAP(ahci_ctlp->ahcictl_fm_cap) ||
3482 3482                      DDI_FM_ERRCB_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3483 3483                          pci_ereport_setup(ahci_ctlp->ahcictl_dip);
3484 3484                  }
3485 3485  
3486 3486                  /*
3487 3487                   * Register error callback if error callback capable.
3488 3488                   */
3489 3489                  if (DDI_FM_ERRCB_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3490 3490                          ddi_fm_handler_register(ahci_ctlp->ahcictl_dip,
3491 3491                              ahci_fm_error_cb, (void *) ahci_ctlp);
3492 3492                  }
3493 3493  
3494 3494                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3495 3495                      "ahci_fm_fini: fma enabled.", NULL);
3496 3496          }
3497 3497  }
3498 3498  
3499 3499  /*
3500 3500   * Releases fma capabilities and un-registers with IO fault services.
3501 3501   */
3502 3502  static void
3503 3503  ahci_fm_fini(ahci_ctl_t *ahci_ctlp)
3504 3504  {
3505 3505          /* Only unregister FMA capabilities if registered */
3506 3506          if (ahci_ctlp->ahcictl_fm_cap) {
3507 3507                  /*
3508 3508                   * Un-register error callback if error callback capable.
3509 3509                   */
3510 3510                  if (DDI_FM_ERRCB_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3511 3511                          ddi_fm_handler_unregister(ahci_ctlp->ahcictl_dip);
3512 3512                  }
3513 3513  
3514 3514                  /*
3515 3515                   * Release any resources allocated by pci_ereport_setup()
3516 3516                   */
3517 3517                  if (DDI_FM_EREPORT_CAP(ahci_ctlp->ahcictl_fm_cap) ||
3518 3518                      DDI_FM_ERRCB_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3519 3519                          pci_ereport_teardown(ahci_ctlp->ahcictl_dip);
3520 3520                  }
3521 3521  
3522 3522                  /* Unregister from IO Fault Services */
3523 3523                  ddi_fm_fini(ahci_ctlp->ahcictl_dip);
3524 3524  
3525 3525                  /* Adjust access and dma attributes for FMA */
3526 3526                  accattr.devacc_attr_access = DDI_DEFAULT_ACC;
3527 3527                  buffer_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3528 3528                  rcvd_fis_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3529 3529                  cmd_list_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3530 3530                  cmd_table_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3531 3531  
3532 3532                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3533 3533                      "ahci_fm_fini: fma disabled.", NULL);
3534 3534          }
3535 3535  }
3536 3536  
3537 3537  /*ARGSUSED*/
3538 3538  static int
3539 3539  ahci_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
3540 3540  {
3541 3541          /*
3542 3542           * as the driver can always deal with an error in any dma or
3543 3543           * access handle, we can just return the fme_status value.
3544 3544           */
3545 3545          pci_ereport_post(dip, err, NULL);
3546 3546          return (err->fme_status);
3547 3547  }
3548 3548  
3549 3549  int
3550 3550  ahci_check_acc_handle(ddi_acc_handle_t handle)
3551 3551  {
3552 3552          ddi_fm_error_t de;
3553 3553  
3554 3554          ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION);
3555 3555          return (de.fme_status);
3556 3556  }
3557 3557  
3558 3558  int
3559 3559  ahci_check_dma_handle(ddi_dma_handle_t handle)
3560 3560  {
3561 3561          ddi_fm_error_t de;
3562 3562  
3563 3563          ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION);
3564 3564          return (de.fme_status);
3565 3565  }
3566 3566  
3567 3567  /*
3568 3568   * Generate an ereport
3569 3569   */
3570 3570  void
3571 3571  ahci_fm_ereport(ahci_ctl_t *ahci_ctlp, char *detail)
3572 3572  {
3573 3573          uint64_t ena;
3574 3574          char buf[FM_MAX_CLASS];
3575 3575  
3576 3576          (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
3577 3577          ena = fm_ena_generate(0, FM_ENA_FMT1);
3578 3578          if (DDI_FM_EREPORT_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3579 3579                  ddi_fm_ereport_post(ahci_ctlp->ahcictl_dip, buf, ena,
3580 3580                      DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8,
3581 3581                      FM_EREPORT_VERSION, NULL);
3582 3582          }
3583 3583  }
3584 3584  
3585 3585  /*
3586 3586   * Check if all handles are correctly allocated.
3587 3587   */
3588 3588  static int
3589 3589  ahci_check_all_handle(ahci_ctl_t *ahci_ctlp)
3590 3590  {
3591 3591          int port;
3592 3592  
3593 3593          if (ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) {
3594 3594                  return (DDI_FAILURE);
3595 3595          }
3596 3596  
3597 3597          for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3598 3598                  ahci_port_t *ahci_portp;
3599 3599  
3600 3600                  if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port))
3601 3601                          continue;
3602 3602  
3603 3603                  ahci_portp = ahci_ctlp->ahcictl_ports[port];
3604 3604  
3605 3605                  mutex_enter(&ahci_portp->ahciport_mutex);
3606 3606                  if (ahci_check_port_handle(ahci_ctlp, port) != DDI_SUCCESS) {
3607 3607                          mutex_exit(&ahci_portp->ahciport_mutex);
3608 3608                          return (DDI_FAILURE);
3609 3609                  }
3610 3610                  mutex_exit(&ahci_portp->ahciport_mutex);
3611 3611          }
3612 3612  
3613 3613          return (DDI_SUCCESS);
3614 3614  }
3615 3615  
3616 3616  /*
3617 3617   * Check the access handles for the controller. Note that
3618 3618   * ahcictl_pci_conf_handle is only used in attach process.
3619 3619   */
3620 3620  static int
3621 3621  ahci_check_ctl_handle(ahci_ctl_t *ahci_ctlp)
3622 3622  {
3623 3623          if ((ahci_check_acc_handle(ahci_ctlp->
3624 3624              ahcictl_pci_conf_handle) != DDI_FM_OK) ||
3625 3625              (ahci_check_acc_handle(ahci_ctlp->
3626 3626              ahcictl_ahci_acc_handle) != DDI_FM_OK)) {
3627 3627                  return (DDI_FAILURE);
3628 3628          }
3629 3629          return (DDI_SUCCESS);
3630 3630  }
3631 3631  
3632 3632  /*
3633 3633   * Check the DMA handles and the access handles of a controller port.
3634 3634   */
3635 3635  static int
3636 3636  ahci_check_port_handle(ahci_ctl_t *ahci_ctlp, int port)
3637 3637  {
3638 3638          ahci_port_t *ahci_portp = ahci_ctlp->ahcictl_ports[port];
3639 3639          int slot;
3640 3640  
3641 3641          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3642 3642  
3643 3643          if ((ahci_check_dma_handle(ahci_portp->
3644 3644              ahciport_rcvd_fis_dma_handle) != DDI_FM_OK) ||
3645 3645              (ahci_check_dma_handle(ahci_portp->
3646 3646              ahciport_cmd_list_dma_handle) != DDI_FM_OK) ||
3647 3647              (ahci_check_acc_handle(ahci_portp->
3648 3648              ahciport_rcvd_fis_acc_handle) != DDI_FM_OK) ||
3649 3649              (ahci_check_acc_handle(ahci_portp->
3650 3650              ahciport_cmd_list_acc_handle) != DDI_FM_OK)) {
3651 3651                  return (DDI_FAILURE);
3652 3652          }
3653 3653          for (slot = 0; slot < ahci_ctlp->ahcictl_num_cmd_slots; slot++) {
3654 3654                  if (ahci_check_slot_handle(ahci_portp, slot)
3655 3655                      != DDI_SUCCESS) {
3656 3656                          return (DDI_FAILURE);
3657 3657                  }
3658 3658          }
3659 3659          return (DDI_SUCCESS);
3660 3660  }
3661 3661  
3662 3662  /*
3663 3663   * Check the DMA handles and the access handles of a cmd table slot.
3664 3664   */
3665 3665  static int
3666 3666  ahci_check_slot_handle(ahci_port_t *ahci_portp, int slot)
3667 3667  {
3668 3668          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3669 3669  
3670 3670          if ((ahci_check_acc_handle(ahci_portp->
3671 3671              ahciport_cmd_tables_acc_handle[slot]) != DDI_FM_OK) ||
3672 3672              (ahci_check_dma_handle(ahci_portp->
3673 3673              ahciport_cmd_tables_dma_handle[slot]) != DDI_FM_OK)) {
3674 3674                  return (DDI_FAILURE);
3675 3675          }
3676 3676          return (DDI_SUCCESS);
3677 3677  }
3678 3678  
3679 3679  /*
3680 3680   * Allocate the ports structure, only called by ahci_attach
3681 3681   */
3682 3682  static int
3683 3683  ahci_alloc_ports_state(ahci_ctl_t *ahci_ctlp)
3684 3684  {
3685 3685          int port, cport = 0;
3686 3686  
3687 3687          AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
3688 3688              "ahci_alloc_ports_state enter", NULL);
3689 3689  
3690 3690          mutex_enter(&ahci_ctlp->ahcictl_mutex);
3691 3691  
3692 3692          /* Allocate structures only for the implemented ports */
3693 3693          for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3694 3694                  if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3695 3695                          AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3696 3696                              "hba port %d not implemented", port);
3697 3697                          continue;
3698 3698                  }
3699 3699  
3700 3700                  ahci_ctlp->ahcictl_cport_to_port[cport] = (uint8_t)port;
3701 3701                  ahci_ctlp->ahcictl_port_to_cport[port] =
3702 3702                      (uint8_t)cport++;
3703 3703  
3704 3704                  if (ahci_alloc_port_state(ahci_ctlp, port) != AHCI_SUCCESS) {
3705 3705                          goto err_out;
3706 3706                  }
3707 3707          }
3708 3708  
3709 3709          mutex_exit(&ahci_ctlp->ahcictl_mutex);
3710 3710          return (AHCI_SUCCESS);
3711 3711  
3712 3712  err_out:
3713 3713          for (port--; port >= 0; port--) {
3714 3714                  if (AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3715 3715                          ahci_dealloc_port_state(ahci_ctlp, port);
3716 3716                  }
3717 3717          }
3718 3718  
3719 3719          mutex_exit(&ahci_ctlp->ahcictl_mutex);
3720 3720          return (AHCI_FAILURE);
3721 3721  }
3722 3722  
3723 3723  /*
3724 3724   * Reverse of ahci_alloc_ports_state(), only called by ahci_detach
3725 3725   */
3726 3726  static void
3727 3727  ahci_dealloc_ports_state(ahci_ctl_t *ahci_ctlp)
3728 3728  {
3729 3729          int port;
3730 3730  
3731 3731          mutex_enter(&ahci_ctlp->ahcictl_mutex);
3732 3732          for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3733 3733                  /* if this port is implemented by the HBA */
3734 3734                  if (AHCI_PORT_IMPLEMENTED(ahci_ctlp, port))
3735 3735                          ahci_dealloc_port_state(ahci_ctlp, port);
3736 3736          }
3737 3737          mutex_exit(&ahci_ctlp->ahcictl_mutex);
3738 3738  }
3739 3739  
3740 3740  /*
3741 3741   * Drain the taskq.
3742 3742   */
3743 3743  static void
3744 3744  ahci_drain_ports_taskq(ahci_ctl_t *ahci_ctlp)
3745 3745  {
3746 3746          ahci_port_t *ahci_portp;
3747 3747          int port;
3748 3748  
3749 3749          for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3750 3750                  if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3751 3751                          continue;
3752 3752                  }
3753 3753  
3754 3754                  ahci_portp = ahci_ctlp->ahcictl_ports[port];
3755 3755  
3756 3756                  mutex_enter(&ahci_portp->ahciport_mutex);
3757 3757                  ddi_taskq_wait(ahci_portp->ahciport_event_taskq);
3758 3758                  mutex_exit(&ahci_portp->ahciport_mutex);
3759 3759          }
3760 3760  }
3761 3761  
3762 3762  /*
3763 3763   * Initialize the controller and all ports. And then try to start the ports
3764 3764   * if there are devices attached.
3765 3765   *
3766 3766   * This routine can be called from three seperate cases: DDI_ATTACH,
3767 3767   * PM_LEVEL_D0 and DDI_RESUME. The DDI_ATTACH case is different from
3768 3768   * other two cases; device signature probing are attempted only during
3769 3769   * DDI_ATTACH case.
3770 3770   */
3771 3771  static int
3772 3772  ahci_initialize_controller(ahci_ctl_t *ahci_ctlp)
3773 3773  {
3774 3774          ahci_port_t *ahci_portp;
3775 3775          ahci_addr_t addr;
3776 3776          int port;
3777 3777  
3778 3778          AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
3779 3779              "ahci_initialize_controller enter", NULL);
3780 3780  
3781 3781          /* Disable the whole controller interrupts */
3782 3782          mutex_enter(&ahci_ctlp->ahcictl_mutex);
3783 3783          ahci_disable_all_intrs(ahci_ctlp);
3784 3784          mutex_exit(&ahci_ctlp->ahcictl_mutex);
3785 3785  
3786 3786          /* Initialize the implemented ports and structures */
3787 3787          for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3788 3788                  if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3789 3789                          continue;
3790 3790                  }
3791 3791  
3792 3792                  ahci_portp = ahci_ctlp->ahcictl_ports[port];
3793 3793                  mutex_enter(&ahci_portp->ahciport_mutex);
3794 3794  
3795 3795                  /*
3796 3796                   * Ensure that the controller is not in the running state
3797 3797                   * by checking every implemented port's PxCMD register
3798 3798                   */
3799 3799                  AHCI_ADDR_SET_PORT(&addr, (uint8_t)port);
3800 3800  
3801 3801                  if (ahci_initialize_port(ahci_ctlp, ahci_portp, &addr)
3802 3802                      != AHCI_SUCCESS) {
3803 3803                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3804 3804                              "ahci_initialize_controller: failed to "
3805 3805                              "initialize port %d", port);
3806 3806                          /*
3807 3807                           * Set the port state to SATA_PSTATE_FAILED if
3808 3808                           * failed to initialize it.
3809 3809                           */
3810 3810                          ahci_portp->ahciport_port_state = SATA_PSTATE_FAILED;
3811 3811                  }
3812 3812  
3813 3813                  mutex_exit(&ahci_portp->ahciport_mutex);
3814 3814          }
3815 3815  
3816 3816          /* Enable the whole controller interrupts */
3817 3817          mutex_enter(&ahci_ctlp->ahcictl_mutex);
3818 3818          ahci_enable_all_intrs(ahci_ctlp);
3819 3819          mutex_exit(&ahci_ctlp->ahcictl_mutex);
3820 3820  
3821 3821          return (AHCI_SUCCESS);
3822 3822  }
3823 3823  
3824 3824  /*
3825 3825   * Reverse of ahci_initialize_controller()
3826 3826   *
3827 3827   * We only need to stop the ports and disable the interrupt.
3828 3828   */
3829 3829  static void
3830 3830  ahci_uninitialize_controller(ahci_ctl_t *ahci_ctlp)
3831 3831  {
3832 3832          ahci_port_t *ahci_portp;
3833 3833          int port;
3834 3834  
3835 3835          AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3836 3836              "ahci_uninitialize_controller enter", NULL);
3837 3837  
3838 3838          /* disable all the interrupts. */
3839 3839          mutex_enter(&ahci_ctlp->ahcictl_mutex);
3840 3840          ahci_disable_all_intrs(ahci_ctlp);
3841 3841          mutex_exit(&ahci_ctlp->ahcictl_mutex);
3842 3842  
3843 3843          for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3844 3844                  if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3845 3845                          continue;
3846 3846                  }
3847 3847  
3848 3848                  ahci_portp = ahci_ctlp->ahcictl_ports[port];
3849 3849  
3850 3850                  /* Stop the port by clearing PxCMD.ST */
3851 3851                  mutex_enter(&ahci_portp->ahciport_mutex);
3852 3852  
3853 3853                  /*
3854 3854                   * Here we must disable the port interrupt because
3855 3855                   * ahci_disable_all_intrs only clear GHC.IE, and IS
3856 3856                   * register will be still set if PxIE is enabled.
3857 3857                   * When ahci shares one IRQ with other drivers, the
3858 3858                   * intr handler may claim the intr mistakenly.
3859 3859                   */
3860 3860                  ahci_disable_port_intrs(ahci_ctlp, port);
3861 3861                  (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
3862 3862                      ahci_portp, port);
3863 3863                  mutex_exit(&ahci_portp->ahciport_mutex);
3864 3864          }
3865 3865  }
3866 3866  
3867 3867  /*
3868 3868   * ahci_alloc_pmult()
3869 3869   * 1. Setting HBA port registers which are necessary for a port multiplier.
3870 3870   *    (Set PxCMD.PMA while PxCMD.ST is '0')
3871 3871   * 2. Allocate ahci_pmult_info structure.
3872 3872   *
3873 3873   * NOTE: Must stop port before the function is called.
3874 3874   */
3875 3875  static void
3876 3876  ahci_alloc_pmult(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
3877 3877  {
3878 3878          uint32_t port_cmd_status;
3879 3879          uint8_t port = ahci_portp->ahciport_port_num;
3880 3880  
3881 3881          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3882 3882  
3883 3883          port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3884 3884              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
3885 3885  
3886 3886          /* The port must have been stopped before. */
3887 3887          ASSERT(!(port_cmd_status & AHCI_CMD_STATUS_ST));
3888 3888  
3889 3889          if (!(port_cmd_status & AHCI_CMD_STATUS_PMA)) {
3890 3890                  /* set PMA bit */
3891 3891                  ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
3892 3892                      (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
3893 3893                      port_cmd_status|AHCI_CMD_STATUS_PMA);
3894 3894  
3895 3895                  AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
3896 3896                      "ahci_alloc_pmult: "
3897 3897                      "PxCMD.PMA bit set at port %d.", port);
3898 3898          }
3899 3899  
3900 3900          /* Allocate port multiplier information structure */
3901 3901          if (ahci_portp->ahciport_pmult_info == NULL) {
3902 3902                  ahci_portp->ahciport_pmult_info = (ahci_pmult_info_t *)
3903 3903                      kmem_zalloc(sizeof (ahci_pmult_info_t), KM_SLEEP);
3904 3904          }
3905 3905  
3906 3906          ASSERT(ahci_portp->ahciport_pmult_info != NULL);
3907 3907  }
3908 3908  
3909 3909  /*
3910 3910   * ahci_dealloc_pmult()
3911 3911   * 1. Clearing related registers when a port multiplier is detached.
3912 3912   *    (Clear PxCMD.PMA while PxCMD.ST is '0')
3913 3913   * 2. Deallocate ahci_pmult_info structure.
3914 3914   *
3915 3915   * NOTE: Must stop port before the function is called.
3916 3916   */
3917 3917  static void
3918 3918  ahci_dealloc_pmult(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
3919 3919  {
3920 3920          uint32_t port_cmd_status;
3921 3921          uint8_t port = ahci_portp->ahciport_port_num;
3922 3922  
3923 3923          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3924 3924  
3925 3925          port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3926 3926              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
3927 3927  
3928 3928          if (port_cmd_status & AHCI_CMD_STATUS_PMA) {
3929 3929                  /* Clear PMA bit */
3930 3930                  ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
3931 3931                      (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
3932 3932                      (port_cmd_status & (~AHCI_CMD_STATUS_PMA)));
3933 3933  
3934 3934                  AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
3935 3935                      "ahci_dealloc_pmult: "
3936 3936                      "PxCMD.PMA bit cleared at port %d.", port);
3937 3937          }
3938 3938  
3939 3939          /* Release port multiplier information structure */
3940 3940          if (ahci_portp->ahciport_pmult_info != NULL) {
3941 3941                  kmem_free(ahci_portp->ahciport_pmult_info,
3942 3942                      sizeof (ahci_pmult_info_t));
3943 3943                  ahci_portp->ahciport_pmult_info = NULL;
3944 3944          }
3945 3945  }
3946 3946  
3947 3947  /*
3948 3948   * Staggered Spin-up.
3949 3949   */
3950 3950  static void
3951 3951  ahci_staggered_spin_up(ahci_ctl_t *ahci_ctlp, uint8_t port)
3952 3952  {
3953 3953          uint32_t cap_status;
3954 3954          uint32_t port_cmd_status;
3955 3955  
3956 3956          ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
3957 3957  
3958 3958          cap_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3959 3959              (uint32_t *)AHCI_GLOBAL_CAP(ahci_ctlp));
3960 3960  
3961 3961          /* Check for staggered spin-up support */
3962 3962          if (!(cap_status & AHCI_HBA_CAP_SSS))
3963 3963                  return;
3964 3964  
3965 3965          port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3966 3966              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
3967 3967  
3968 3968          /* If PxCMD.SUD == 1, no staggered spin-up is needed */
3969 3969          if (port_cmd_status & AHCI_CMD_STATUS_SUD)
3970 3970                  return;
3971 3971  
3972 3972          AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "Spin-up at port %d", port);
3973 3973  
3974 3974          /* Set PxCMD.SUD */
3975 3975          port_cmd_status |= AHCI_CMD_STATUS_SUD;
3976 3976          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
3977 3977              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
3978 3978              port_cmd_status);
3979 3979  }
3980 3980  
3981 3981  /*
3982 3982   * The routine is to initialize a port. First put the port in NotRunning
3983 3983   * state, then enable port interrupt and clear Serror register. And under
3984 3984   * AHCI_ATTACH case, find device signature and then try to start the port.
3985 3985   *
3986 3986   * Called by
3987 3987   *    1. ahci_initialize_controller
3988 3988   *    2. ahci_intr_phyrdy_change (hotplug)
3989 3989   */
3990 3990  static int
3991 3991  ahci_initialize_port(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
3992 3992      ahci_addr_t *addrp)
3993 3993  {
3994 3994          uint32_t port_sstatus, port_task_file, port_cmd_status;
3995 3995          uint8_t port = addrp->aa_port;
3996 3996          boolean_t resuming = B_TRUE;    /*  processing DDI_RESUME */
3997 3997          int ret;
3998 3998  
3999 3999          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4000 4000  
4001 4001          /* AHCI_ADDR_PORT: We've no idea of the attached device here.  */
4002 4002          ASSERT(AHCI_ADDR_IS_PORT(addrp));
4003 4003  
4004 4004          /*
4005 4005           * At the time being, only probe ports/devices and get the types of
4006 4006           * attached devices during DDI_ATTACH. In fact, the device can be
4007 4007           * changed during power state changes, but at the time being, we
4008 4008           * don't support the situation.
4009 4009           */
4010 4010          if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_HOTPLUG) {
4011 4011                  resuming = B_FALSE;
4012 4012          } else {
4013 4013                  /* check for DDI_RESUME case */
4014 4014                  mutex_exit(&ahci_portp->ahciport_mutex);
4015 4015                  mutex_enter(&ahci_ctlp->ahcictl_mutex);
4016 4016                  if (ahci_ctlp->ahcictl_flags & AHCI_ATTACH)
4017 4017                          resuming = B_FALSE;
4018 4018                  mutex_exit(&ahci_ctlp->ahcictl_mutex);
4019 4019                  mutex_enter(&ahci_portp->ahciport_mutex);
4020 4020          }
4021 4021  
4022 4022          if (resuming) {
4023 4023                  /*
4024 4024                   * During the resume, we need to set the PxCLB, PxCLBU, PxFB
4025 4025                   * and PxFBU registers in case these registers were cleared
4026 4026                   * during the suspend.
4027 4027                   */
4028 4028                  AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4029 4029                      "ahci_initialize_port: port %d "
4030 4030                      "set PxCLB, PxCLBU, PxFB and PxFBU "
4031 4031                      "during resume", port);
4032 4032  
4033 4033                  if (ahci_setup_port_base_addresses(ahci_ctlp, ahci_portp) !=
4034 4034                      AHCI_SUCCESS)
4035 4035                          return (AHCI_FAILURE);
4036 4036          }
4037 4037  
4038 4038          port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4039 4039              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
4040 4040  
4041 4041          AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
4042 4042              "ahci_initialize_port: port %d ", port);
4043 4043  
4044 4044          /*
4045 4045           * Check whether the port is in NotRunning state, if not,
4046 4046           * put the port in NotRunning state
4047 4047           */
4048 4048          if (port_cmd_status &
4049 4049              (AHCI_CMD_STATUS_ST |
4050 4050              AHCI_CMD_STATUS_CR |
4051 4051              AHCI_CMD_STATUS_FRE |
4052 4052              AHCI_CMD_STATUS_FR)) {
4053 4053                  (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
4054 4054                      ahci_portp, port);
4055 4055          }
4056 4056  
4057 4057          /* Make sure the drive is spun-up */
4058 4058          ahci_staggered_spin_up(ahci_ctlp, port);
4059 4059  
4060 4060          /* Disable interrupt */
4061 4061          ahci_disable_port_intrs(ahci_ctlp, port);
4062 4062  
4063 4063          /* Device is unknown at first */
4064 4064          AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_UNKNOWN);
4065 4065  
4066 4066          /* Disable the interface power management */
4067 4067          ahci_disable_interface_pm(ahci_ctlp, port);
4068 4068  
4069 4069          port_sstatus = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4070 4070              (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp, port));
4071 4071          port_task_file = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4072 4072              (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
4073 4073  
4074 4074          /* Check physcial link status */
4075 4075          if (SSTATUS_GET_IPM(port_sstatus) == SSTATUS_IPM_NODEV_NOPHYCOM ||
4076 4076              SSTATUS_GET_DET(port_sstatus) == SSTATUS_DET_DEVPRE_NOPHYCOM ||
4077 4077  
4078 4078              /* Check interface status */
4079 4079              port_task_file & AHCI_TFD_STS_BSY ||
4080 4080              port_task_file & AHCI_TFD_STS_DRQ ||
4081 4081  
4082 4082              /* Check whether port reset must be executed */
4083 4083              ahci_ctlp->ahcictl_cap & AHCI_CAP_INIT_PORT_RESET ||
4084 4084  
4085 4085              /* Always reset port on RESUME */
4086 4086              resuming != B_FALSE) {
4087 4087  
4088 4088                  /* Something went wrong, we need do some reset things */
4089 4089                  ret = ahci_port_reset(ahci_ctlp, ahci_portp, addrp);
4090 4090  
4091 4091                  /* Does port reset succeed on HBA port? */
4092 4092                  if (ret != AHCI_SUCCESS) {
4093 4093                          AHCIDBG(AHCIDBG_INIT|AHCIDBG_ERRS, ahci_ctlp,
4094 4094                              "ahci_initialize_port:"
4095 4095                              "port reset failed at port %d", port);
4096 4096                          return (AHCI_FAILURE);
4097 4097                  }
4098 4098  
4099 4099                  /* Is port failed? */
4100 4100                  if (AHCIPORT_GET_STATE(ahci_portp, addrp) &
4101 4101                      SATA_PSTATE_FAILED) {
4102 4102                          AHCIDBG(AHCIDBG_INIT|AHCIDBG_ERRS, ahci_ctlp,
4103 4103                              "ahci_initialize_port: port %d state 0x%x",
4104 4104                              port, ahci_portp->ahciport_port_state);
4105 4105                          return (AHCI_FAILURE);
4106 4106                  }
4107 4107          }
4108 4108  
4109 4109          AHCIPORT_SET_STATE(ahci_portp, addrp, SATA_STATE_READY);
4110 4110          AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "port %d is ready now.", port);
4111 4111  
4112 4112          /*
4113 4113           * Try to get the device signature if the port is not empty.
4114 4114           */
4115 4115          if (!resuming && AHCIPORT_DEV_TYPE(ahci_portp, addrp) !=
4116 4116              SATA_DTYPE_NONE)
4117 4117                  ahci_find_dev_signature(ahci_ctlp, ahci_portp, addrp);
4118 4118  
4119 4119          /* Return directly if no device connected */
4120 4120          if (AHCIPORT_DEV_TYPE(ahci_portp, addrp) == SATA_DTYPE_NONE) {
4121 4121                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4122 4122                      "No device connected to port %d", port);
4123 4123                  goto out;
4124 4124          }
4125 4125  
4126 4126          /* If this is a port multiplier, we need do some initialization */
4127 4127          if (AHCIPORT_DEV_TYPE(ahci_portp, addrp) == SATA_DTYPE_PMULT) {
4128 4128                  AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4129 4129                      "Port multiplier found at port %d", port);
4130 4130                  ahci_alloc_pmult(ahci_ctlp, ahci_portp);
4131 4131          }
4132 4132  
4133 4133          /* Try to start the port */
4134 4134          if (ahci_start_port(ahci_ctlp, ahci_portp, port)
4135 4135              != AHCI_SUCCESS) {
4136 4136                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4137 4137                      "failed to start port %d", port);
4138 4138                  return (AHCI_FAILURE);
4139 4139          }
4140 4140  out:
4141 4141          /* Enable port interrupts */
4142 4142          ahci_enable_port_intrs(ahci_ctlp, port);
4143 4143  
4144 4144          return (AHCI_SUCCESS);
4145 4145  }
4146 4146  
4147 4147  /*
4148 4148   *  Handle hardware defect, and check the capabilities. For example,
4149 4149   *  power management capabilty and MSI capability.
4150 4150   */
4151 4151  static int
4152 4152  ahci_config_space_init(ahci_ctl_t *ahci_ctlp)
4153 4153  {
4154 4154          ushort_t caps_ptr, cap_count, cap;
4155 4155  #if AHCI_DEBUG
4156 4156          ushort_t pmcap, pmcsr;
4157 4157          ushort_t msimc;
4158 4158  #endif
4159 4159          uint8_t revision;
4160 4160  
4161 4161          ahci_ctlp->ahcictl_venid =
4162 4162              pci_config_get16(ahci_ctlp->ahcictl_pci_conf_handle,
4163 4163              PCI_CONF_VENID);
4164 4164  
4165 4165          ahci_ctlp->ahcictl_devid =
4166 4166              pci_config_get16(ahci_ctlp->ahcictl_pci_conf_handle,
4167 4167              PCI_CONF_DEVID);
4168 4168  
4169 4169          /*
4170 4170           * Modify dma_attr_align of ahcictl_buffer_dma_attr. For VT8251, those
4171 4171           * controllers with 0x00 revision id work on 4-byte aligned buffer,
4172 4172           * which is a bug and was fixed after 0x00 revision id controllers.
4173 4173           *
4174 4174           * Moreover, VT8251 cannot use multiple command slots in the command
4175 4175           * list for non-queued commands because the previous register content
4176 4176           * of PxCI can be re-written in the register write, so a flag will be
4177 4177           * set to record this defect - AHCI_CAP_NO_MCMDLIST_NONQUEUE.
4178 4178           *
4179 4179           * For VT8251, software reset also has the same defect as the below
4180 4180           * AMD/ATI chipset. That is, software reset will get failed if 0xf
4181 4181           * is filled in pmport field. Therefore, another software reset need
4182 4182           * to be done with 0 filled in pmport field.
4183 4183           */
4184 4184          if (ahci_ctlp->ahcictl_venid == VIA_VENID) {
4185 4185                  revision = pci_config_get8(ahci_ctlp->ahcictl_pci_conf_handle,
4186 4186                      PCI_CONF_REVID);
4187 4187                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4188 4188                      "revision id = 0x%x", revision);
4189 4189                  if (revision == 0x00) {
4190 4190                          ahci_ctlp->ahcictl_buffer_dma_attr.dma_attr_align = 0x4;
4191 4191                          AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4192 4192                              "change ddi_attr_align to 0x4", NULL);
4193 4193                  }
4194 4194  
4195 4195                  ahci_ctlp->ahcictl_cap |= AHCI_CAP_NO_MCMDLIST_NONQUEUE;
4196 4196                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4197 4197                      "VT8251 cannot use multiple command lists for "
4198 4198                      "non-queued commands", NULL);
4199 4199  
4200 4200                  ahci_ctlp->ahcictl_cap |= AHCI_CAP_SRST_NO_HOSTPORT;
4201 4201          }
4202 4202  
4203 4203          /*
4204 4204           * AMD/ATI SB600 (0x1002,0x4380) AHCI chipset doesn't support 64-bit
4205 4205           * DMA addressing for communication memory descriptors though S64A bit
4206 4206           * of CAP register declares it supports. Even though 64-bit DMA for
4207 4207           * data buffer works on ASUS M2A-VM with newer BIOS, three other
4208 4208           * motherboards are known not, so both AHCI_CAP_BUF_32BIT_DMA and
4209 4209           * AHCI_CAP_COMMU_32BIT_DMA are set for this controller.
4210 4210           *
4211 4211           * Due to certain hardware issue, the chipset must do port reset during
4212 4212           * initialization, otherwise, when retrieving device signature,
4213 4213           * software reset will get time out. So AHCI_CAP_INIT_PORT_RESET flag
4214 4214           * need to set.
4215 4215           *
4216 4216           * For this chipset software reset will get failure if the pmport of
4217 4217           * Register FIS was set with SATA_PMULT_HOSTPORT (0xf) and no port
4218 4218           * multiplier is connected to the port. In order to fix the issue,
4219 4219           * AHCI_CAP_SRST_NO_HOSTPORT flag need to be set, and once software
4220 4220           * reset got failure, the driver will try to do another software reset
4221 4221           * with pmport 0.
4222 4222           */
4223 4223          if (ahci_ctlp->ahcictl_venid == 0x1002 &&
4224 4224              ahci_ctlp->ahcictl_devid == 0x4380) {
4225 4225                  ahci_ctlp->ahcictl_cap |= AHCI_CAP_BUF_32BIT_DMA;
4226 4226                  ahci_ctlp->ahcictl_cap |= AHCI_CAP_COMMU_32BIT_DMA;
4227 4227                  ahci_ctlp->ahcictl_cap |= AHCI_CAP_INIT_PORT_RESET;
4228 4228                  ahci_ctlp->ahcictl_cap |= AHCI_CAP_SRST_NO_HOSTPORT;
4229 4229  
4230 4230                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4231 4231                      "ATI SB600 cannot do 64-bit DMA for both data buffer and "
4232 4232                      "communication memory descriptors though CAP indicates "
4233 4233                      "support, so force it to use 32-bit DMA", NULL);
4234 4234                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4235 4235                      "ATI SB600 need to do a port reset during initialization",
4236 4236                      NULL);
4237 4237                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4238 4238                      "ATI SB600 will get software reset failure if pmport "
4239 4239                      "is set 0xf and no port multiplier is attached", NULL);
4240 4240          }
4241 4241  
4242 4242          /*
4243 4243           * AMD/ATI SB700/710/750/800 and SP5100 AHCI chipset share the same
4244 4244           * vendor ID and device ID (0x1002,0x4391).
4245 4245           *
4246 4246           * SB700/750 AHCI chipset on some boards doesn't support 64-bit
4247 4247           * DMA addressing for communication memory descriptors though S64A bit
4248 4248           * of CAP register declares the support. However, it does support
4249 4249           * 64-bit DMA for data buffer. So only AHCI_CAP_COMMU_32BIT_DMA is
4250 4250           * set for this controller.
4251 4251           *
4252 4252           * SB710 has the same initialization issue as SB600, so it also need
4253 4253           * a port reset. That is AHCI_CAP_INIT_PORT_RESET need to set for it.
4254 4254           *
4255 4255           * SB700 also has the same issue about software reset, and thus
4256 4256           * AHCI_CAP_SRST_NO_HOSTPORT flag also is needed.
4257 4257           */
4258 4258          if (ahci_ctlp->ahcictl_venid == 0x1002 &&
4259 4259              ahci_ctlp->ahcictl_devid == 0x4391) {
4260 4260                  ahci_ctlp->ahcictl_cap |= AHCI_CAP_COMMU_32BIT_DMA;
4261 4261                  ahci_ctlp->ahcictl_cap |= AHCI_CAP_INIT_PORT_RESET;
4262 4262                  ahci_ctlp->ahcictl_cap |= AHCI_CAP_SRST_NO_HOSTPORT;
4263 4263  
4264 4264                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4265 4265                      "ATI SB700/750 cannot do 64-bit DMA for communication "
4266 4266                      "memory descriptors though CAP indicates support, "
4267 4267                      "so force it to use 32-bit DMA", NULL);
4268 4268                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4269 4269                      "ATI SB710 need to do a port reset during initialization",
4270 4270                      NULL);
4271 4271                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4272 4272                      "ATI SB700 will get software reset failure if pmport "
4273 4273                      "is set 0xf and no port multiplier is attached", NULL);
4274 4274          }
4275 4275  
4276 4276          /*
4277 4277           * Check if capabilities list is supported and if so,
4278 4278           * get initial capabilities pointer and clear bits 0,1.
4279 4279           */
4280 4280          if (pci_config_get16(ahci_ctlp->ahcictl_pci_conf_handle,
4281 4281              PCI_CONF_STAT) & PCI_STAT_CAP) {
4282 4282                  caps_ptr = P2ALIGN(pci_config_get8(
4283 4283                      ahci_ctlp->ahcictl_pci_conf_handle,
4284 4284                      PCI_CONF_CAP_PTR), 4);
4285 4285          } else {
4286 4286                  caps_ptr = PCI_CAP_NEXT_PTR_NULL;
4287 4287          }
4288 4288  
4289 4289          /*
4290 4290           * Walk capabilities if supported.
4291 4291           */
4292 4292          for (cap_count = 0; caps_ptr != PCI_CAP_NEXT_PTR_NULL; ) {
4293 4293  
4294 4294                  /*
4295 4295                   * Check that we haven't exceeded the maximum number of
4296 4296                   * capabilities and that the pointer is in a valid range.
4297 4297                   */
4298 4298                  if (++cap_count > PCI_CAP_MAX_PTR) {
4299 4299                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
4300 4300                              "too many device capabilities", NULL);
4301 4301                          return (AHCI_FAILURE);
4302 4302                  }
4303 4303                  if (caps_ptr < PCI_CAP_PTR_OFF) {
4304 4304                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
4305 4305                              "capabilities pointer 0x%x out of range",
4306 4306                              caps_ptr);
4307 4307                          return (AHCI_FAILURE);
4308 4308                  }
4309 4309  
4310 4310                  /*
4311 4311                   * Get next capability and check that it is valid.
4312 4312                   * For now, we only support power management.
4313 4313                   */
4314 4314                  cap = pci_config_get8(ahci_ctlp->ahcictl_pci_conf_handle,
4315 4315                      caps_ptr);
4316 4316                  switch (cap) {
4317 4317                  case PCI_CAP_ID_PM:
4318 4318  
4319 4319                          /* power management supported */
4320 4320                          ahci_ctlp->ahcictl_cap |= AHCI_CAP_PM;
4321 4321  
4322 4322                          /* Save PMCSR offset */
4323 4323                          ahci_ctlp->ahcictl_pmcsr_offset = caps_ptr + PCI_PMCSR;
4324 4324  
4325 4325  #if AHCI_DEBUG
4326 4326                          pmcap = pci_config_get16(
4327 4327                              ahci_ctlp->ahcictl_pci_conf_handle,
4328 4328                              caps_ptr + PCI_PMCAP);
4329 4329                          pmcsr = pci_config_get16(
4330 4330                              ahci_ctlp->ahcictl_pci_conf_handle,
4331 4331                              ahci_ctlp->ahcictl_pmcsr_offset);
4332 4332                          AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4333 4333                              "Power Management capability found PCI_PMCAP "
4334 4334                              "= 0x%x PCI_PMCSR = 0x%x", pmcap, pmcsr);
4335 4335                          if ((pmcap & 0x3) == 0x3)
4336 4336                                  AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4337 4337                                      "PCI Power Management Interface "
4338 4338                                      "spec 1.2 compliant", NULL);
4339 4339  #endif
4340 4340                          break;
4341 4341  
4342 4342                  case PCI_CAP_ID_MSI:
4343 4343  #if AHCI_DEBUG
4344 4344                          msimc = pci_config_get16(
4345 4345                              ahci_ctlp->ahcictl_pci_conf_handle,
4346 4346                              caps_ptr + PCI_MSI_CTRL);
4347 4347                          AHCIDBG(AHCIDBG_MSI, ahci_ctlp,
4348 4348                              "Message Signaled Interrupt capability found "
4349 4349                              "MSICAP_MC.MMC = 0x%x", (msimc & 0xe) >> 1);
4350 4350  #endif
4351 4351                          AHCIDBG(AHCIDBG_MSI, ahci_ctlp,
4352 4352                              "MSI capability found", NULL);
4353 4353                          break;
4354 4354  
4355 4355                  case PCI_CAP_ID_PCIX:
4356 4356                          AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4357 4357                              "PCI-X capability found", NULL);
4358 4358                          break;
4359 4359  
4360 4360                  case PCI_CAP_ID_PCI_E:
4361 4361                          AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4362 4362                              "PCI Express capability found", NULL);
4363 4363                          break;
4364 4364  
4365 4365                  case PCI_CAP_ID_MSI_X:
4366 4366                          AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4367 4367                              "MSI-X capability found", NULL);
4368 4368                          break;
4369 4369  
4370 4370                  case PCI_CAP_ID_SATA:
4371 4371                          AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4372 4372                              "SATA capability found", NULL);
4373 4373                          break;
4374 4374  
4375 4375                  case PCI_CAP_ID_VS:
4376 4376                          AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4377 4377                              "Vendor Specific capability found", NULL);
4378 4378                          break;
4379 4379  
4380 4380                  default:
4381 4381                          AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4382 4382                              "unrecognized capability 0x%x", cap);
4383 4383                          break;
4384 4384                  }
4385 4385  
4386 4386                  /*
4387 4387                   * Get next capabilities pointer and clear bits 0,1.
4388 4388                   */
4389 4389                  caps_ptr = P2ALIGN(pci_config_get8(
4390 4390                      ahci_ctlp->ahcictl_pci_conf_handle,
4391 4391                      (caps_ptr + PCI_CAP_NEXT_PTR)), 4);
4392 4392          }
4393 4393  
4394 4394          return (AHCI_SUCCESS);
4395 4395  }
4396 4396  
4397 4397  /*
4398 4398   * Read/Write a register at port multiplier by SATA READ PORTMULT / SATA WRITE
4399 4399   * PORTMULT command. SYNC & POLLING mode is used.
4400 4400   */
4401 4401  static int
4402 4402  ahci_rdwr_pmult(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4403 4403      uint8_t regn, uint32_t *pregv, uint8_t type)
4404 4404  {
4405 4405          ahci_port_t *ahci_portp;
4406 4406          ahci_addr_t pmult_addr;
4407 4407          sata_pkt_t *spkt;
4408 4408          sata_cmd_t *scmd;
4409 4409          sata_device_t sata_device;
4410 4410          uint8_t port = addrp->aa_port;
4411 4411          uint8_t pmport = addrp->aa_pmport;
4412 4412          uint8_t cport;
4413 4413          uint32_t intr_mask;
4414 4414          int rval;
4415 4415          char portstr[10];
4416 4416  
4417 4417          SET_PORTSTR(portstr, addrp);
4418 4418          cport = ahci_ctlp->ahcictl_port_to_cport[port];
4419 4419          ahci_portp = ahci_ctlp->ahcictl_ports[port];
4420 4420  
4421 4421          ASSERT(AHCI_ADDR_IS_PMPORT(addrp) || AHCI_ADDR_IS_PMULT(addrp));
4422 4422          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4423 4423  
4424 4424          /* Check the existence of the port multiplier */
4425 4425          if (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT)
4426 4426                  return (AHCI_FAILURE);
4427 4427  
4428 4428          /* Request a READ/WRITE PORTMULT sata packet. */
4429 4429          bzero(&sata_device, sizeof (sata_device_t));
4430 4430          sata_device.satadev_addr.cport = cport;
4431 4431          sata_device.satadev_addr.pmport = pmport;
4432 4432          sata_device.satadev_addr.qual = SATA_ADDR_PMULT;
4433 4433          sata_device.satadev_rev = SATA_DEVICE_REV;
4434 4434  
4435 4435          /*
4436 4436           * Make sure no command is outstanding here. All R/W PMULT requests
4437 4437           * come from
4438 4438           *
4439 4439           * 1. ahci_attach()
4440 4440           *    The port should be empty.
4441 4441           *
4442 4442           * 2. ahci_tran_probe_port()
4443 4443           *    Any request from SATA framework (via ahci_tran_start) should be
4444 4444           *    rejected if R/W PMULT command is outstanding.
4445 4445           *
4446 4446           *    If we are doing mopping, do not check those flags because no
4447 4447           *    command will be actually outstanding.
4448 4448           *
4449 4449           *    If the port has been occupied by any other commands, the probe
4450 4450           *    function will return a SATA_RETRY. SATA framework will retry
4451 4451           *    later.
4452 4452           */
4453 4453          if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
4454 4454                  AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4455 4455                      "R/W PMULT failed: R/W PMULT in progress at port %d.",
4456 4456                      port, ahci_portp->ahciport_flags);
4457 4457                  return (AHCI_FAILURE);
4458 4458          }
4459 4459  
4460 4460          if (!(ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) && (
4461 4461              ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) ||
4462 4462              NCQ_CMD_IN_PROGRESS(ahci_portp) ||
4463 4463              NON_NCQ_CMD_IN_PROGRESS(ahci_portp))) {
4464 4464                  AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4465 4465                      "R/W PMULT failed: port %d is occupied (flags 0x%x).",
4466 4466                      port, ahci_portp->ahciport_flags);
4467 4467                  return (AHCI_FAILURE);
4468 4468          }
4469 4469  
4470 4470          /*
4471 4471           * The port multiplier is gone. This may happen when
4472 4472           * 1. Cutting off the power of an enclosure. The device lose the power
4473 4473           *    before port multiplier.
4474 4474           * 2. Disconnecting the port multiplier during hot-plugging a sub-drive.
4475 4475           *
4476 4476           * The issued command should be aborted and the following command
4477 4477           * should not be continued.
4478 4478           */
4479 4479          if (!(ahci_portp->ahciport_port_state & SATA_STATE_READY)) {
4480 4480                  AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4481 4481                      "READ/WRITE PMULT failed: "
4482 4482                      "port-mult is removed from port %d", port);
4483 4483                  return (AHCI_FAILURE);
4484 4484          }
4485 4485  
4486 4486          ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_RDWR_PMULT;
4487 4487  
4488 4488          spkt = sata_get_rdwr_pmult_pkt(ahci_ctlp->ahcictl_dip,
4489 4489              &sata_device, regn, *pregv, type);
4490 4490  
4491 4491          /*
4492 4492           * READ/WRITE PORTMULT command is intended to sent to the control port
4493 4493           * of the port multiplier.
4494 4494           */
4495 4495          AHCI_ADDR_SET_PMULT(&pmult_addr, addrp->aa_port);
4496 4496  
4497 4497          ahci_portp->ahciport_rdwr_pmult_pkt = spkt;
4498 4498  
4499 4499          /* No interrupt here. Store the interrupt enable mask. */
4500 4500          intr_mask = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4501 4501              (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port));
4502 4502          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
4503 4503              (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port), 0);
4504 4504  
4505 4505          rval = ahci_do_sync_start(ahci_ctlp, ahci_portp, &pmult_addr, spkt);
4506 4506  
4507 4507          if (rval == AHCI_SUCCESS &&
4508 4508              spkt->satapkt_reason == SATA_PKT_COMPLETED) {
4509 4509                  if (type == SATA_RDWR_PMULT_PKT_TYPE_READ) {
4510 4510                          scmd = &spkt->satapkt_cmd;
4511 4511                          *pregv = scmd->satacmd_lba_high_lsb << 24 |
4512 4512                              scmd->satacmd_lba_mid_lsb << 16 |
4513 4513                              scmd->satacmd_lba_low_lsb << 8 |
4514 4514                              scmd->satacmd_sec_count_lsb;
4515 4515                  }
4516 4516          } else {
4517 4517                  /* Failed or not completed. */
4518 4518                  AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4519 4519                      "ahci_rdwr_pmult: cannot [%s] %s[%d] at port %s",
4520 4520                      type == SATA_RDWR_PMULT_PKT_TYPE_READ?"Read":"Write",
4521 4521                      AHCI_ADDR_IS_PMULT(addrp)?"gscr":"pscr", regn, portstr);
4522 4522                  rval = AHCI_FAILURE;
4523 4523          }
4524 4524  out:
4525 4525          /* Restore the interrupt mask */
4526 4526          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
4527 4527              (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port), intr_mask);
4528 4528  
4529 4529          ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_RDWR_PMULT;
4530 4530          ahci_portp->ahciport_rdwr_pmult_pkt = NULL;
4531 4531          sata_free_rdwr_pmult_pkt(spkt);
4532 4532          return (rval);
4533 4533  }
4534 4534  
4535 4535  static int
4536 4536  ahci_read_pmult(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4537 4537      uint8_t regn, uint32_t *pregv)
4538 4538  {
4539 4539          return ahci_rdwr_pmult(ahci_ctlp, addrp, regn, pregv,
4540 4540              SATA_RDWR_PMULT_PKT_TYPE_READ);
4541 4541  }
4542 4542  
4543 4543  static int
4544 4544  ahci_write_pmult(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4545 4545      uint8_t regn, uint32_t regv)
4546 4546  {
4547 4547          return ahci_rdwr_pmult(ahci_ctlp, addrp, regn, ®v,
4548 4548              SATA_RDWR_PMULT_PKT_TYPE_WRITE);
4549 4549  }
4550 4550  
4551 4551  #define READ_PMULT(addrp, r, pv, out)                                   \
4552 4552          if (ahci_read_pmult(ahci_ctlp, addrp, r, pv) != AHCI_SUCCESS)   \
4553 4553                  goto out;
4554 4554  
4555 4555  #define WRITE_PMULT(addrp, r, v, out)                                   \
4556 4556          if (ahci_write_pmult(ahci_ctlp, addrp, r, v) != AHCI_SUCCESS)   \
4557 4557                  goto out;
4558 4558  
4559 4559  /*
4560 4560   * Update sata registers on port multiplier, including GSCR/PSCR registers.
4561 4561   * ahci_update_pmult_gscr()
4562 4562   * ahci_update_pmult_pscr()
4563 4563   */
4564 4564  static int
4565 4565  ahci_update_pmult_gscr(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4566 4566      sata_pmult_gscr_t *sg)
4567 4567  {
4568 4568          ASSERT(MUTEX_HELD(
4569 4569              &ahci_ctlp->ahcictl_ports[addrp->aa_port]->ahciport_mutex));
4570 4570  
4571 4571          READ_PMULT(addrp, SATA_PMULT_GSCR0, &sg->gscr0, err);
4572 4572          READ_PMULT(addrp, SATA_PMULT_GSCR1, &sg->gscr1, err);
4573 4573          READ_PMULT(addrp, SATA_PMULT_GSCR2, &sg->gscr2, err);
4574 4574          READ_PMULT(addrp, SATA_PMULT_GSCR64, &sg->gscr64, err);
4575 4575  
4576 4576          return (AHCI_SUCCESS);
4577 4577  
4578 4578  err:    /* R/W PMULT error */
4579 4579          return (AHCI_FAILURE);
4580 4580  }
4581 4581  
4582 4582  static int
4583 4583  ahci_update_pmult_pscr(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4584 4584      sata_device_t *sd)
4585 4585  {
4586 4586          ASSERT(AHCI_ADDR_IS_PMPORT(addrp));
4587 4587          ASSERT(MUTEX_HELD(
4588 4588              &ahci_ctlp->ahcictl_ports[addrp->aa_port]->ahciport_mutex));
4589 4589  
4590 4590          READ_PMULT(addrp, SATA_PMULT_REG_SSTS, &sd->satadev_scr.sstatus, err);
4591 4591          READ_PMULT(addrp, SATA_PMULT_REG_SERR, &sd->satadev_scr.serror, err);
4592 4592          READ_PMULT(addrp, SATA_PMULT_REG_SCTL, &sd->satadev_scr.scontrol, err);
4593 4593          READ_PMULT(addrp, SATA_PMULT_REG_SACT, &sd->satadev_scr.sactive, err);
4594 4594  
4595 4595          return (AHCI_SUCCESS);
4596 4596  
4597 4597  err:    /* R/W PMULT error */
4598 4598          return (AHCI_FAILURE);
4599 4599  }
4600 4600  
4601 4601  /*
4602 4602   * ahci_initialize_pmult()
4603 4603   *
4604 4604   * Initialize a port multiplier, including
4605 4605   * 1. Enable FEATURES register at port multiplier. (SATA Chp.16)
4606 4606   * 2. Redefine MASK register. (SATA Chap 16.?)
4607 4607   */
4608 4608  static int
4609 4609  ahci_initialize_pmult(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
4610 4610      ahci_addr_t *addrp, sata_device_t *sd)
4611 4611  {
4612 4612          sata_pmult_gscr_t sg;
4613 4613          uint32_t gscr64;
4614 4614          uint8_t port = addrp->aa_port;
4615 4615  
4616 4616          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4617 4617  
4618 4618          AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4619 4619              "[Initialize] Port-multiplier at port %d.", port);
4620 4620  
4621 4621          /*
4622 4622           * Enable features of port multiplier. Currently only
4623 4623           * Asynchronous Notification is enabled.
4624 4624           */
4625 4625          /* Check gscr64 for supported features. */
4626 4626          READ_PMULT(addrp, SATA_PMULT_GSCR64, &gscr64, err);
4627 4627  
4628 4628          if (gscr64 & SATA_PMULT_CAP_SNOTIF) {
4629 4629                  AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4630 4630                      "port %d: Port Multiplier supports "
4631 4631                      "Asynchronous Notification.", port);
4632 4632  
4633 4633                  /* Write to gscr96 to enabled features */
4634 4634                  WRITE_PMULT(addrp, SATA_PMULT_GSCR96,
4635 4635                      SATA_PMULT_CAP_SNOTIF, err);
4636 4636  
4637 4637                  ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
4638 4638                      (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp, port),
4639 4639                      AHCI_SNOTIF_CLEAR_ALL);
4640 4640                  AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4641 4641                      "port %d: PMult PxSNTF cleared.", port);
4642 4642  
4643 4643          }
4644 4644  
4645 4645          /*
4646 4646           * Now we need to update gscr33 register to enable hot-plug interrupt
4647 4647           * for sub devices behind port multiplier.
4648 4648           */
4649 4649          WRITE_PMULT(addrp, SATA_PMULT_GSCR33, (0x1ffff), err);
4650 4650          AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4651 4651              "port %d: gscr33 mask set to %x.", port, (0x1ffff));
4652 4652  
4653 4653          /*
4654 4654           * Fetch the number of device ports of the port multiplier
4655 4655           */
4656 4656          if (ahci_update_pmult_gscr(ahci_ctlp, addrp, &sg) != AHCI_SUCCESS)
4657 4657                  return (AHCI_FAILURE);
4658 4658  
4659 4659          /* Register the port multiplier to SATA Framework. */
4660 4660          mutex_exit(&ahci_portp->ahciport_mutex);
4661 4661          sata_register_pmult(ahci_ctlp->ahcictl_dip, sd, &sg);
4662 4662          mutex_enter(&ahci_portp->ahciport_mutex);
4663 4663  
4664 4664          ahci_portp->ahciport_pmult_info->ahcipmi_num_dev_ports =
4665 4665              sd->satadev_add_info & SATA_PMULT_PORTNUM_MASK;
4666 4666  
4667 4667          AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4668 4668              "port %d: pmult sub-port number updated to %x.", port,
4669 4669              ahci_portp->ahciport_pmult_info->ahcipmi_num_dev_ports);
4670 4670  
4671 4671          /* Till now port-mult is successfully initialized */
4672 4672          ahci_portp->ahciport_port_state |= SATA_DSTATE_PMULT_INIT;
4673 4673          return (AHCI_SUCCESS);
4674 4674  
4675 4675  err:    /* R/W PMULT error */
4676 4676          return (AHCI_FAILURE);
4677 4677  }
4678 4678  
4679 4679  /*
4680 4680   * Initialize a port multiplier port. According to spec, firstly we need
4681 4681   * issue a COMRESET, then a software reset to get its signature.
4682 4682   *
4683 4683   * NOTE: This function should only be called in ahci_probe_pmport()
4684 4684   */
4685 4685  static int
4686 4686  ahci_initialize_pmport(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
4687 4687      ahci_addr_t *addrp)
4688 4688  {
4689 4689          uint32_t finished_tags = 0, reset_tags = 0, slot_status = 0;
4690 4690          uint8_t port = addrp->aa_port;
4691 4691          uint8_t pmport = addrp->aa_pmport;
4692 4692          int ret = AHCI_FAILURE;
4693 4693  
4694 4694          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4695 4695          ASSERT(AHCI_ADDR_IS_PMPORT(addrp));
4696 4696  
4697 4697          AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
4698 4698              "ahci_initialize_pmport: port %d:%d", port, pmport);
4699 4699  
4700 4700          /* Check HBA port state */
4701 4701          if (ahci_portp->ahciport_port_state & SATA_PSTATE_FAILED) {
4702 4702                  AHCIDBG(AHCIDBG_INIT|AHCIDBG_ERRS, ahci_ctlp,
4703 4703                      "ahci_initialize_pmport:"
4704 4704                      "port %d:%d Port Multiplier is failed.",
4705 4705                      port, pmport);
4706 4706                  return (AHCI_FAILURE);
4707 4707          }
4708 4708  
4709 4709          if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_HOTPLUG) {
4710 4710                  return (AHCI_FAILURE);
4711 4711          }
4712 4712          ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_HOTPLUG;
4713 4713  
4714 4714          /* Checking for outstanding commands */
4715 4715          if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
4716 4716                  slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4717 4717                      (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
4718 4718                  reset_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
4719 4719          } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
4720 4720                  slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4721 4721                      (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
4722 4722                  reset_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
4723 4723          }
4724 4724  
4725 4725          ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
4726 4726          ahci_portp->ahciport_mop_in_progress++;
4727 4727  
4728 4728          /* Clear status */
4729 4729          AHCIPORT_SET_STATE(ahci_portp, addrp, SATA_STATE_UNKNOWN);
4730 4730  
4731 4731          /* Firstly assume an unknown device */
4732 4732          AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_UNKNOWN);
4733 4733  
4734 4734          ahci_disable_port_intrs(ahci_ctlp, port);
4735 4735  
4736 4736          /* port reset is necessary for port multiplier port */
4737 4737          if (ahci_pmport_reset(ahci_ctlp, ahci_portp, addrp) != AHCI_SUCCESS) {
4738 4738                  AHCIDBG(AHCIDBG_INIT|AHCIDBG_ERRS, ahci_ctlp,
4739 4739                      "ahci_initialize_pmport:"
4740 4740                      "port reset failed at port %d:%d",
4741 4741                      port, pmport);
4742 4742                  goto out;
4743 4743          }
4744 4744  
4745 4745          /* Is port failed? */
4746 4746          if (AHCIPORT_GET_STATE(ahci_portp, addrp) &
4747 4747              SATA_PSTATE_FAILED) {
4748 4748                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
4749 4749                      "ahci_initialize_pmport: port %d:%d failed. "
4750 4750                      "state = 0x%x", port, pmport,
4751 4751                      ahci_portp->ahciport_port_state);
4752 4752                  goto out;
4753 4753          }
4754 4754  
4755 4755          /* Is there any device attached? */
4756 4756          if (AHCIPORT_GET_DEV_TYPE(ahci_portp, addrp)
4757 4757              == SATA_DTYPE_NONE) {
4758 4758                  /* Do not waste time on an empty port */
4759 4759                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
4760 4760                      "ahci_initialize_pmport: No device is found "
4761 4761                      "at port %d:%d", port, pmport);
4762 4762                  ret = AHCI_SUCCESS;
4763 4763                  goto out;
4764 4764          }
4765 4765  
4766 4766          AHCIPORT_SET_STATE(ahci_portp, addrp, SATA_STATE_READY);
4767 4767          AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4768 4768              "port %d:%d is ready now.", port, pmport);
4769 4769  
4770 4770          /*
4771 4771           * Till now we can assure a device attached to that HBA port and work
4772 4772           * correctly. Now try to get the device signature. This is an optional
4773 4773           * step. If failed, unknown device is assumed, then SATA module will
4774 4774           * continue to use IDENTIFY DEVICE to get the information of the
4775 4775           * device.
4776 4776           */
4777 4777          ahci_find_dev_signature(ahci_ctlp, ahci_portp, addrp);
4778 4778  
4779 4779          ret = AHCI_SUCCESS;
4780 4780  
4781 4781  out:
4782 4782          /* Next try to mop the pending commands */
4783 4783          if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
4784 4784                  finished_tags = ahci_portp->ahciport_pending_tags &
4785 4785                      ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
4786 4786          else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
4787 4787                  finished_tags = ahci_portp->ahciport_pending_ncq_tags &
4788 4788                      ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
4789 4789          reset_tags &= ~finished_tags;
4790 4790  
4791 4791          ahci_mop_commands(ahci_ctlp,
4792 4792              ahci_portp,
4793 4793              slot_status,
4794 4794              0, /* failed tags */
4795 4795              0, /* timeout tags */
4796 4796              0, /* aborted tags */
4797 4797              reset_tags); /* reset tags */
4798 4798  
4799 4799          /* Clear PxSNTF register if supported. */
4800 4800          if (ahci_ctlp->ahcictl_cap & AHCI_CAP_SNTF) {
4801 4801                  ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
4802 4802                      (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp, port),
4803 4803                      AHCI_SNOTIF_CLEAR_ALL);
4804 4804          }
4805 4805  
4806 4806          ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_HOTPLUG;
4807 4807          ahci_enable_port_intrs(ahci_ctlp, port);
4808 4808          return (ret);
4809 4809  }
4810 4810  
4811 4811  /*
4812 4812   * ahci_probe_pmult()
4813 4813   *
4814 4814   * This function will be called to probe a port multiplier, which will
4815 4815   * handle hotplug events on port multiplier ports.
4816 4816   *
4817 4817   * NOTE: Only called from ahci_tran_probe_port()
4818 4818   */
4819 4819  static int
4820 4820  ahci_probe_pmult(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
4821 4821      ahci_addr_t *addrp)
4822 4822  {
4823 4823          sata_device_t sdevice;
4824 4824          ahci_addr_t pmport_addr;
4825 4825          uint32_t gscr32, port_hotplug_tags;
4826 4826          uint32_t pmport_sstatus;
4827 4827          int dev_exists_now = 0, dev_existed_previously = 0;
4828 4828          uint8_t port = addrp->aa_port;
4829 4829          int npmport;
4830 4830  
4831 4831          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4832 4832  
4833 4833          /* The bits in GSCR32 refers to the pmport that has a hot-plug event. */
4834 4834          READ_PMULT(addrp, SATA_PMULT_GSCR32, &gscr32, err);
4835 4835          port_hotplug_tags = gscr32 & AHCI_PMPORT_MASK(ahci_portp);
4836 4836  
4837 4837          do {
4838 4838                  npmport = ddi_ffs(port_hotplug_tags) - 1;
4839 4839                  if (npmport == -1)
4840 4840                          /* no pending hot plug events. */
4841 4841                          return (AHCI_SUCCESS);
4842 4842  
4843 4843                  AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4844 4844                      "hot-plug event at port %d:%d", port, npmport);
4845 4845  
4846 4846                  AHCI_ADDR_SET_PMPORT(&pmport_addr, port, (uint8_t)npmport);
4847 4847  
4848 4848                  /* Check previous device at that port */
4849 4849                  if (AHCIPORT_GET_DEV_TYPE(ahci_portp, &pmport_addr)
4850 4850                      != SATA_DTYPE_NONE)
4851 4851                          dev_existed_previously = 1;
4852 4852  
4853 4853                  /* PxSStatus tells the presence of device. */
4854 4854                  READ_PMULT(&pmport_addr, SATA_PMULT_REG_SSTS,
4855 4855                      &pmport_sstatus, err);
4856 4856  
4857 4857                  if (SSTATUS_GET_DET(pmport_sstatus) ==
4858 4858                      SSTATUS_DET_DEVPRE_PHYCOM)
4859 4859                          dev_exists_now = 1;
4860 4860  
4861 4861                  /*
4862 4862                   * Clear PxSERR is critical. The transition from 0 to 1 will
4863 4863                   * emit a FIS which generates an asynchronous notification
4864 4864                   * event at controller. If we fail to clear the PxSERR, the
4865 4865                   * Async Notif events will no longer be activated on this
4866 4866                   * pmport.
4867 4867                   */
4868 4868                  WRITE_PMULT(&pmport_addr, SATA_PMULT_REG_SERR,
4869 4869                      AHCI_SERROR_CLEAR_ALL, err);
4870 4870  
4871 4871                  bzero((void *)&sdevice, sizeof (sata_device_t));
4872 4872                  sdevice.satadev_addr.cport = ahci_ctlp->
4873 4873                      ahcictl_port_to_cport[port];
4874 4874                  sdevice.satadev_addr.qual = SATA_ADDR_PMPORT;
4875 4875                  sdevice.satadev_addr.pmport = (uint8_t)npmport;
4876 4876                  sdevice.satadev_state = SATA_PSTATE_PWRON;
4877 4877  
4878 4878                  AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4879 4879                      "[Existence] %d -> %d", dev_existed_previously,
4880 4880                      dev_exists_now);
4881 4881  
4882 4882                  if (dev_exists_now) {
4883 4883                          if (dev_existed_previously) {
4884 4884                                  /* Link (may) not change: Exist -> Exist * */
4885 4885                                  AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
4886 4886                                      "ahci_probe_pmult: port %d:%d "
4887 4887                                      "device link lost/established",
4888 4888                                      port, npmport);
4889 4889  
4890 4890                                  mutex_exit(&ahci_portp->ahciport_mutex);
4891 4891                                  sata_hba_event_notify(
4892 4892                                      ahci_ctlp->ahcictl_sata_hba_tran->
4893 4893                                      sata_tran_hba_dip,
4894 4894                                      &sdevice,
4895 4895                                      SATA_EVNT_LINK_LOST|
4896 4896                                      SATA_EVNT_LINK_ESTABLISHED);
4897 4897                                  mutex_enter(&ahci_portp->ahciport_mutex);
4898 4898                          } else {
4899 4899                                  /* Link change: None -> Exist */
4900 4900                                  AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4901 4901                                      "ahci_probe_pmult: port %d:%d "
4902 4902                                      "device link established", port, npmport);
4903 4903  
4904 4904                                  /* Clear port state */
4905 4905                                  AHCIPORT_SET_STATE(ahci_portp, &pmport_addr,
4906 4906                                      SATA_STATE_UNKNOWN);
4907 4907                                  AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4908 4908                                      "ahci_probe_pmult: port %d "
4909 4909                                      "ahciport_port_state [Cleared].", port);
4910 4910  
4911 4911                                  mutex_exit(&ahci_portp->ahciport_mutex);
4912 4912                                  sata_hba_event_notify(
4913 4913                                      ahci_ctlp->ahcictl_sata_hba_tran->
4914 4914                                      sata_tran_hba_dip,
4915 4915                                      &sdevice,
4916 4916                                      SATA_EVNT_LINK_ESTABLISHED);
4917 4917                                  mutex_enter(&ahci_portp->ahciport_mutex);
4918 4918                          }
4919 4919                  } else { /* No device exists now */
4920 4920                          if (dev_existed_previously) {
4921 4921  
4922 4922                                  /* Link change: Exist -> None */
4923 4923                                  AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4924 4924                                      "ahci_probe_pmult: port %d:%d "
4925 4925                                      "device link lost", port, npmport);
4926 4926  
4927 4927                                  /* An existing device is lost. */
4928 4928                                  AHCIPORT_SET_STATE(ahci_portp, &pmport_addr,
4929 4929                                      SATA_STATE_UNKNOWN);
4930 4930                                  AHCIPORT_SET_DEV_TYPE(ahci_portp, &pmport_addr,
4931 4931                                      SATA_DTYPE_NONE);
4932 4932  
4933 4933                                  mutex_exit(&ahci_portp->ahciport_mutex);
4934 4934                                  sata_hba_event_notify(
4935 4935                                      ahci_ctlp->ahcictl_sata_hba_tran->
4936 4936                                      sata_tran_hba_dip,
4937 4937                                      &sdevice,
4938 4938                                      SATA_EVNT_LINK_LOST);
4939 4939                                  mutex_enter(&ahci_portp->ahciport_mutex);
4940 4940                          }
4941 4941                  }
4942 4942  
4943 4943                  CLEAR_BIT(port_hotplug_tags, npmport);
4944 4944          } while (port_hotplug_tags != 0);
4945 4945  
4946 4946          return (AHCI_SUCCESS);
4947 4947  
4948 4948  err:    /* R/W PMULT error */
4949 4949          return (AHCI_FAILURE);
4950 4950  }
4951 4951  
4952 4952  /*
4953 4953   * Probe and initialize a port multiplier port.
4954 4954   * A port multiplier port could only be initilaizer here.
4955 4955   */
4956 4956  static int
4957 4957  ahci_probe_pmport(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
4958 4958      ahci_addr_t *addrp, sata_device_t *sd)
4959 4959  {
4960 4960          uint32_t port_state;
4961 4961          uint8_t port = addrp->aa_port;
4962 4962          ahci_addr_t addr_pmult;
4963 4963  
4964 4964          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4965 4965  
4966 4966          /*
4967 4967           * Check the parent - port multiplier first.
4968 4968           */
4969 4969  
4970 4970          /*
4971 4971           * Parent port multiplier might have been removed. This event will be
4972 4972           * ignored and failure.
4973 4973           */
4974 4974          if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE ||
4975 4975              ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) {
4976 4976                  AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4977 4977                      "ahci_tran_probe_port: "
4978 4978                      "parent device removed, ignore event.", NULL);
4979 4979  
4980 4980                  return (AHCI_FAILURE);
4981 4981          }
4982 4982  
4983 4983          /* The port is ready? */
4984 4984          port_state = ahci_portp->ahciport_port_state;
4985 4985          if (!(port_state & SATA_STATE_READY)) {
4986 4986                  AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4987 4987                      "ahci_tran_probe_port: "
4988 4988                      "parent port-mult is NOT ready.", NULL);
4989 4989  
4990 4990                  if (ahci_restart_port_wait_till_ready(ahci_ctlp,
4991 4991                      ahci_portp, port, AHCI_PORT_RESET, NULL) !=
4992 4992                      AHCI_SUCCESS) {
4993 4993                          AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4994 4994                              "ahci_tran_probe_port: "
4995 4995                              "restart port-mult failed.", NULL);
4996 4996                          return (AHCI_FAILURE);
4997 4997                  }
4998 4998          }
4999 4999  
5000 5000          /*
5001 5001           * If port-mult is restarted due to some reason, we need
5002 5002           * re-initialized the PMult.
5003 5003           */
5004 5004          if (!(port_state & SATA_DSTATE_PMULT_INIT)) {
5005 5005                  /* Initialize registers on a port multiplier */
5006 5006                  AHCI_ADDR_SET_PMULT(&addr_pmult, addrp->aa_port);
5007 5007                  if (ahci_initialize_pmult(ahci_ctlp, ahci_portp,
5008 5008                      &addr_pmult, sd) != AHCI_SUCCESS)
5009 5009                          return (AHCI_FAILURE);
5010 5010          }
5011 5011  
5012 5012          /*
5013 5013           * Then we check the port-mult port
5014 5014           */
5015 5015          /* Is this pmport initialized? */
5016 5016          port_state = AHCIPORT_GET_STATE(ahci_portp, addrp);
5017 5017          if (!(port_state & SATA_STATE_READY)) {
5018 5018  
5019 5019                  /* ahci_initialize_pmport() will set READY state */
5020 5020                  if (ahci_initialize_pmport(ahci_ctlp,
5021 5021                      ahci_portp, addrp) != AHCI_SUCCESS)
5022 5022                          return (AHCI_FAILURE);
5023 5023          }
5024 5024  
5025 5025          return (AHCI_SUCCESS);
5026 5026  }
5027 5027  
5028 5028  /*
5029 5029   * AHCI device reset ...; a single device on one of the ports is reset,
5030 5030   * but the HBA and physical communication remain intact. This is the
5031 5031   * least intrusive.
5032 5032   *
5033 5033   * When issuing a software reset sequence, there should not be other
5034 5034   * commands in the command list, so we will first clear and then re-set
5035 5035   * PxCMD.ST to clear PxCI. And before issuing the software reset,
5036 5036   * the port must be idle and PxTFD.STS.BSY and PxTFD.STS.DRQ must be
5037 5037   * cleared unless command list override (PxCMD.CLO) is supported.
5038 5038   */
5039 5039  static int
5040 5040  ahci_software_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
5041 5041      ahci_addr_t *addrp)
5042 5042  {
5043 5043          ahci_fis_h2d_register_t *h2d_register_fisp;
5044 5044          ahci_cmd_table_t *cmd_table;
5045 5045          ahci_cmd_header_t *cmd_header;
5046 5046          uint32_t port_cmd_status, port_cmd_issue, port_task_file;
5047 5047          int slot, loop_count;
5048 5048          uint8_t port = addrp->aa_port;
5049 5049          uint8_t pmport = addrp->aa_pmport;
5050 5050          int rval = AHCI_FAILURE;
5051 5051  
5052 5052          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
5053 5053  
5054 5054          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
5055 5055              "port %d:%d device software resetting (FIS)", port, pmport);
5056 5056  
5057 5057          /* First clear PxCMD.ST (AHCI v1.2 10.4.1) */
5058 5058          if (ahci_put_port_into_notrunning_state(ahci_ctlp, ahci_portp,
5059 5059              port) != AHCI_SUCCESS) {
5060 5060                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5061 5061                      "ahci_software_reset: cannot stop HBA port %d.", port);
5062 5062                  goto out;
5063 5063          }
5064 5064  
5065 5065          /* Check PxTFD.STS.BSY and PxTFD.STS.DRQ */
5066 5066          port_task_file = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5067 5067              (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
5068 5068  
5069 5069          if (port_task_file & AHCI_TFD_STS_BSY ||
5070 5070              port_task_file & AHCI_TFD_STS_DRQ) {
5071 5071                  if (!(ahci_ctlp->ahcictl_cap & AHCI_CAP_SCLO)) {
5072 5072                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5073 5073                              "PxTFD.STS.BSY/DRQ is set (PxTFD=0x%x), "
5074 5074                              "cannot issue a software reset.", port_task_file);
5075 5075                          goto out;
5076 5076                  }
5077 5077  
5078 5078                  /*
5079 5079                   * If HBA Support CLO, as Command List Override (CAP.SCLO is
5080 5080                   * set), PxCMD.CLO bit should be set before set PxCMD.ST, in
5081 5081                   * order to clear PxTFD.STS.BSY and PxTFD.STS.DRQ.
5082 5082                   */
5083 5083                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5084 5084                      "PxTFD.STS.BSY/DRQ is set, try SCLO.", NULL)
5085 5085  
5086 5086                  port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5087 5087                      (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5088 5088                  ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5089 5089                      (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
5090 5090                      port_cmd_status|AHCI_CMD_STATUS_CLO);
5091 5091  
5092 5092                  /* Waiting till PxCMD.SCLO bit is cleared */
5093 5093                  loop_count = 0;
5094 5094                  do {
5095 5095                          /* Wait for 10 millisec */
5096 5096                          drv_usecwait(AHCI_10MS_USECS);
5097 5097  
5098 5098                          /* We are effectively timing out after 1 sec. */
5099 5099                          if (loop_count++ > 100) {
5100 5100                                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5101 5101                                      "SCLO time out. port %d is busy.", port);
5102 5102                                  goto out;
5103 5103                          }
5104 5104  
5105 5105                          port_cmd_status =
5106 5106                              ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5107 5107                              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5108 5108                  } while (port_cmd_status & AHCI_CMD_STATUS_CLO);
5109 5109  
5110 5110                  /* Re-check */
5111 5111                  port_task_file = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5112 5112                      (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
5113 5113                  if (port_task_file & AHCI_TFD_STS_BSY ||
5114 5114                      port_task_file & AHCI_TFD_STS_DRQ) {
5115 5115                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5116 5116                              "SCLO cannot clear PxTFD.STS.BSY/DRQ (PxTFD=0x%x)",
5117 5117                              port_task_file);
5118 5118                          goto out;
5119 5119                  }
5120 5120          }
5121 5121  
5122 5122          /* Then start port */
5123 5123          if (ahci_start_port(ahci_ctlp, ahci_portp, port)
5124 5124              != AHCI_SUCCESS) {
5125 5125                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5126 5126                      "ahci_software_reset: cannot start AHCI port %d.", port);
5127 5127                  goto out;
5128 5128          }
5129 5129  
5130 5130          /*
5131 5131           * When ahci_port.ahciport_mop_in_progress is set, A non-zero
5132 5132           * ahci_port.ahciport_pending_ncq_tags may fail
5133 5133           * ahci_claim_free_slot(). Actually according to spec, by clearing
5134 5134           * PxCMD.ST there is no command outstanding while executing software
5135 5135           * reseting. Hence we directly use slot 0 instead of
5136 5136           * ahci_claim_free_slot().
5137 5137           */
5138 5138          slot = 0;
5139 5139  
5140 5140          /* Now send the first H2D Register FIS with SRST set to 1 */
5141 5141          cmd_table = ahci_portp->ahciport_cmd_tables[slot];
5142 5142          bzero((void *)cmd_table, ahci_cmd_table_size);
5143 5143  
5144 5144          h2d_register_fisp =
5145 5145              &(cmd_table->ahcict_command_fis.ahcifc_fis.ahcifc_h2d_register);
5146 5146  
5147 5147          SET_FIS_TYPE(h2d_register_fisp, AHCI_H2D_REGISTER_FIS_TYPE);
5148 5148          SET_FIS_PMP(h2d_register_fisp, pmport);
5149 5149          SET_FIS_DEVCTL(h2d_register_fisp, SATA_DEVCTL_SRST);
5150 5150  
5151 5151          /* Set Command Header in Command List */
5152 5152          cmd_header = &ahci_portp->ahciport_cmd_list[slot];
5153 5153          BZERO_DESCR_INFO(cmd_header);
5154 5154          BZERO_PRD_BYTE_COUNT(cmd_header);
5155 5155          SET_COMMAND_FIS_LENGTH(cmd_header, 5);
5156 5156          SET_PORT_MULTI_PORT(cmd_header, pmport);
5157 5157  
5158 5158          SET_CLEAR_BUSY_UPON_R_OK(cmd_header, 1);
5159 5159          SET_RESET(cmd_header, 1);
5160 5160          SET_WRITE(cmd_header, 1);
5161 5161  
5162 5162          (void) ddi_dma_sync(ahci_portp->ahciport_cmd_tables_dma_handle[slot],
5163 5163              0,
5164 5164              ahci_cmd_table_size,
5165 5165              DDI_DMA_SYNC_FORDEV);
5166 5166  
5167 5167          (void) ddi_dma_sync(ahci_portp->ahciport_cmd_list_dma_handle,
5168 5168              slot * sizeof (ahci_cmd_header_t),
5169 5169              sizeof (ahci_cmd_header_t),
5170 5170              DDI_DMA_SYNC_FORDEV);
5171 5171  
5172 5172          /* Indicate to the HBA that a command is active. */
5173 5173          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5174 5174              (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port),
5175 5175              (0x1 << slot));
5176 5176  
5177 5177          loop_count = 0;
5178 5178  
5179 5179          /* Loop till the first command is finished */
5180 5180          do {
5181 5181                  port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5182 5182                      (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
5183 5183  
5184 5184                  /* We are effectively timing out after 1 sec. */
5185 5185                  if (loop_count++ > AHCI_POLLRATE_PORT_SOFTRESET) {
5186 5186                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5187 5187                              "the first SRST FIS is timed out, "
5188 5188                              "loop_count = %d", loop_count);
5189 5189                          goto out;
5190 5190                  }
5191 5191                  /* Wait for 10 millisec */
5192 5192                  drv_usecwait(AHCI_10MS_USECS);
5193 5193          } while (port_cmd_issue & AHCI_SLOT_MASK(ahci_ctlp) & (0x1 << slot));
5194 5194  
5195 5195          AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5196 5196              "ahci_software_reset: 1st loop count: %d, "
5197 5197              "port_cmd_issue = 0x%x, slot = 0x%x",
5198 5198              loop_count, port_cmd_issue, slot);
5199 5199  
5200 5200          /* According to ATA spec, we need wait at least 5 microsecs here. */
5201 5201          drv_usecwait(AHCI_1MS_USECS);
5202 5202  
5203 5203          /* Now send the second H2D Register FIS with SRST cleard to zero */
5204 5204          cmd_table = ahci_portp->ahciport_cmd_tables[slot];
5205 5205          bzero((void *)cmd_table, ahci_cmd_table_size);
5206 5206  
5207 5207          h2d_register_fisp =
5208 5208              &(cmd_table->ahcict_command_fis.ahcifc_fis.ahcifc_h2d_register);
5209 5209  
5210 5210          SET_FIS_TYPE(h2d_register_fisp, AHCI_H2D_REGISTER_FIS_TYPE);
5211 5211          SET_FIS_PMP(h2d_register_fisp, pmport);
5212 5212  
5213 5213          /* Set Command Header in Command List */
5214 5214          cmd_header = &ahci_portp->ahciport_cmd_list[slot];
5215 5215          BZERO_DESCR_INFO(cmd_header);
5216 5216          BZERO_PRD_BYTE_COUNT(cmd_header);
5217 5217          SET_COMMAND_FIS_LENGTH(cmd_header, 5);
5218 5218          SET_PORT_MULTI_PORT(cmd_header, pmport);
5219 5219  
5220 5220          SET_WRITE(cmd_header, 1);
5221 5221  
5222 5222          (void) ddi_dma_sync(ahci_portp->ahciport_cmd_tables_dma_handle[slot],
5223 5223              0,
5224 5224              ahci_cmd_table_size,
5225 5225              DDI_DMA_SYNC_FORDEV);
5226 5226  
5227 5227          (void) ddi_dma_sync(ahci_portp->ahciport_cmd_list_dma_handle,
5228 5228              slot * sizeof (ahci_cmd_header_t),
5229 5229              sizeof (ahci_cmd_header_t),
5230 5230              DDI_DMA_SYNC_FORDEV);
5231 5231  
5232 5232          /* Indicate to the HBA that a command is active. */
5233 5233          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5234 5234              (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port),
5235 5235              (0x1 << slot));
5236 5236  
5237 5237          loop_count = 0;
5238 5238  
5239 5239          /* Loop till the second command is finished */
5240 5240          do {
5241 5241                  port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5242 5242                      (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
5243 5243  
5244 5244                  /* We are effectively timing out after 1 sec. */
5245 5245                  if (loop_count++ > AHCI_POLLRATE_PORT_SOFTRESET) {
5246 5246                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5247 5247                              "the second SRST FIS is timed out, "
5248 5248                              "loop_count = %d", loop_count);
5249 5249                          goto out;
5250 5250                  }
5251 5251  
5252 5252                  /* Wait for 10 millisec */
5253 5253                  drv_usecwait(AHCI_10MS_USECS);
5254 5254          } while (port_cmd_issue & AHCI_SLOT_MASK(ahci_ctlp) & (0x1 << slot));
5255 5255  
5256 5256          AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5257 5257              "ahci_software_reset: 2nd loop count: %d, "
5258 5258              "port_cmd_issue = 0x%x, slot = 0x%x",
5259 5259              loop_count, port_cmd_issue, slot);
5260 5260  
5261 5261          if ((ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) ||
5262 5262              (ahci_check_port_handle(ahci_ctlp, port) != DDI_SUCCESS)) {
5263 5263                  ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
5264 5264                      DDI_SERVICE_UNAFFECTED);
5265 5265                  goto out;
5266 5266          }
5267 5267  
5268 5268          rval = AHCI_SUCCESS;
5269 5269  out:
5270 5270          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5271 5271              "ahci_software_reset: %s at port %d:%d",
5272 5272              rval == AHCI_SUCCESS ? "succeed" : "failed",
5273 5273              port, pmport);
5274 5274  
5275 5275          return (rval);
5276 5276  }
5277 5277  
5278 5278  /*
5279 5279   * AHCI port reset ...; the physical communication between the HBA and device
5280 5280   * on a port are disabled. This is more intrusive.
5281 5281   *
5282 5282   * When an HBA or port reset occurs, Phy communication is going to
5283 5283   * be re-established with the device through a COMRESET followed by the
5284 5284   * normal out-of-band communication sequence defined in Serial ATA. At
5285 5285   * the end of reset, the device, if working properly, will send a D2H
5286 5286   * Register FIS, which contains the device signature. When the HBA receives
5287 5287   * this FIS, it updates PxTFD.STS and PxTFD.ERR register fields, and updates
5288 5288   * the PxSIG register with the signature.
5289 5289   *
5290 5290   * NOTE: It is expected both PxCMD.ST and PxCMD.CR are cleared before the
5291 5291   * function is called. If not, it is assumed the interface is in hung
5292 5292   * condition.
5293 5293   */
5294 5294  static int
5295 5295  ahci_port_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
5296 5296      ahci_addr_t *addrp)
5297 5297  {
5298 5298          ahci_addr_t pmult_addr;
5299 5299          uint32_t port_cmd_status;
5300 5300          uint32_t port_scontrol, port_sstatus;
5301 5301          uint32_t port_task_file;
5302 5302          uint32_t port_state;
5303 5303          uint8_t port = addrp->aa_port;
5304 5304  
5305 5305          int loop_count;
5306 5306          int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
5307 5307  
5308 5308          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
5309 5309  
5310 5310          /* Target is a port multiplier port? */
5311 5311          if (AHCI_ADDR_IS_PMPORT(addrp))
5312 5312                  return (ahci_pmport_reset(ahci_ctlp, ahci_portp, addrp));
5313 5313  
5314 5314          /* Otherwise it must be an HBA port. */
5315 5315          ASSERT(AHCI_ADDR_IS_PORT(addrp));
5316 5316  
5317 5317          AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
5318 5318              "Port %d port resetting...", port);
5319 5319          ahci_portp->ahciport_port_state = 0;
5320 5320  
5321 5321          port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5322 5322              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5323 5323  
5324 5324          /*
5325 5325           * According to the spec, SUD bit should be set here,
5326 5326           * but JMicron JMB363 doesn't follow it, so print
5327 5327           * a debug message.
5328 5328           */
5329 5329          if (!(port_cmd_status & AHCI_CMD_STATUS_SUD))
5330 5330                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5331 5331                      "ahci_port_reset: port %d SUD bit not set", port);
5332 5332  
5333 5333          port_scontrol = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5334 5334              (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port));
5335 5335          SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_COMRESET);
5336 5336  
5337 5337          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5338 5338              (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port),
5339 5339              port_scontrol);
5340 5340  
5341 5341          /* Enable PxCMD.FRE to read device */
5342 5342          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5343 5343              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
5344 5344              port_cmd_status|AHCI_CMD_STATUS_FRE);
5345 5345  
5346 5346          /*
5347 5347           * The port enters P:StartComm state, and the HBA tells the link layer
5348 5348           * to start communication, which involves sending COMRESET to the
5349 5349           * device. And the HBA resets PxTFD.STS to 7Fh.
5350 5350           *
5351 5351           * Give time for COMRESET to percolate, according to the AHCI
5352 5352           * spec, software shall wait at least 1 millisecond before
5353 5353           * clearing PxSCTL.DET
5354 5354           */
5355 5355          drv_usecwait(AHCI_1MS_USECS * 2);
5356 5356  
5357 5357          /* Fetch the SCONTROL again and rewrite the DET part with 0 */
5358 5358          port_scontrol = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5359 5359              (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port));
5360 5360          SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_NOACTION);
5361 5361          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5362 5362              (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port),
5363 5363              port_scontrol);
5364 5364  
5365 5365          /*
5366 5366           * When a COMINIT is received from the device, then the port enters
5367 5367           * P:ComInit state. And HBA sets PxTFD.STS to FFh or 80h. HBA sets
5368 5368           * PxSSTS.DET to 1h to indicate a device is detected but communication
5369 5369           * is not yet established. HBA sets PxSERR.DIAG.X to '1' to indicate
5370 5370           * a COMINIT has been received.
5371 5371           */
5372 5372          /*
5373 5373           * The DET field is valid only if IPM field indicates
5374 5374           * that the interface is in active state.
5375 5375           */
5376 5376          loop_count = 0;
5377 5377          for (;;) {
5378 5378                  port_sstatus = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5379 5379                      (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp, port));
5380 5380  
5381 5381                  if (SSTATUS_GET_IPM(port_sstatus) != SSTATUS_IPM_ACTIVE) {
5382 5382                          /*
5383 5383                           * If the interface is not active, the DET field
5384 5384                           * is considered not accurate. So we want to
5385 5385                           * continue looping.
5386 5386                           */
5387 5387                          SSTATUS_SET_DET(port_sstatus, SSTATUS_DET_NODEV);
5388 5388                  }
5389 5389  
5390 5390                  if (SSTATUS_GET_DET(port_sstatus) == SSTATUS_DET_DEVPRE_PHYCOM)
5391 5391                          break;
5392 5392  
5393 5393                  if (loop_count++ > AHCI_POLLRATE_PORT_SSTATUS) {
5394 5394                          /*
5395 5395                           * We are effectively timing out after 0.1 sec.
5396 5396                           */
5397 5397                          break;
5398 5398                  }
5399 5399  
5400 5400                  /* Wait for 10 millisec */
5401 5401                  drv_usecwait(AHCI_10MS_USECS);
5402 5402          }
5403 5403  
5404 5404          AHCIDBG(AHCIDBG_INIT|AHCIDBG_POLL_LOOP, ahci_ctlp,
5405 5405              "ahci_port_reset: 1st loop count: %d, "
5406 5406              "port_sstatus = 0x%x port %d",
5407 5407              loop_count, port_sstatus, port);
5408 5408  
5409 5409          if (SSTATUS_GET_DET(port_sstatus) != SSTATUS_DET_DEVPRE_PHYCOM) {
5410 5410                  /*
5411 5411                   * Either the port is not active or there
5412 5412                   * is no device present.
5413 5413                   */
5414 5414                  AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_NONE);
5415 5415                  return (AHCI_SUCCESS);
5416 5416          }
5417 5417  
5418 5418          /* Clear port serror register for the port */
5419 5419          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5420 5420              (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
5421 5421              AHCI_SERROR_CLEAR_ALL);
5422 5422  
5423 5423          /*
5424 5424           * Devices should return a FIS contains its signature to HBA after
5425 5425           * COMINIT signal. Check whether a D2H Register FIS is received by
5426 5426           * polling PxTFD.STS.
5427 5427           */
5428 5428          loop_count = 0;
5429 5429          for (;;) {
5430 5430                  port_task_file =
5431 5431                      ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5432 5432                      (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
5433 5433  
5434 5434                  if ((port_task_file & (AHCI_TFD_STS_BSY | AHCI_TFD_STS_DRQ |
5435 5435                      AHCI_TFD_STS_ERR)) == 0)
5436 5436                          break;
5437 5437  
5438 5438                  if (loop_count++ > AHCI_POLLRATE_PORT_TFD_ERROR) {
5439 5439                          /*
5440 5440                           * We are effectively timing out after 11 sec.
5441 5441                           */
5442 5442                          cmn_err(CE_WARN, "!ahci%d: ahci_port_reset port %d "
5443 5443                              "the device hardware has been initialized and "
5444 5444                              "the power-up diagnostics failed",
5445 5445                              instance, port);
5446 5446  
5447 5447                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_port_reset: "
5448 5448                              "port %d: some or all of BSY, DRQ and ERR in "
5449 5449                              "PxTFD.STS are not clear. We need another "
5450 5450                              "software reset.", port);
5451 5451  
5452 5452                          /* Clear port serror register for the port */
5453 5453                          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5454 5454                              (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
5455 5455                              AHCI_SERROR_CLEAR_ALL);
5456 5456  
5457 5457                          AHCI_ADDR_SET_PMULT(&pmult_addr, port);
5458 5458  
5459 5459                          /* Try another software reset. */
5460 5460                          if (ahci_software_reset(ahci_ctlp, ahci_portp,
5461 5461                              &pmult_addr) != AHCI_SUCCESS) {
5462 5462                                  AHCIPORT_SET_STATE(ahci_portp, addrp,
5463 5463                                      SATA_PSTATE_FAILED);
5464 5464                                  return (AHCI_FAILURE);
5465 5465                          }
5466 5466                          break;
5467 5467                  }
5468 5468  
5469 5469                  /* Wait for 10 millisec */
5470 5470                  drv_usecwait(AHCI_10MS_USECS);
5471 5471          }
5472 5472  
5473 5473          AHCIDBG(AHCIDBG_INIT|AHCIDBG_POLL_LOOP, ahci_ctlp,
5474 5474              "ahci_port_reset: 2nd loop count: %d, "
5475 5475              "port_task_file = 0x%x port %d",
5476 5476              loop_count, port_task_file, port);
5477 5477  
5478 5478          /* Clear port serror register for the port */
5479 5479          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5480 5480              (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
5481 5481              AHCI_SERROR_CLEAR_ALL);
5482 5482  
5483 5483          /* Set port as ready */
5484 5484          port_state = AHCIPORT_GET_STATE(ahci_portp, addrp);
5485 5485          AHCIPORT_SET_STATE(ahci_portp, addrp, port_state|SATA_STATE_READY);
5486 5486  
5487 5487          AHCIDBG(AHCIDBG_INFO|AHCIDBG_ERRS, ahci_ctlp,
5488 5488              "ahci_port_reset: succeed at port %d.", port);
5489 5489          return (AHCI_SUCCESS);
5490 5490  }
5491 5491  
5492 5492  /*
5493 5493   * COMRESET on a port multiplier port.
5494 5494   *
5495 5495   * NOTE: Only called in ahci_port_reset()
5496 5496   */
5497 5497  static int
5498 5498  ahci_pmport_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
5499 5499      ahci_addr_t *addrp)
5500 5500  {
5501 5501          uint32_t port_scontrol, port_sstatus, port_serror;
5502 5502          uint32_t port_cmd_status, port_intr_status;
5503 5503          uint32_t port_state;
5504 5504          uint8_t port = addrp->aa_port;
5505 5505          uint8_t pmport = addrp->aa_pmport;
5506 5506          int loop_count;
5507 5507          int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
5508 5508  
5509 5509          AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
5510 5510              "port %d:%d: pmport resetting", port, pmport);
5511 5511  
5512 5512          /* Initialize pmport state */
5513 5513          AHCIPORT_SET_STATE(ahci_portp, addrp, 0);
5514 5514  
5515 5515          READ_PMULT(addrp, SATA_PMULT_REG_SCTL, &port_scontrol, err);
5516 5516          SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_COMRESET);
5517 5517          WRITE_PMULT(addrp, SATA_PMULT_REG_SCTL, port_scontrol, err);
5518 5518  
5519 5519          /* PxCMD.FRE should be set before. */
5520 5520          port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5521 5521              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5522 5522          ASSERT(port_cmd_status & AHCI_CMD_STATUS_FRE);
5523 5523          if (!(port_cmd_status & AHCI_CMD_STATUS_FRE))
5524 5524                  return (AHCI_FAILURE);
5525 5525  
5526 5526          /*
5527 5527           * Give time for COMRESET to percolate, according to the AHCI
5528 5528           * spec, software shall wait at least 1 millisecond before
5529 5529           * clearing PxSCTL.DET
5530 5530           */
5531 5531          drv_usecwait(AHCI_1MS_USECS*2);
5532 5532  
5533 5533          /*
5534 5534           * Fetch the SCONTROL again and rewrite the DET part with 0
5535 5535           * This will generate an Asychronous Notification events.
5536 5536           */
5537 5537          READ_PMULT(addrp, SATA_PMULT_REG_SCTL, &port_scontrol, err);
5538 5538          SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_NOACTION);
5539 5539          WRITE_PMULT(addrp, SATA_PMULT_REG_SCTL, port_scontrol, err);
5540 5540  
5541 5541          /*
5542 5542           * The port enters P:StartComm state, and HBA tells link layer to
5543 5543           * start communication, which involves sending COMRESET to device.
5544 5544           * And the HBA resets PxTFD.STS to 7Fh.
5545 5545           *
5546 5546           * When a COMINIT is received from the device, then the port enters
5547 5547           * P:ComInit state. And HBA sets PxTFD.STS to FFh or 80h. HBA sets
5548 5548           * PxSSTS.DET to 1h to indicate a device is detected but communication
5549 5549           * is not yet established. HBA sets PxSERR.DIAG.X to '1' to indicate
5550 5550           * a COMINIT has been received.
5551 5551           */
5552 5552          /*
5553 5553           * The DET field is valid only if IPM field indicates
5554 5554           * that the interface is in active state.
5555 5555           */
5556 5556          loop_count = 0;
5557 5557          do {
5558 5558                  READ_PMULT(addrp, SATA_PMULT_REG_SSTS, &port_sstatus, err);
5559 5559  
5560 5560                  if (SSTATUS_GET_IPM(port_sstatus) != SSTATUS_IPM_ACTIVE) {
5561 5561                          /*
5562 5562                           * If the interface is not active, the DET field
5563 5563                           * is considered not accurate. So we want to
5564 5564                           * continue looping.
5565 5565                           */
5566 5566                          SSTATUS_SET_DET(port_sstatus, SSTATUS_DET_NODEV);
5567 5567                  }
5568 5568  
5569 5569                  if (loop_count++ > AHCI_POLLRATE_PORT_SSTATUS) {
5570 5570                          /*
5571 5571                           * We are effectively timing out after 0.1 sec.
5572 5572                           */
5573 5573                          break;
5574 5574                  }
5575 5575  
5576 5576                  /* Wait for 10 millisec */
5577 5577                  drv_usecwait(AHCI_10MS_USECS);
5578 5578  
5579 5579          } while (SSTATUS_GET_DET(port_sstatus) != SSTATUS_DET_DEVPRE_PHYCOM);
5580 5580  
5581 5581          AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5582 5582              "ahci_pmport_reset: 1st loop count: %d, "
5583 5583              "port_sstatus = 0x%x port %d:%d",
5584 5584              loop_count, port_sstatus, port, pmport);
5585 5585  
5586 5586          if ((SSTATUS_GET_IPM(port_sstatus) != SSTATUS_IPM_ACTIVE) ||
5587 5587              (SSTATUS_GET_DET(port_sstatus) != SSTATUS_DET_DEVPRE_PHYCOM)) {
5588 5588                  /*
5589 5589                   * Either the port is not active or there
5590 5590                   * is no device present.
5591 5591                   */
5592 5592                  AHCIDBG(AHCIDBG_INIT|AHCIDBG_INFO, ahci_ctlp,
5593 5593                      "ahci_pmport_reset: "
5594 5594                      "no device attached to port %d:%d",
5595 5595                      port, pmport);
5596 5596                  AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_NONE);
5597 5597                  return (AHCI_SUCCESS);
5598 5598          }
5599 5599  
5600 5600          /* Now we can make sure there is a device connected to the port */
5601 5601          /* COMINIT signal is supposed to be received (PxSERR.DIAG.X = '1') */
5602 5602          READ_PMULT(addrp, SATA_PMULT_REG_SERR, &port_serror, err);
5603 5603  
5604 5604          if (!(port_serror & (1 << 26))) {
5605 5605                  cmn_err(CE_WARN, "!ahci%d: ahci_pmport_reset: "
5606 5606                      "COMINIT signal from the device not received port %d:%d",
5607 5607                      instance, port, pmport);
5608 5608  
5609 5609                  AHCIPORT_SET_STATE(ahci_portp, addrp, SATA_PSTATE_FAILED);
5610 5610                  return (AHCI_FAILURE);
5611 5611          }
5612 5612  
5613 5613          /*
5614 5614           * After clear PxSERR register, we will receive a D2H FIS.
5615 5615           * Normally this FIS will cause a IPMS error according to AHCI spec
5616 5616           * v1.2 because there is no command outstanding for it. So we need
5617 5617           * to ignore this error.
5618 5618           */
5619 5619          ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_IGNORE_IPMS;
5620 5620          WRITE_PMULT(addrp, SATA_PMULT_REG_SERR, AHCI_SERROR_CLEAR_ALL, err);
5621 5621  
5622 5622          /* Now we need to check the D2H FIS by checking IPMS error. */
5623 5623          loop_count = 0;
5624 5624          do {
5625 5625                  port_intr_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5626 5626                      (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port));
5627 5627  
5628 5628                  if (loop_count++ > AHCI_POLLRATE_PORT_TFD_ERROR) {
5629 5629                          /*
5630 5630                           * No D2H FIS received. This is possible according
5631 5631                           * to SATA 2.6 spec.
5632 5632                           */
5633 5633                          cmn_err(CE_WARN, "ahci_port_reset: port %d:%d "
5634 5634                              "PxIS.IPMS is not set, we need another "
5635 5635                              "software reset.", port, pmport);
5636 5636  
5637 5637                          break;
5638 5638                  }
5639 5639  
5640 5640                  /* Wait for 10 millisec */
5641 5641                  mutex_exit(&ahci_portp->ahciport_mutex);
5642 5642                  delay(AHCI_10MS_TICKS);
5643 5643                  mutex_enter(&ahci_portp->ahciport_mutex);
5644 5644  
5645 5645          } while (!(port_intr_status & AHCI_INTR_STATUS_IPMS));
5646 5646  
5647 5647          AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5648 5648              "ahci_pmport_reset: 2st loop count: %d, "
5649 5649              "port_sstatus = 0x%x port %d:%d",
5650 5650              loop_count, port_sstatus, port, pmport);
5651 5651  
5652 5652          /* Clear IPMS */
5653 5653          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5654 5654              (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port),
5655 5655              AHCI_INTR_STATUS_IPMS);
5656 5656          ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_IGNORE_IPMS;
5657 5657  
5658 5658          /* This pmport is now ready for ahci_tran_start() */
5659 5659          port_state = AHCIPORT_GET_STATE(ahci_portp, addrp);
5660 5660          AHCIPORT_SET_STATE(ahci_portp, addrp, port_state|SATA_STATE_READY);
5661 5661  
5662 5662          AHCIDBG(AHCIDBG_INFO|AHCIDBG_ERRS, ahci_ctlp,
5663 5663              "ahci_pmport_reset: succeed at port %d:%d", port, pmport);
5664 5664          return (AHCI_SUCCESS);
5665 5665  
5666 5666  err:    /* R/W PMULT error */
5667 5667          /* IPMS flags might be set before. */
5668 5668          ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_IGNORE_IPMS;
5669 5669          AHCIDBG(AHCIDBG_INFO|AHCIDBG_ERRS, ahci_ctlp,
5670 5670              "ahci_pmport_reset: failed at port %d:%d", port, pmport);
5671 5671  
5672 5672          return (AHCI_FAILURE);
5673 5673  }
5674 5674  
5675 5675  /*
5676 5676   * AHCI HBA reset ...; the entire HBA is reset, and all ports are disabled.
5677 5677   * This is the most intrusive.
5678 5678   *
5679 5679   * When an HBA reset occurs, Phy communication will be re-established with
5680 5680   * the device through a COMRESET followed by the normal out-of-band
5681 5681   * communication sequence defined in Serial ATA. At the end of reset, the
5682 5682   * device, if working properly, will send a D2H Register FIS, which contains
5683 5683   * the device signature. When the HBA receives this FIS, it updates PxTFD.STS
5684 5684   * and PxTFD.ERR register fields, and updates the PxSIG register with the
5685 5685   * signature.
5686 5686   *
5687 5687   * Remember to set GHC.AE to 1 before calling ahci_hba_reset.
5688 5688   */
5689 5689  static int
5690 5690  ahci_hba_reset(ahci_ctl_t *ahci_ctlp)
5691 5691  {
5692 5692          ahci_port_t *ahci_portp;
5693 5693          uint32_t ghc_control;
5694 5694          uint8_t port;
5695 5695          int loop_count;
5696 5696          int rval = AHCI_SUCCESS;
5697 5697  
5698 5698          AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp, "HBA resetting",
5699 5699              NULL);
5700 5700  
5701 5701          mutex_enter(&ahci_ctlp->ahcictl_mutex);
5702 5702  
5703 5703          ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5704 5704              (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
5705 5705  
5706 5706          /* Setting GHC.HR to 1, remember GHC.AE is already set to 1 before */
5707 5707          ghc_control |= AHCI_HBA_GHC_HR;
5708 5708          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5709 5709              (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
5710 5710  
5711 5711          /*
5712 5712           * Wait until HBA Reset complete or timeout
5713 5713           */
5714 5714          loop_count = 0;
5715 5715          do {
5716 5716                  ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5717 5717                      (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
5718 5718  
5719 5719                  if (loop_count++ > AHCI_POLLRATE_HBA_RESET) {
5720 5720                          AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
5721 5721                              "ahci hba reset is timing out, "
5722 5722                              "ghc_control = 0x%x", ghc_control);
5723 5723                          /* We are effectively timing out after 1 sec. */
5724 5724                          break;
5725 5725                  }
5726 5726  
5727 5727                  /* Wait for 10 millisec */
5728 5728                  drv_usecwait(AHCI_10MS_USECS);
5729 5729          } while (ghc_control & AHCI_HBA_GHC_HR);
5730 5730  
5731 5731          AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5732 5732              "ahci_hba_reset: 1st loop count: %d, "
5733 5733              "ghc_control = 0x%x", loop_count, ghc_control);
5734 5734  
5735 5735          if (ghc_control & AHCI_HBA_GHC_HR) {
5736 5736                  /* The hba is not reset for some reasons */
5737 5737                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
5738 5738                      "hba reset failed: HBA in a hung or locked state", NULL);
5739 5739                  mutex_exit(&ahci_ctlp->ahcictl_mutex);
5740 5740                  return (AHCI_FAILURE);
5741 5741          }
5742 5742  
5743 5743          /*
5744 5744           * HBA reset will clear (AHCI Spec v1.2 10.4.3) GHC.IE / GHC.AE
5745 5745           */
5746 5746          ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5747 5747              (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
5748 5748          ghc_control |= (AHCI_HBA_GHC_AE | AHCI_HBA_GHC_IE);
5749 5749          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5750 5750              (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
5751 5751  
5752 5752          mutex_exit(&ahci_ctlp->ahcictl_mutex);
5753 5753  
5754 5754          for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
5755 5755                  /* Only check implemented ports */
5756 5756                  if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
5757 5757                          continue;
5758 5758                  }
5759 5759  
5760 5760                  ahci_portp = ahci_ctlp->ahcictl_ports[port];
5761 5761                  mutex_enter(&ahci_portp->ahciport_mutex);
5762 5762  
5763 5763                  /* Make sure the drive is spun-up */
5764 5764                  ahci_staggered_spin_up(ahci_ctlp, port);
5765 5765  
5766 5766                  if (ahci_restart_port_wait_till_ready(ahci_ctlp, ahci_portp,
5767 5767                      port, AHCI_PORT_RESET|AHCI_RESET_NO_EVENTS_UP, NULL) !=
5768 5768                      AHCI_SUCCESS) {
5769 5769                          rval = AHCI_FAILURE;
5770 5770                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5771 5771                              "ahci_hba_reset: port %d failed", port);
5772 5772                          /*
5773 5773                           * Set the port state to SATA_PSTATE_FAILED if
5774 5774                           * failed to initialize it.
5775 5775                           */
5776 5776                          ahci_portp->ahciport_port_state = SATA_PSTATE_FAILED;
5777 5777                  }
5778 5778  
5779 5779                  mutex_exit(&ahci_portp->ahciport_mutex);
5780 5780          }
5781 5781  
5782 5782          return (rval);
5783 5783  }
5784 5784  
5785 5785  /*
5786 5786   * This routine is only called from AHCI_ATTACH or phyrdy change
5787 5787   * case. It first calls software reset, then stop the port and try to
5788 5788   * read PxSIG register to find the type of device attached to the port.
5789 5789   *
5790 5790   * The caller should make sure a valid device exists on specified port and
5791 5791   * physical communication has been established so that the signature could
5792 5792   * be retrieved by software reset.
5793 5793   *
5794 5794   * NOTE: The port interrupts should be disabled before the function is called.
5795 5795   */
5796 5796  static void
5797 5797  ahci_find_dev_signature(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
5798 5798      ahci_addr_t *addrp)
5799 5799  {
5800 5800          ahci_addr_t dev_addr;
5801 5801          uint32_t signature;
5802 5802          uint8_t port = addrp->aa_port;
5803 5803          uint8_t pmport = addrp->aa_pmport;
5804 5804          int rval;
5805 5805  
5806 5806          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
5807 5807          ASSERT(AHCI_ADDR_IS_VALID(addrp));
5808 5808  
5809 5809          /*
5810 5810           * If the HBA doesn't support port multiplier, then the driver
5811 5811           * doesn't need to bother to check port multiplier device.
5812 5812           *
5813 5813           * The second port of ICH7 on ASUS P5W DH deluxe motherboard is
5814 5814           * connected to Silicon Image 4723, to which the two sata drives
5815 5815           * attached can be set with RAID1, RAID0 or Spanning mode.
5816 5816           *
5817 5817           * We found software reset will get failure if port multiplier address
5818 5818           * 0xf is used by software reset, so just ignore the check since
5819 5819           * ICH7 doesn't support port multiplier device at all.
5820 5820           */
5821 5821          if (AHCI_ADDR_IS_PORT(addrp) &&
5822 5822              (ahci_ctlp->ahcictl_cap & AHCI_CAP_PMULT_CBSS)) {
5823 5823                  AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
5824 5824                      "ahci_find_dev_signature enter: port %d", port);
5825 5825  
5826 5826                  /*
5827 5827                   * NOTE: when the ahci address is a HBA port, we do not know
5828 5828                   * it is a device or a port multiplier that attached. we need
5829 5829                   * try a software reset at port multiplier address (0xf
5830 5830                   * pmport)
5831 5831                   */
5832 5832                  AHCI_ADDR_SET_PMULT(&dev_addr, addrp->aa_port);
5833 5833          } else {
5834 5834                  AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
5835 5835                      "ahci_find_dev_signature enter: port %d:%d",
5836 5836                      port, pmport);
5837 5837                  dev_addr = *addrp;
5838 5838          }
5839 5839  
5840 5840          /* Assume it is unknown. */
5841 5841          AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_UNKNOWN);
5842 5842  
5843 5843          /* Issue a software reset to get the signature */
5844 5844          rval = ahci_software_reset(ahci_ctlp, ahci_portp, &dev_addr);
5845 5845          if (rval != AHCI_SUCCESS) {
5846 5846  
5847 5847                  /*
5848 5848                   * Try to do software reset again with pmport set with 0 if
5849 5849                   * the controller is set with AHCI_CAP_SRST_NO_HOSTPORT and
5850 5850                   * the original pmport is set with SATA_PMULT_HOSTPORT (0xf)
5851 5851                   */
5852 5852                  if ((ahci_ctlp->ahcictl_cap & AHCI_CAP_SRST_NO_HOSTPORT) &&
5853 5853                      (dev_addr.aa_pmport == SATA_PMULT_HOSTPORT)) {
5854 5854                          dev_addr.aa_pmport = 0;
5855 5855                          rval = ahci_software_reset(ahci_ctlp, ahci_portp,
5856 5856                              &dev_addr);
5857 5857                  }
5858 5858  
5859 5859                  if (rval != AHCI_SUCCESS) {
5860 5860                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5861 5861                              "ahci_find_dev_signature: software reset failed "
5862 5862                              "at port %d:%d, cannot get signature.",
5863 5863                              port, pmport);
5864 5864  
5865 5865                          AHCIPORT_SET_STATE(ahci_portp, addrp,
5866 5866                              SATA_PSTATE_FAILED);
5867 5867                          return;
5868 5868                  }
5869 5869          }
5870 5870  
5871 5871          /*
5872 5872           * ahci_software_reset has started the port, so we need manually stop
5873 5873           * the port again.
5874 5874           */
5875 5875          if (AHCI_ADDR_IS_PORT(addrp)) {
5876 5876                  if (ahci_put_port_into_notrunning_state(ahci_ctlp,
5877 5877                      ahci_portp, port) != AHCI_SUCCESS) {
5878 5878                          AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5879 5879                              "ahci_find_dev_signature: cannot stop port %d.",
5880 5880                              port);
5881 5881                          ahci_portp->ahciport_port_state = SATA_PSTATE_FAILED;
5882 5882                          return;
5883 5883                  }
5884 5884          }
5885 5885  
5886 5886          /* Now we can make sure that a valid signature is received. */
5887 5887          signature = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5888 5888              (uint32_t *)AHCI_PORT_PxSIG(ahci_ctlp, port));
5889 5889  
5890 5890          if (AHCI_ADDR_IS_PMPORT(addrp)) {
5891 5891                  AHCIDBG(AHCIDBG_INIT|AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
5892 5892                      "ahci_find_dev_signature: signature = 0x%x at port %d:%d",
5893 5893                      signature, port, pmport);
5894 5894          } else {
5895 5895                  AHCIDBG(AHCIDBG_INIT|AHCIDBG_INFO, ahci_ctlp,
5896 5896                      "ahci_find_dev_signature: signature = 0x%x at port %d",
5897 5897                      signature, port);
5898 5898          }
5899 5899  
5900 5900          /* NOTE: Only support ATAPI device at controller port. */
5901 5901          if (signature == AHCI_SIGNATURE_ATAPI && !AHCI_ADDR_IS_PORT(addrp))
5902 5902                  signature = SATA_DTYPE_UNKNOWN;
5903 5903  
5904 5904          switch (signature) {
5905 5905  
5906 5906          case AHCI_SIGNATURE_DISK:
5907 5907                  AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_ATADISK);
5908 5908                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5909 5909                      "Disk is found at port: %d", port);
5910 5910                  break;
5911 5911  
5912 5912          case AHCI_SIGNATURE_ATAPI:
5913 5913                  AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_ATAPI);
5914 5914                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5915 5915                      "ATAPI device is found at port: %d", port);
5916 5916                  break;
5917 5917  
5918 5918          case AHCI_SIGNATURE_PORT_MULTIPLIER:
5919 5919                  /* Port Multiplier cannot recursively attached. */
5920 5920                  ASSERT(AHCI_ADDR_IS_PORT(addrp));
5921 5921                  AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_PMULT);
5922 5922                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5923 5923                      "Port Multiplier is found at port: %d", port);
5924 5924                  break;
5925 5925  
5926 5926          default:
5927 5927                  AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_UNKNOWN);
5928 5928                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5929 5929                      "Unknown device is found at port: %d", port);
5930 5930          }
5931 5931  }
5932 5932  
5933 5933  /*
5934 5934   * According to the spec, to reliably detect hot plug removals, software
5935 5935   * must disable interface power management. Software should perform the
5936 5936   * following initialization on a port after a device is attached:
5937 5937   *   Set PxSCTL.IPM to 3h to disable interface state transitions
5938 5938   *   Set PxCMD.ALPE to '0' to disable aggressive power management
5939 5939   *   Disable device initiated interface power management by SET FEATURE
5940 5940   *
5941 5941   * We can ignore the last item because by default the feature is disabled
5942 5942   */
5943 5943  static void
5944 5944  ahci_disable_interface_pm(ahci_ctl_t *ahci_ctlp, uint8_t port)
5945 5945  {
5946 5946          uint32_t port_scontrol, port_cmd_status;
5947 5947  
5948 5948          port_scontrol = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5949 5949              (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port));
5950 5950          SCONTROL_SET_IPM(port_scontrol, SCONTROL_IPM_DISABLE_BOTH);
5951 5951          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5952 5952              (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port), port_scontrol);
5953 5953  
5954 5954          port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5955 5955              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5956 5956          port_cmd_status &= ~AHCI_CMD_STATUS_ALPE;
5957 5957          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5958 5958              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port), port_cmd_status);
5959 5959  }
5960 5960  
5961 5961  /*
5962 5962   * Start the port - set PxCMD.ST to 1, if PxCMD.FRE is not set
5963 5963   * to 1, then set it firstly.
5964 5964   *
5965 5965   * Each port contains two major DMA engines. One DMA engine walks through
5966 5966   * the command list, and is controlled by PxCMD.ST. The second DMA engine
5967 5967   * copies received FISes into system memory, and is controlled by PxCMD.FRE.
5968 5968   *
5969 5969   * Software shall not set PxCMD.ST to '1' until it verifies that PxCMD.CR
5970 5970   * is '0' and has set PxCMD.FRE is '1'. And software shall not clear
5971 5971   * PxCMD.FRE while PxCMD.ST or PxCMD.CR is set '1'.
5972 5972   *
5973 5973   * Software shall not set PxCMD.ST to '1' unless a functional device is
5974 5974   * present on the port(as determined by PxTFD.STS.BSY = '0',
5975 5975   * PxTFD.STS.DRQ = '0', and PxSSTS.DET = 3h).
5976 5976   */
5977 5977  static int
5978 5978  ahci_start_port(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp, uint8_t port)
5979 5979  {
5980 5980          uint32_t port_cmd_status;
5981 5981  
5982 5982          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
5983 5983  
5984 5984          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_start_port: %d enter", port);
5985 5985  
5986 5986          if (ahci_portp->ahciport_port_state & SATA_PSTATE_FAILED) {
5987 5987                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_start_port failed "
5988 5988                      "the state for port %d is 0x%x",
5989 5989                      port, ahci_portp->ahciport_port_state);
5990 5990                  return (AHCI_FAILURE);
5991 5991          }
5992 5992  
5993 5993          if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
5994 5994                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_start_port failed "
5995 5995                      "no device is attached at port %d", port);
5996 5996                  return (AHCI_FAILURE);
5997 5997          }
5998 5998  
5999 5999          /* First to set PxCMD.FRE before setting PxCMD.ST. */
6000 6000          port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6001 6001              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
6002 6002  
6003 6003          if (!(port_cmd_status & AHCI_CMD_STATUS_FRE)) {
6004 6004                  port_cmd_status |= AHCI_CMD_STATUS_FRE;
6005 6005                  ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6006 6006                      (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
6007 6007                      port_cmd_status);
6008 6008          }
6009 6009  
6010 6010          port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6011 6011              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
6012 6012  
6013 6013          port_cmd_status |= AHCI_CMD_STATUS_ST;
6014 6014  
6015 6015          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6016 6016              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
6017 6017              port_cmd_status);
6018 6018  
6019 6019          ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_STARTED;
6020 6020  
6021 6021          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_start_port: "
6022 6022              "PxCMD.ST set to '1' at port %d", port);
6023 6023  
6024 6024          return (AHCI_SUCCESS);
6025 6025  }
6026 6026  
6027 6027  /*
6028 6028   * Setup PxCLB, PxCLBU, PxFB, and PxFBU for particular port. First, we need
6029 6029   * to make sure PxCMD.ST, PxCMD.CR, PxCMD.FRE, and PxCMD.FR are all cleared.
6030 6030   * Then set PxCLB, PxCLBU, PxFB, and PxFBU.
6031 6031   */
6032 6032  static int
6033 6033  ahci_setup_port_base_addresses(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6034 6034  {
6035 6035          uint8_t port = ahci_portp->ahciport_port_num;
6036 6036          uint32_t port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6037 6037              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
6038 6038  
6039 6039          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6040 6040  
6041 6041          /* Step 1: Make sure both PxCMD.ST and PxCMD.CR are cleared. */
6042 6042          if (port_cmd_status & (AHCI_CMD_STATUS_ST | AHCI_CMD_STATUS_CR)) {
6043 6043                  if (ahci_put_port_into_notrunning_state(ahci_ctlp, ahci_portp,
6044 6044                      port) != AHCI_SUCCESS)
6045 6045                          return (AHCI_FAILURE);
6046 6046  
6047 6047                  port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6048 6048                      (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
6049 6049          }
6050 6050  
6051 6051          /* Step 2: Make sure both PxCMD.FRE and PxCMD.FR are cleared. */
6052 6052          if (port_cmd_status & (AHCI_CMD_STATUS_FRE | AHCI_CMD_STATUS_FR)) {
6053 6053                  int loop_count = 0;
6054 6054  
6055 6055                  /* Clear PxCMD.FRE */
6056 6056                  port_cmd_status &= ~AHCI_CMD_STATUS_FRE;
6057 6057                  ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6058 6058                      (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
6059 6059                      port_cmd_status);
6060 6060  
6061 6061                  /* Wait until PxCMD.FR is cleared */
6062 6062                  for (;;) {
6063 6063                          port_cmd_status =
6064 6064                              ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6065 6065                              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
6066 6066  
6067 6067                          if (!(port_cmd_status & AHCI_CMD_STATUS_FR))
6068 6068                                  break;
6069 6069  
6070 6070                          if (loop_count++ >= AHCI_POLLRATE_PORT_IDLE_FR) {
6071 6071                                  AHCIDBG(AHCIDBG_INIT | AHCIDBG_ERRS, ahci_ctlp,
6072 6072                                      "ahci_setup_port_base_addresses: cannot "
6073 6073                                      "clear PxCMD.FR for port %d.", port);
6074 6074  
6075 6075                                  /*
6076 6076                                   * We are effectively timing out after 0.5 sec.
6077 6077                                   * This value is specified in AHCI spec.
6078 6078                                   */
6079 6079                                  return (AHCI_FAILURE);
6080 6080                          }
6081 6081  
6082 6082                          /* Wait for 1 millisec */
6083 6083                          drv_usecwait(AHCI_1MS_USECS);
6084 6084                  }
6085 6085          }
6086 6086  
6087 6087          /* Step 3: Config Port Command List Base Address */
6088 6088          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6089 6089              (uint32_t *)AHCI_PORT_PxCLB(ahci_ctlp, port),
6090 6090              ahci_portp->ahciport_cmd_list_dma_cookie.dmac_address);
6091 6091  
6092 6092          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6093 6093              (uint32_t *)AHCI_PORT_PxCLBU(ahci_ctlp, port),
6094 6094              ahci_portp->ahciport_cmd_list_dma_cookie.dmac_notused);
6095 6095  
6096 6096          /* Step 4: Config Port Received FIS Base Address */
6097 6097          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6098 6098              (uint32_t *)AHCI_PORT_PxFB(ahci_ctlp, port),
6099 6099              ahci_portp->ahciport_rcvd_fis_dma_cookie.dmac_address);
6100 6100  
6101 6101          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6102 6102              (uint32_t *)AHCI_PORT_PxFBU(ahci_ctlp, port),
6103 6103              ahci_portp->ahciport_rcvd_fis_dma_cookie.dmac_notused);
6104 6104  
6105 6105          return (AHCI_SUCCESS);
6106 6106  }
6107 6107  
6108 6108  /*
6109 6109   * Allocate the ahci_port_t including Received FIS and Command List.
6110 6110   * The argument - port is the physical port number, and not logical
6111 6111   * port number seen by the SATA framework.
6112 6112   */
6113 6113  static int
6114 6114  ahci_alloc_port_state(ahci_ctl_t *ahci_ctlp, uint8_t port)
6115 6115  {
6116 6116          dev_info_t *dip = ahci_ctlp->ahcictl_dip;
6117 6117          ahci_port_t *ahci_portp;
6118 6118          char taskq_name[64] = "event_handle_taskq";
6119 6119  
6120 6120          ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_mutex));
6121 6121  
6122 6122          ahci_portp =
6123 6123              (ahci_port_t *)kmem_zalloc(sizeof (ahci_port_t), KM_SLEEP);
6124 6124  
6125 6125          ahci_ctlp->ahcictl_ports[port] = ahci_portp;
6126 6126          ahci_portp->ahciport_port_num = port;
6127 6127  
6128 6128          /* Initialize the port condition variable */
6129 6129          cv_init(&ahci_portp->ahciport_cv, NULL, CV_DRIVER, NULL);
6130 6130  
6131 6131          /* Initialize the port mutex */
6132 6132          mutex_init(&ahci_portp->ahciport_mutex, NULL, MUTEX_DRIVER,
6133 6133              (void *)(uintptr_t)ahci_ctlp->ahcictl_intr_pri);
6134 6134  
6135 6135          mutex_enter(&ahci_portp->ahciport_mutex);
6136 6136  
6137 6137          /*
6138 6138           * Allocate memory for received FIS structure and
6139 6139           * command list for this port
6140 6140           */
6141 6141          if (ahci_alloc_rcvd_fis(ahci_ctlp, ahci_portp) != AHCI_SUCCESS) {
6142 6142                  goto err_case1;
6143 6143          }
6144 6144  
6145 6145          if (ahci_alloc_cmd_list(ahci_ctlp, ahci_portp) != AHCI_SUCCESS) {
6146 6146                  goto err_case2;
6147 6147          }
6148 6148  
6149 6149          /* Setup PxCMD.CLB, PxCMD.CLBU, PxCMD.FB, and PxCMD.FBU */
6150 6150          if (ahci_setup_port_base_addresses(ahci_ctlp, ahci_portp) !=
6151 6151              AHCI_SUCCESS) {
6152 6152                  goto err_case3;
6153 6153          }
6154 6154  
6155 6155          (void) snprintf(taskq_name + strlen(taskq_name),
6156 6156              sizeof (taskq_name) - strlen(taskq_name),
6157 6157              "_port%d", port);
6158 6158  
6159 6159          /* Create the taskq for the port */
6160 6160          if ((ahci_portp->ahciport_event_taskq = ddi_taskq_create(dip,
6161 6161              taskq_name, 2, TASKQ_DEFAULTPRI, 0)) == NULL) {
6162 6162                  cmn_err(CE_WARN, "!ahci%d: ddi_taskq_create failed for event "
6163 6163                      "handle", ddi_get_instance(ahci_ctlp->ahcictl_dip));
6164 6164                  goto err_case3;
6165 6165          }
6166 6166  
6167 6167          /* Allocate the argument for the taskq */
6168 6168          ahci_portp->ahciport_event_args =
6169 6169              kmem_zalloc(sizeof (ahci_event_arg_t), KM_SLEEP);
6170 6170  
6171 6171          ahci_portp->ahciport_event_args->ahciea_addrp =
6172 6172              kmem_zalloc(sizeof (ahci_addr_t), KM_SLEEP);
6173 6173  
6174 6174          /* Initialize the done queue */
6175 6175          ahci_portp->ahciport_doneq = NULL;
6176 6176          ahci_portp->ahciport_doneqtail = &ahci_portp->ahciport_doneq;
6177 6177          ahci_portp->ahciport_doneq_len = 0;
6178 6178  
6179 6179          mutex_exit(&ahci_portp->ahciport_mutex);
6180 6180  
6181 6181          return (AHCI_SUCCESS);
6182 6182  
6183 6183  err_case3:
6184 6184          ahci_dealloc_cmd_list(ahci_ctlp, ahci_portp);
6185 6185  
6186 6186  err_case2:
6187 6187          ahci_dealloc_rcvd_fis(ahci_portp);
6188 6188  
6189 6189  err_case1:
6190 6190          mutex_exit(&ahci_portp->ahciport_mutex);
6191 6191          mutex_destroy(&ahci_portp->ahciport_mutex);
6192 6192          cv_destroy(&ahci_portp->ahciport_cv);
6193 6193  
6194 6194          kmem_free(ahci_portp, sizeof (ahci_port_t));
6195 6195  
6196 6196          return (AHCI_FAILURE);
6197 6197  }
6198 6198  
6199 6199  /*
6200 6200   * Reverse of ahci_alloc_port_state().
6201 6201   */
6202 6202  static void
6203 6203  ahci_dealloc_port_state(ahci_ctl_t *ahci_ctlp, uint8_t port)
6204 6204  {
6205 6205          ahci_port_t *ahci_portp = ahci_ctlp->ahcictl_ports[port];
6206 6206  
6207 6207          ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_mutex));
6208 6208          ASSERT(ahci_portp != NULL);
6209 6209  
6210 6210          mutex_enter(&ahci_portp->ahciport_mutex);
6211 6211          kmem_free(ahci_portp->ahciport_event_args->ahciea_addrp,
6212 6212              sizeof (ahci_addr_t));
6213 6213          ahci_portp->ahciport_event_args->ahciea_addrp = NULL;
6214 6214          kmem_free(ahci_portp->ahciport_event_args, sizeof (ahci_event_arg_t));
6215 6215          ahci_portp->ahciport_event_args = NULL;
6216 6216          ddi_taskq_destroy(ahci_portp->ahciport_event_taskq);
6217 6217          ahci_dealloc_cmd_list(ahci_ctlp, ahci_portp);
6218 6218          ahci_dealloc_rcvd_fis(ahci_portp);
6219 6219          ahci_dealloc_pmult(ahci_ctlp, ahci_portp);
6220 6220          mutex_exit(&ahci_portp->ahciport_mutex);
6221 6221  
6222 6222          mutex_destroy(&ahci_portp->ahciport_mutex);
6223 6223          cv_destroy(&ahci_portp->ahciport_cv);
6224 6224  
6225 6225          kmem_free(ahci_portp, sizeof (ahci_port_t));
6226 6226  
6227 6227          ahci_ctlp->ahcictl_ports[port] = NULL;
6228 6228  }
6229 6229  
6230 6230  /*
6231 6231   * Allocates memory for the Received FIS Structure
6232 6232   */
6233 6233  static int
6234 6234  ahci_alloc_rcvd_fis(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6235 6235  {
6236 6236          size_t rcvd_fis_size;
6237 6237          size_t ret_len;
6238 6238          uint_t cookie_count;
6239 6239  
6240 6240          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6241 6241  
6242 6242          rcvd_fis_size = sizeof (ahci_rcvd_fis_t);
6243 6243  
6244 6244          /* allocate rcvd FIS dma handle. */
6245 6245          if (ddi_dma_alloc_handle(ahci_ctlp->ahcictl_dip,
6246 6246              &ahci_ctlp->ahcictl_rcvd_fis_dma_attr,
6247 6247              DDI_DMA_SLEEP,
6248 6248              NULL,
6249 6249              &ahci_portp->ahciport_rcvd_fis_dma_handle) !=
6250 6250              DDI_SUCCESS) {
6251 6251                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6252 6252                      "rcvd FIS dma handle alloc failed", NULL);
6253 6253  
6254 6254                  return (AHCI_FAILURE);
6255 6255          }
6256 6256  
6257 6257          if (ddi_dma_mem_alloc(ahci_portp->ahciport_rcvd_fis_dma_handle,
6258 6258              rcvd_fis_size,
6259 6259              &accattr,
6260 6260              DDI_DMA_CONSISTENT,
6261 6261              DDI_DMA_SLEEP,
6262 6262              NULL,
6263 6263              (caddr_t *)&ahci_portp->ahciport_rcvd_fis,
6264 6264              &ret_len,
6265 6265              &ahci_portp->ahciport_rcvd_fis_acc_handle) != 0) {
6266 6266  
6267 6267                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6268 6268                      "rcvd FIS dma mem alloc fail", NULL);
6269 6269                  /* error.. free the dma handle. */
6270 6270                  ddi_dma_free_handle(&ahci_portp->ahciport_rcvd_fis_dma_handle);
6271 6271                  return (AHCI_FAILURE);
6272 6272          }
6273 6273  
6274 6274          if (ddi_dma_addr_bind_handle(ahci_portp->ahciport_rcvd_fis_dma_handle,
6275 6275              NULL,
6276 6276              (caddr_t)ahci_portp->ahciport_rcvd_fis,
6277 6277              rcvd_fis_size,
6278 6278              DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
6279 6279              DDI_DMA_SLEEP,
6280 6280              NULL,
6281 6281              &ahci_portp->ahciport_rcvd_fis_dma_cookie,
6282 6282              &cookie_count) !=  DDI_DMA_MAPPED) {
6283 6283  
6284 6284                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6285 6285                      "rcvd FIS dma handle bind fail", NULL);
6286 6286                  /*  error.. free the dma handle & free the memory. */
6287 6287                  ddi_dma_mem_free(&ahci_portp->ahciport_rcvd_fis_acc_handle);
6288 6288                  ddi_dma_free_handle(&ahci_portp->ahciport_rcvd_fis_dma_handle);
6289 6289                  return (AHCI_FAILURE);
6290 6290          }
6291 6291  
6292 6292          bzero((void *)ahci_portp->ahciport_rcvd_fis, rcvd_fis_size);
6293 6293  
6294 6294          AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "64-bit, dma address: 0x%llx",
6295 6295              ahci_portp->ahciport_rcvd_fis_dma_cookie.dmac_laddress);
6296 6296          AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "32-bit, dma address: 0x%x",
6297 6297              ahci_portp->ahciport_rcvd_fis_dma_cookie.dmac_address);
6298 6298  
6299 6299          return (AHCI_SUCCESS);
6300 6300  }
6301 6301  
6302 6302  /*
6303 6303   * Deallocates the Received FIS Structure
6304 6304   */
6305 6305  static void
6306 6306  ahci_dealloc_rcvd_fis(ahci_port_t *ahci_portp)
6307 6307  {
6308 6308          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6309 6309  
6310 6310          /* Unbind the cmd list dma handle first. */
6311 6311          (void) ddi_dma_unbind_handle(ahci_portp->ahciport_rcvd_fis_dma_handle);
6312 6312  
6313 6313          /* Then free the underlying memory. */
6314 6314          ddi_dma_mem_free(&ahci_portp->ahciport_rcvd_fis_acc_handle);
6315 6315  
6316 6316          /* Now free the handle itself. */
6317 6317          ddi_dma_free_handle(&ahci_portp->ahciport_rcvd_fis_dma_handle);
6318 6318  }
6319 6319  
6320 6320  /*
6321 6321   * Allocates memory for the Command List, which contains up to 32 entries.
6322 6322   * Each entry contains a command header, which is a 32-byte structure that
6323 6323   * includes the pointer to the command table.
6324 6324   */
6325 6325  static int
6326 6326  ahci_alloc_cmd_list(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6327 6327  {
6328 6328          size_t cmd_list_size;
6329 6329          size_t ret_len;
6330 6330          uint_t cookie_count;
6331 6331  
6332 6332          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6333 6333  
6334 6334          cmd_list_size =
6335 6335              ahci_ctlp->ahcictl_num_cmd_slots * sizeof (ahci_cmd_header_t);
6336 6336  
6337 6337          /* allocate cmd list dma handle. */
6338 6338          if (ddi_dma_alloc_handle(ahci_ctlp->ahcictl_dip,
6339 6339              &ahci_ctlp->ahcictl_cmd_list_dma_attr,
6340 6340              DDI_DMA_SLEEP,
6341 6341              NULL,
6342 6342              &ahci_portp->ahciport_cmd_list_dma_handle) != DDI_SUCCESS) {
6343 6343  
6344 6344                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6345 6345                      "cmd list dma handle alloc failed", NULL);
6346 6346                  return (AHCI_FAILURE);
6347 6347          }
6348 6348  
6349 6349          if (ddi_dma_mem_alloc(ahci_portp->ahciport_cmd_list_dma_handle,
6350 6350              cmd_list_size,
6351 6351              &accattr,
6352 6352              DDI_DMA_CONSISTENT,
6353 6353              DDI_DMA_SLEEP,
6354 6354              NULL,
6355 6355              (caddr_t *)&ahci_portp->ahciport_cmd_list,
6356 6356              &ret_len,
6357 6357              &ahci_portp->ahciport_cmd_list_acc_handle) != 0) {
6358 6358  
6359 6359                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6360 6360                      "cmd list dma mem alloc fail", NULL);
6361 6361                  /* error.. free the dma handle. */
6362 6362                  ddi_dma_free_handle(&ahci_portp->ahciport_cmd_list_dma_handle);
6363 6363                  return (AHCI_FAILURE);
6364 6364          }
6365 6365  
6366 6366          if (ddi_dma_addr_bind_handle(ahci_portp->ahciport_cmd_list_dma_handle,
6367 6367              NULL,
6368 6368              (caddr_t)ahci_portp->ahciport_cmd_list,
6369 6369              cmd_list_size,
6370 6370              DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
6371 6371              DDI_DMA_SLEEP,
6372 6372              NULL,
6373 6373              &ahci_portp->ahciport_cmd_list_dma_cookie,
6374 6374              &cookie_count) !=  DDI_DMA_MAPPED) {
6375 6375  
6376 6376                  AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6377 6377                      "cmd list dma handle bind fail", NULL);
6378 6378                  /*  error.. free the dma handle & free the memory. */
6379 6379                  ddi_dma_mem_free(&ahci_portp->ahciport_cmd_list_acc_handle);
6380 6380                  ddi_dma_free_handle(&ahci_portp->ahciport_cmd_list_dma_handle);
6381 6381                  return (AHCI_FAILURE);
6382 6382          }
6383 6383  
6384 6384          bzero((void *)ahci_portp->ahciport_cmd_list, cmd_list_size);
6385 6385  
6386 6386          AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "64-bit, dma address: 0x%llx",
6387 6387              ahci_portp->ahciport_cmd_list_dma_cookie.dmac_laddress);
6388 6388  
6389 6389          AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "32-bit, dma address: 0x%x",
6390 6390              ahci_portp->ahciport_cmd_list_dma_cookie.dmac_address);
6391 6391  
6392 6392          if (ahci_alloc_cmd_tables(ahci_ctlp, ahci_portp) != AHCI_SUCCESS) {
6393 6393                  goto err_out;
6394 6394          }
6395 6395  
6396 6396          return (AHCI_SUCCESS);
6397 6397  
6398 6398  err_out:
6399 6399          /* Unbind the cmd list dma handle first. */
6400 6400          (void) ddi_dma_unbind_handle(ahci_portp->ahciport_cmd_list_dma_handle);
6401 6401  
6402 6402          /* Then free the underlying memory. */
6403 6403          ddi_dma_mem_free(&ahci_portp->ahciport_cmd_list_acc_handle);
6404 6404  
6405 6405          /* Now free the handle itself. */
6406 6406          ddi_dma_free_handle(&ahci_portp->ahciport_cmd_list_dma_handle);
6407 6407  
6408 6408          return (AHCI_FAILURE);
6409 6409  }
6410 6410  
6411 6411  /*
6412 6412   * Deallocates the Command List
6413 6413   */
6414 6414  static void
6415 6415  ahci_dealloc_cmd_list(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6416 6416  {
6417 6417          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6418 6418  
6419 6419          /* First dealloc command table */
6420 6420          ahci_dealloc_cmd_tables(ahci_ctlp, ahci_portp);
6421 6421  
6422 6422          /* Unbind the cmd list dma handle first. */
6423 6423          (void) ddi_dma_unbind_handle(ahci_portp->ahciport_cmd_list_dma_handle);
6424 6424  
6425 6425          /* Then free the underlying memory. */
6426 6426          ddi_dma_mem_free(&ahci_portp->ahciport_cmd_list_acc_handle);
6427 6427  
6428 6428          /* Now free the handle itself. */
6429 6429          ddi_dma_free_handle(&ahci_portp->ahciport_cmd_list_dma_handle);
6430 6430  }
6431 6431  
6432 6432  /*
6433 6433   * Allocates memory for all Command Tables, which contains Command FIS,
6434 6434   * ATAPI Command and Physical Region Descriptor Table.
6435 6435   */
6436 6436  static int
6437 6437  ahci_alloc_cmd_tables(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6438 6438  {
6439 6439          size_t ret_len;
6440 6440          ddi_dma_cookie_t cmd_table_dma_cookie;
6441 6441          uint_t cookie_count;
6442 6442          int slot;
6443 6443  
6444 6444          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6445 6445  
6446 6446          AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
6447 6447              "ahci_alloc_cmd_tables: port %d enter",
6448 6448              ahci_portp->ahciport_port_num);
6449 6449  
6450 6450          for (slot = 0; slot < ahci_ctlp->ahcictl_num_cmd_slots; slot++) {
6451 6451                  /* Allocate cmd table dma handle. */
6452 6452                  if (ddi_dma_alloc_handle(ahci_ctlp->ahcictl_dip,
6453 6453                      &ahci_ctlp->ahcictl_cmd_table_dma_attr,
6454 6454                      DDI_DMA_SLEEP,
6455 6455                      NULL,
6456 6456                      &ahci_portp->ahciport_cmd_tables_dma_handle[slot]) !=
6457 6457                      DDI_SUCCESS) {
6458 6458  
6459 6459                          AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6460 6460                              "cmd table dma handle alloc failed", NULL);
6461 6461  
6462 6462                          goto err_out;
6463 6463                  }
6464 6464  
6465 6465                  if (ddi_dma_mem_alloc(
6466 6466                      ahci_portp->ahciport_cmd_tables_dma_handle[slot],
6467 6467                      ahci_cmd_table_size,
6468 6468                      &accattr,
6469 6469                      DDI_DMA_CONSISTENT,
6470 6470                      DDI_DMA_SLEEP,
6471 6471                      NULL,
6472 6472                      (caddr_t *)&ahci_portp->ahciport_cmd_tables[slot],
6473 6473                      &ret_len,
6474 6474                      &ahci_portp->ahciport_cmd_tables_acc_handle[slot]) != 0) {
6475 6475  
6476 6476                          AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6477 6477                              "cmd table dma mem alloc fail", NULL);
6478 6478  
6479 6479                          /* error.. free the dma handle. */
6480 6480                          ddi_dma_free_handle(
6481 6481                              &ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6482 6482                          goto err_out;
6483 6483                  }
6484 6484  
6485 6485                  if (ddi_dma_addr_bind_handle(
6486 6486                      ahci_portp->ahciport_cmd_tables_dma_handle[slot],
6487 6487                      NULL,
6488 6488                      (caddr_t)ahci_portp->ahciport_cmd_tables[slot],
6489 6489                      ahci_cmd_table_size,
6490 6490                      DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
6491 6491                      DDI_DMA_SLEEP,
6492 6492                      NULL,
6493 6493                      &cmd_table_dma_cookie,
6494 6494                      &cookie_count) !=  DDI_DMA_MAPPED) {
6495 6495  
6496 6496                          AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6497 6497                              "cmd table dma handle bind fail", NULL);
6498 6498                          /*  error.. free the dma handle & free the memory. */
6499 6499                          ddi_dma_mem_free(
6500 6500                              &ahci_portp->ahciport_cmd_tables_acc_handle[slot]);
6501 6501                          ddi_dma_free_handle(
6502 6502                              &ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6503 6503                          goto err_out;
6504 6504                  }
6505 6505  
6506 6506                  bzero((void *)ahci_portp->ahciport_cmd_tables[slot],
6507 6507                      ahci_cmd_table_size);
6508 6508  
6509 6509                  /* Config Port Command Table Base Address */
6510 6510                  SET_COMMAND_TABLE_BASE_ADDR(
6511 6511                      (&ahci_portp->ahciport_cmd_list[slot]),
6512 6512                      cmd_table_dma_cookie.dmac_laddress & 0xffffffffull);
6513 6513  
6514 6514  #ifndef __lock_lint
6515 6515                  SET_COMMAND_TABLE_BASE_ADDR_UPPER(
6516 6516                      (&ahci_portp->ahciport_cmd_list[slot]),
6517 6517                      cmd_table_dma_cookie.dmac_laddress >> 32);
6518 6518  #endif
6519 6519          }
6520 6520  
6521 6521          return (AHCI_SUCCESS);
6522 6522  err_out:
6523 6523  
6524 6524          for (slot--; slot >= 0; slot--) {
6525 6525                  /* Unbind the cmd table dma handle first */
6526 6526                  (void) ddi_dma_unbind_handle(
6527 6527                      ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6528 6528  
6529 6529                  /* Then free the underlying memory */
6530 6530                  ddi_dma_mem_free(
6531 6531                      &ahci_portp->ahciport_cmd_tables_acc_handle[slot]);
6532 6532  
6533 6533                  /* Now free the handle itself */
6534 6534                  ddi_dma_free_handle(
6535 6535                      &ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6536 6536          }
6537 6537  
6538 6538          return (AHCI_FAILURE);
6539 6539  }
6540 6540  
6541 6541  /*
6542 6542   * Deallocates memory for all Command Tables.
6543 6543   */
6544 6544  static void
6545 6545  ahci_dealloc_cmd_tables(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6546 6546  {
6547 6547          int slot;
6548 6548  
6549 6549          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6550 6550  
6551 6551          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
6552 6552              "ahci_dealloc_cmd_tables: %d enter",
6553 6553              ahci_portp->ahciport_port_num);
6554 6554  
6555 6555          for (slot = 0; slot < ahci_ctlp->ahcictl_num_cmd_slots; slot++) {
6556 6556                  /* Unbind the cmd table dma handle first. */
6557 6557                  (void) ddi_dma_unbind_handle(
6558 6558                      ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6559 6559  
6560 6560                  /* Then free the underlying memory. */
6561 6561                  ddi_dma_mem_free(
6562 6562                      &ahci_portp->ahciport_cmd_tables_acc_handle[slot]);
6563 6563  
6564 6564                  /* Now free the handle itself. */
6565 6565                  ddi_dma_free_handle(
6566 6566                      &ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6567 6567          }
6568 6568  }
6569 6569  
6570 6570  /*
6571 6571   * Update SATA registers at controller ports
6572 6572   */
6573 6573  static void
6574 6574  ahci_update_sata_registers(ahci_ctl_t *ahci_ctlp, uint8_t port,
6575 6575      sata_device_t *sd)
6576 6576  {
6577 6577          ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
6578 6578  
6579 6579          sd->satadev_scr.sstatus =
6580 6580              ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6581 6581              (uint32_t *)(AHCI_PORT_PxSSTS(ahci_ctlp, port)));
6582 6582          sd->satadev_scr.serror =
6583 6583              ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6584 6584              (uint32_t *)(AHCI_PORT_PxSERR(ahci_ctlp, port)));
6585 6585          sd->satadev_scr.scontrol =
6586 6586              ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6587 6587              (uint32_t *)(AHCI_PORT_PxSCTL(ahci_ctlp, port)));
6588 6588          sd->satadev_scr.sactive =
6589 6589              ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6590 6590              (uint32_t *)(AHCI_PORT_PxSACT(ahci_ctlp, port)));
6591 6591  }
6592 6592  
6593 6593  /*
6594 6594   * For poll mode, ahci_port_intr will be called to emulate the interrupt
6595 6595   */
6596 6596  static void
6597 6597  ahci_port_intr(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp, uint8_t port)
6598 6598  {
6599 6599          uint32_t port_intr_status;
6600 6600          uint32_t port_intr_enable;
6601 6601  
6602 6602          AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY, ahci_ctlp,
6603 6603              "ahci_port_intr enter: port %d", port);
6604 6604  
6605 6605          mutex_enter(&ahci_portp->ahciport_mutex);
6606 6606          if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_POLLING) {
6607 6607                  /* For SATA_OPMODE_POLLING commands */
6608 6608                  port_intr_enable =
6609 6609                      (AHCI_INTR_STATUS_DHRS |
6610 6610                      AHCI_INTR_STATUS_PSS |
6611 6611                      AHCI_INTR_STATUS_SDBS |
6612 6612                      AHCI_INTR_STATUS_UFS |
6613 6613                      AHCI_INTR_STATUS_PCS |
6614 6614                      AHCI_INTR_STATUS_PRCS |
6615 6615                      AHCI_INTR_STATUS_OFS |
6616 6616                      AHCI_INTR_STATUS_INFS |
6617 6617                      AHCI_INTR_STATUS_IFS |
6618 6618                      AHCI_INTR_STATUS_HBDS |
6619 6619                      AHCI_INTR_STATUS_HBFS |
6620 6620                      AHCI_INTR_STATUS_TFES);
6621 6621          } else {
6622 6622                  /*
6623 6623                   * port_intr_enable indicates that the corresponding interrrupt
6624 6624                   * reporting is enabled.
6625 6625                   */
6626 6626                  port_intr_enable = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6627 6627                      (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port));
6628 6628          }
6629 6629  
6630 6630          /* IPMS error in port reset should be ignored according AHCI spec. */
6631 6631          if (!(ahci_portp->ahciport_flags & AHCI_PORT_FLAG_IGNORE_IPMS))
6632 6632                  port_intr_enable |= AHCI_INTR_STATUS_IPMS;
6633 6633          mutex_exit(&ahci_portp->ahciport_mutex);
6634 6634  
6635 6635          /*
6636 6636           * port_intr_stats indicates that the corresponding interrupt
6637 6637           * condition is active.
6638 6638           */
6639 6639          port_intr_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6640 6640              (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port));
6641 6641  
6642 6642          AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
6643 6643              "ahci_port_intr: port %d, port_intr_status = 0x%x, "
6644 6644              "port_intr_enable = 0x%x",
6645 6645              port, port_intr_status, port_intr_enable);
6646 6646  
6647 6647          port_intr_status &= port_intr_enable;
6648 6648  
6649 6649          /*
6650 6650           * Pending interrupt events are indicated by the PxIS register.
6651 6651           * Make sure we don't miss any event.
6652 6652           */
6653 6653          if (ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) {
6654 6654                  ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
6655 6655                      DDI_SERVICE_UNAFFECTED);
6656 6656                  ddi_fm_acc_err_clear(ahci_ctlp->ahcictl_ahci_acc_handle,
6657 6657                      DDI_FME_VERSION);
6658 6658                  return;
6659 6659          }
6660 6660  
6661 6661          /* First clear the port interrupts status */
6662 6662          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6663 6663              (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port),
6664 6664              port_intr_status);
6665 6665  
6666 6666          /* Check the completed non-queued commands */
6667 6667          if (port_intr_status & (AHCI_INTR_STATUS_DHRS |
6668 6668              AHCI_INTR_STATUS_PSS)) {
6669 6669                  (void) ahci_intr_cmd_cmplt(ahci_ctlp,
6670 6670                      ahci_portp, port);
6671 6671          }
6672 6672  
6673 6673          /* Check the completed queued commands */
6674 6674          if (port_intr_status & AHCI_INTR_STATUS_SDBS) {
6675 6675                  (void) ahci_intr_set_device_bits(ahci_ctlp,
6676 6676                      ahci_portp, port);
6677 6677          }
6678 6678  
6679 6679          /* Check the port connect change status interrupt bit */
6680 6680          if (port_intr_status & AHCI_INTR_STATUS_PCS) {
6681 6681                  (void) ahci_intr_port_connect_change(ahci_ctlp,
6682 6682                      ahci_portp, port);
6683 6683          }
6684 6684  
6685 6685          /* Check the device mechanical presence status interrupt bit */
6686 6686          if (port_intr_status & AHCI_INTR_STATUS_DMPS) {
6687 6687                  (void) ahci_intr_device_mechanical_presence_status(
6688 6688                      ahci_ctlp, ahci_portp, port);
6689 6689          }
6690 6690  
6691 6691          /* Check the PhyRdy change status interrupt bit */
6692 6692          if (port_intr_status & AHCI_INTR_STATUS_PRCS) {
6693 6693                  (void) ahci_intr_phyrdy_change(ahci_ctlp, ahci_portp,
6694 6694                      port);
6695 6695          }
6696 6696  
6697 6697          /*
6698 6698           * Check the non-fatal error interrupt bits, there are four
6699 6699           * kinds of non-fatal errors at the time being:
6700 6700           *
6701 6701           *    PxIS.UFS - Unknown FIS Error
6702 6702           *    PxIS.OFS - Overflow Error
6703 6703           *    PxIS.INFS - Interface Non-Fatal Error
6704 6704           *    PxIS.IPMS - Incorrect Port Multiplier Status Error
6705 6705           *
6706 6706           * For these non-fatal errors, the HBA can continue to operate,
6707 6707           * so the driver just log the error messages.
6708 6708           */
6709 6709          if (port_intr_status & (AHCI_INTR_STATUS_UFS |
6710 6710              AHCI_INTR_STATUS_OFS |
6711 6711              AHCI_INTR_STATUS_IPMS |
6712 6712              AHCI_INTR_STATUS_INFS)) {
6713 6713                  (void) ahci_intr_non_fatal_error(ahci_ctlp, ahci_portp,
6714 6714                      port, port_intr_status);
6715 6715          }
6716 6716  
6717 6717          /*
6718 6718           * Check the fatal error interrupt bits, there are four kinds
6719 6719           * of fatal errors for AHCI controllers:
6720 6720           *
6721 6721           *    PxIS.HBFS - Host Bus Fatal Error
6722 6722           *    PxIS.HBDS - Host Bus Data Error
6723 6723           *    PxIS.IFS - Interface Fatal Error
6724 6724           *    PxIS.TFES - Task File Error
6725 6725           *
6726 6726           * The fatal error means the HBA can not recover from it by
6727 6727           * itself, and it will try to abort the transfer, and the software
6728 6728           * must intervene to restart the port.
6729 6729           */
6730 6730          if (port_intr_status & (AHCI_INTR_STATUS_IFS |
6731 6731              AHCI_INTR_STATUS_HBDS |
6732 6732              AHCI_INTR_STATUS_HBFS |
6733 6733              AHCI_INTR_STATUS_TFES))
6734 6734                  (void) ahci_intr_fatal_error(ahci_ctlp, ahci_portp,
6735 6735                      port, port_intr_status);
6736 6736  
6737 6737          /* Check the cold port detect interrupt bit */
6738 6738          if (port_intr_status & AHCI_INTR_STATUS_CPDS) {
6739 6739                  (void) ahci_intr_cold_port_detect(ahci_ctlp, ahci_portp, port);
6740 6740          }
6741 6741  
6742 6742          /* Second clear the corresponding bit in IS.IPS */
6743 6743          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6744 6744              (uint32_t *)AHCI_GLOBAL_IS(ahci_ctlp), (0x1 << port));
6745 6745  
6746 6746          /* Try to recover at the end of the interrupt handler. */
6747 6747          if (ahci_check_acc_handle(ahci_ctlp->ahcictl_ahci_acc_handle) !=
6748 6748              DDI_FM_OK) {
6749 6749                  ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
6750 6750                      DDI_SERVICE_UNAFFECTED);
6751 6751                  ddi_fm_acc_err_clear(ahci_ctlp->ahcictl_ahci_acc_handle,
6752 6752                      DDI_FME_VERSION);
6753 6753          }
6754 6754  }
6755 6755  
6756 6756  /*
6757 6757   * Interrupt service handler
6758 6758   */
6759 6759  static uint_t
6760 6760  ahci_intr(caddr_t arg1, caddr_t arg2)
6761 6761  {
6762 6762  #ifndef __lock_lint
6763 6763          _NOTE(ARGUNUSED(arg2))
6764 6764  #endif
6765 6765          /* LINTED */
6766 6766          ahci_ctl_t *ahci_ctlp = (ahci_ctl_t *)arg1;
6767 6767          ahci_port_t *ahci_portp;
6768 6768          int32_t global_intr_status;
6769 6769          uint8_t port;
6770 6770  
6771 6771          /*
6772 6772           * global_intr_status indicates that the corresponding port has
6773 6773           * an interrupt pending.
6774 6774           */
6775 6775          global_intr_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6776 6776              (uint32_t *)AHCI_GLOBAL_IS(ahci_ctlp));
6777 6777  
6778 6778          if (!(global_intr_status & ahci_ctlp->ahcictl_ports_implemented)) {
6779 6779                  /* The interrupt is not ours */
6780 6780                  return (DDI_INTR_UNCLAIMED);
6781 6781          }
6782 6782  
6783 6783          /*
6784 6784           * Check the handle after reading global_intr_status - we don't want
6785 6785           * to miss any port with pending interrupts.
6786 6786           */
6787 6787          if (ahci_check_acc_handle(ahci_ctlp->ahcictl_ahci_acc_handle) !=
6788 6788              DDI_FM_OK) {
6789 6789                  ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
6790 6790                      DDI_SERVICE_UNAFFECTED);
6791 6791                  ddi_fm_acc_err_clear(ahci_ctlp->ahcictl_ahci_acc_handle,
6792 6792                      DDI_FME_VERSION);
6793 6793                  return (DDI_INTR_UNCLAIMED);
6794 6794          }
6795 6795  
6796 6796          /* Loop for all the ports */
6797 6797          for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
6798 6798                  if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
6799 6799                          continue;
6800 6800                  }
6801 6801                  if (!((0x1 << port) & global_intr_status)) {
6802 6802                          continue;
6803 6803                  }
6804 6804  
6805 6805                  ahci_portp = ahci_ctlp->ahcictl_ports[port];
6806 6806  
6807 6807                  /* Call ahci_port_intr */
6808 6808                  ahci_port_intr(ahci_ctlp, ahci_portp, port);
6809 6809          }
6810 6810  
6811 6811          return (DDI_INTR_CLAIMED);
6812 6812  }
6813 6813  
6814 6814  /*
6815 6815   * For non-queued commands, when the corresponding bit in the PxCI register
6816 6816   * is cleared, it means the command is completed successfully. And according
6817 6817   * to the HBA state machine, there are three conditions which possibly will
6818 6818   * try to clear the PxCI register bit.
6819 6819   *      1. Receive one D2H Register FIS which is with 'I' bit set
6820 6820   *      2. Update PIO Setup FIS
6821 6821   *      3. Transmit a command and receive R_OK if CTBA.C is set (software reset)
6822 6822   *
6823 6823   * Process completed non-queued commands when the interrupt status bit -
6824 6824   * AHCI_INTR_STATUS_DHRS or AHCI_INTR_STATUS_PSS is set.
6825 6825   *
6826 6826   * AHCI_INTR_STATUS_DHRS means a D2H Register FIS has been received
6827 6827   * with the 'I' bit set. And the following commands will send thus
6828 6828   * FIS with 'I' bit set upon the successful completion:
6829 6829   *      1. Non-data commands
6830 6830   *      2. DMA data-in command
6831 6831   *      3. DMA data-out command
6832 6832   *      4. PIO data-out command
6833 6833   *      5. PACKET non-data commands
6834 6834   *      6. PACKET PIO data-in command
6835 6835   *      7. PACKET PIO data-out command
6836 6836   *      8. PACKET DMA data-in command
6837 6837   *      9. PACKET DMA data-out command
6838 6838   *
6839 6839   * AHCI_INTR_STATUS_PSS means a PIO Setup FIS has been received
6840 6840   * with the 'I' bit set. And the following commands will send this
6841 6841   * FIS upon the successful completion:
6842 6842   *      1. PIO data-in command
6843 6843   */
6844 6844  static int
6845 6845  ahci_intr_cmd_cmplt(ahci_ctl_t *ahci_ctlp,
6846 6846      ahci_port_t *ahci_portp, uint8_t port)
6847 6847  {
6848 6848          uint32_t port_cmd_issue = 0;
6849 6849          uint32_t finished_tags;
6850 6850          int finished_slot;
6851 6851          sata_pkt_t *satapkt;
6852 6852          ahci_fis_d2h_register_t *rcvd_fisp;
6853 6853  #if AHCI_DEBUG
6854 6854          ahci_cmd_header_t *cmd_header;
6855 6855          uint32_t cmd_dmacount;
6856 6856  #endif
6857 6857  
6858 6858          mutex_enter(&ahci_portp->ahciport_mutex);
6859 6859  
6860 6860          if (!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&
6861 6861              !RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp) &&
6862 6862              !NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
6863 6863                  /*
6864 6864                   * Spurious interrupt. Nothing to be done.
6865 6865                   */
6866 6866                  mutex_exit(&ahci_portp->ahciport_mutex);
6867 6867                  return (AHCI_SUCCESS);
6868 6868          }
6869 6869  
6870 6870          port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6871 6871              (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
6872 6872  
6873 6873          /* If the PxCI corrupts, don't complete the commmands. */
6874 6874          if (ahci_check_acc_handle(ahci_ctlp->ahcictl_ahci_acc_handle)
6875 6875              != DDI_FM_OK) {
6876 6876                  mutex_exit(&ahci_portp->ahciport_mutex);
6877 6877                  return (AHCI_FAILURE);
6878 6878          }
6879 6879  
6880 6880          if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
6881 6881                  /* Slot 0 is always used during error recovery */
6882 6882                  finished_tags = 0x1 & ~port_cmd_issue;
6883 6883                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
6884 6884                      "ahci_intr_cmd_cmplt: port %d the sata pkt for error "
6885 6885                      "retrieval is finished, and finished_tags = 0x%x",
6886 6886                      port, finished_tags);
6887 6887          } else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
6888 6888                  finished_tags = 0x1 & ~port_cmd_issue;
6889 6889                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
6890 6890                      "ahci_intr_cmd_cmplt: port %d the sata pkt for r/w "
6891 6891                      "port multiplier is finished, and finished_tags = 0x%x",
6892 6892                      port, finished_tags);
6893 6893  
6894 6894          } else {
6895 6895  
6896 6896                  finished_tags = ahci_portp->ahciport_pending_tags &
6897 6897                      ~port_cmd_issue & AHCI_SLOT_MASK(ahci_ctlp);
6898 6898          }
6899 6899  
6900 6900          AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
6901 6901              "ahci_intr_cmd_cmplt: pending_tags = 0x%x, "
6902 6902              "port_cmd_issue = 0x%x finished_tags = 0x%x",
6903 6903              ahci_portp->ahciport_pending_tags, port_cmd_issue,
6904 6904              finished_tags);
6905 6905  
6906 6906          if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&
6907 6907              (finished_tags == 0x1)) {
6908 6908                  satapkt = ahci_portp->ahciport_err_retri_pkt;
6909 6909                  ASSERT(satapkt != NULL);
6910 6910  
6911 6911                  AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
6912 6912                      "ahci_intr_cmd_cmplt: sending up pkt 0x%p "
6913 6913                      "with SATA_PKT_COMPLETED", (void *)satapkt);
6914 6914  
6915 6915                  ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
6916 6916                  goto out;
6917 6917          }
6918 6918  
6919 6919          if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp) &&
6920 6920              (finished_tags == 0x1)) {
6921 6921                  satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
6922 6922                  ASSERT(satapkt != NULL);
6923 6923  
6924 6924                  AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
6925 6925                      "ahci_intr_cmd_cmplt: sending up pkt 0x%p "
6926 6926                      "with SATA_PKT_COMPLETED", (void *)satapkt);
6927 6927  
6928 6928                  /* READ PORTMULT need copy out FIS content. */
6929 6929                  if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
6930 6930                          rcvd_fisp = &(ahci_portp->ahciport_rcvd_fis->
6931 6931                              ahcirf_d2h_register_fis);
6932 6932                          satapkt->satapkt_cmd.satacmd_status_reg =
6933 6933                              GET_RFIS_STATUS(rcvd_fisp);
6934 6934                          ahci_copy_out_regs(&satapkt->satapkt_cmd, rcvd_fisp);
6935 6935                  }
6936 6936  
6937 6937                  ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
6938 6938                  goto out;
6939 6939          }
6940 6940  
6941 6941          while (finished_tags) {
6942 6942                  finished_slot = ddi_ffs(finished_tags) - 1;
6943 6943                  if (finished_slot == -1) {
6944 6944                          goto out;
6945 6945                  }
6946 6946  
6947 6947                  satapkt = ahci_portp->ahciport_slot_pkts[finished_slot];
6948 6948                  ASSERT(satapkt != NULL);
6949 6949  #if AHCI_DEBUG
6950 6950                  /*
6951 6951                   * For non-native queued commands, the PRD byte count field
6952 6952                   * shall contain an accurate count of the number of bytes
6953 6953                   * transferred for the command before the PxCI bit is cleared
6954 6954                   * to '0' for the command.
6955 6955                   *
6956 6956                   * The purpose of this field is to let software know how many
6957 6957                   * bytes transferred for a given operation in order to
6958 6958                   * determine if underflow occurred. When issuing native command
6959 6959                   * queuing commands, this field should not be used and is not
6960 6960                   * required to be valid since in this case underflow is always
6961 6961                   * illegal.
6962 6962                   *
6963 6963                   * For data reads, the HBA will update its PRD byte count with
6964 6964                   * the total number of bytes received from the last FIS, and
6965 6965                   * may be able to continue normally. For data writes, the
6966 6966                   * device will detect an error, and HBA most likely will get
6967 6967                   * a fatal error.
6968 6968                   *
6969 6969                   * Therefore, here just put code to debug part. And please
6970 6970                   * refer to the comment above ahci_intr_fatal_error for the
6971 6971                   * definition of underflow error.
6972 6972                   */
6973 6973                  cmd_dmacount =
6974 6974                      ahci_portp->ahciport_prd_bytecounts[finished_slot];
6975 6975                  if (cmd_dmacount) {
6976 6976                          cmd_header =
6977 6977                              &ahci_portp->ahciport_cmd_list[finished_slot];
6978 6978                          AHCIDBG(AHCIDBG_INTR|AHCIDBG_PRDT, ahci_ctlp,
6979 6979                              "ahci_intr_cmd_cmplt: port %d, "
6980 6980                              "PRD Byte Count = 0x%x, "
6981 6981                              "ahciport_prd_bytecounts = 0x%x", port,
6982 6982                              cmd_header->ahcich_prd_byte_count,
6983 6983                              cmd_dmacount);
6984 6984  
6985 6985                          if (cmd_header->ahcich_prd_byte_count != cmd_dmacount) {
6986 6986                                  AHCIDBG(AHCIDBG_UNDERFLOW, ahci_ctlp,
6987 6987                                      "ahci_intr_cmd_cmplt: port %d, "
6988 6988                                      "an underflow occurred", port);
6989 6989                          }
6990 6990                  }
6991 6991  #endif
6992 6992  
6993 6993                  /*
6994 6994                   * For SATAC_SMART command with SATA_SMART_RETURN_STATUS
6995 6995                   * feature, sata_special_regs flag will be set, and the
6996 6996                   * driver should copy the status and the other corresponding
6997 6997                   * register values in the D2H Register FIS received (It's
6998 6998                   * working on Non-data protocol) from the device back to
6999 6999                   * the sata_cmd.
7000 7000                   *
7001 7001                   * For every AHCI port, there is only one Received FIS
7002 7002                   * structure, which contains the FISes received from the
7003 7003                   * device, So we're trying to copy the content of D2H
7004 7004                   * Register FIS in the Received FIS structure back to
7005 7005                   * the sata_cmd.
7006 7006                   */
7007 7007                  if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
7008 7008                          rcvd_fisp = &(ahci_portp->ahciport_rcvd_fis->
7009 7009                              ahcirf_d2h_register_fis);
7010 7010                          satapkt->satapkt_cmd.satacmd_status_reg =
7011 7011                              GET_RFIS_STATUS(rcvd_fisp);
7012 7012                          ahci_copy_out_regs(&satapkt->satapkt_cmd, rcvd_fisp);
7013 7013                  }
7014 7014  
7015 7015                  AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7016 7016                      "ahci_intr_cmd_cmplt: sending up pkt 0x%p "
7017 7017                      "with SATA_PKT_COMPLETED", (void *)satapkt);
7018 7018  
7019 7019                  CLEAR_BIT(ahci_portp->ahciport_pending_tags, finished_slot);
7020 7020                  CLEAR_BIT(finished_tags, finished_slot);
7021 7021                  ahci_portp->ahciport_slot_pkts[finished_slot] = NULL;
7022 7022  
7023 7023                  ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
7024 7024          }
7025 7025  out:
7026 7026          AHCIDBG(AHCIDBG_PKTCOMP, ahci_ctlp,
7027 7027              "ahci_intr_cmd_cmplt: pending_tags = 0x%x",
7028 7028              ahci_portp->ahciport_pending_tags);
7029 7029  
7030 7030          ahci_flush_doneq(ahci_portp);
7031 7031  
7032 7032          mutex_exit(&ahci_portp->ahciport_mutex);
7033 7033  
7034 7034          return (AHCI_SUCCESS);
7035 7035  }
7036 7036  
7037 7037  /*
7038 7038   * AHCI_INTR_STATUS_SDBS means a Set Device Bits FIS has been received
7039 7039   * with the 'I' bit set and has been copied into system memory. It will
7040 7040   * be sent under the following situations:
7041 7041   *
7042 7042   * 1. NCQ command is completed
7043 7043   *
7044 7044   * The completion of NCQ commands (READ/WRITE FPDMA QUEUED) is performed
7045 7045   * via the Set Device Bits FIS. When such event is generated, the software
7046 7046   * needs to read PxSACT register and compares the current value to the
7047 7047   * list of commands previously issue by software. ahciport_pending_ncq_tags
7048 7048   * keeps the tags of previously issued commands.
7049 7049   *
7050 7050   * 2. Asynchronous Notification
7051 7051   *
7052 7052   * Asynchronous Notification is a feature in SATA spec 2.6.
7053 7053   *
7054 7054   * 1) ATAPI device will send a signal to the host when media is inserted or
7055 7055   * removed and avoids polling the device for media changes. The signal
7056 7056   * sent to the host is a Set Device Bits FIS with the 'I' and 'N' bits
7057 7057   * set to '1'. At the moment, it's not supported yet.
7058 7058   *
7059 7059   * 2) Port multiplier will send a signal to the host when a hot plug event
7060 7060   * has occured on a port multiplier port. It is used when command based
7061 7061   * switching is employed. This is handled by ahci_intr_pmult_sntf_events()
7062 7062   */
7063 7063  static int
7064 7064  ahci_intr_set_device_bits(ahci_ctl_t *ahci_ctlp,
7065 7065      ahci_port_t *ahci_portp, uint8_t port)
7066 7066  {
7067 7067          ahci_addr_t addr;
7068 7068  
7069 7069          AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
7070 7070              "ahci_intr_set_device_bits enter: port %d", port);
7071 7071  
7072 7072          /* Initialize HBA port address */
7073 7073          AHCI_ADDR_SET_PORT(&addr, port);
7074 7074  
7075 7075          /* NCQ plug handler */
7076 7076          (void) ahci_intr_ncq_events(ahci_ctlp, ahci_portp, &addr);
7077 7077  
7078 7078          /* Check port multiplier's asynchronous notification events */
7079 7079          if (ahci_ctlp->ahcictl_cap & AHCI_CAP_SNTF) {
7080 7080                  (void) ahci_intr_pmult_sntf_events(ahci_ctlp,
7081 7081                      ahci_portp, port);
7082 7082          }
7083 7083  
7084 7084          /* ATAPI events is not supported yet */
7085 7085  
7086 7086          return (AHCI_SUCCESS);
7087 7087  }
7088 7088  /*
7089 7089   * NCQ interrupt handler. Called upon a NCQ command is completed.
7090 7090   * Only be called from ahci_intr_set_device_bits().
7091 7091   */
7092 7092  static int
7093 7093  ahci_intr_ncq_events(ahci_ctl_t *ahci_ctlp,
7094 7094      ahci_port_t *ahci_portp, ahci_addr_t *addrp)
7095 7095  {
7096 7096          uint32_t port_sactive;
7097 7097          uint32_t port_cmd_issue;
7098 7098          uint32_t issued_tags;
7099 7099          int issued_slot;
7100 7100          uint32_t finished_tags;
7101 7101          int finished_slot;
7102 7102          uint8_t port = addrp->aa_port;
7103 7103          sata_pkt_t *satapkt;
7104 7104  
7105 7105          AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7106 7106              "ahci_intr_set_device_bits enter: port %d", port);
7107 7107  
7108 7108          mutex_enter(&ahci_portp->ahciport_mutex);
7109 7109          if (!NCQ_CMD_IN_PROGRESS(ahci_portp)) {
7110 7110                  mutex_exit(&ahci_portp->ahciport_mutex);
7111 7111                  return (AHCI_SUCCESS);
7112 7112          }
7113 7113  
7114 7114          /*
7115 7115           * First the handler got which commands are finished by checking
7116 7116           * PxSACT register
7117 7117           */
7118 7118          port_sactive = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7119 7119              (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
7120 7120  
7121 7121          finished_tags = ahci_portp->ahciport_pending_ncq_tags &
7122 7122              ~port_sactive & AHCI_NCQ_SLOT_MASK(ahci_portp);
7123 7123  
7124 7124          AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7125 7125              "ahci_intr_set_device_bits: port %d pending_ncq_tags = 0x%x "
7126 7126              "port_sactive = 0x%x", port,
7127 7127              ahci_portp->ahciport_pending_ncq_tags, port_sactive);
7128 7128  
7129 7129          AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7130 7130              "ahci_intr_set_device_bits: finished_tags = 0x%x", finished_tags);
7131 7131  
7132 7132          /*
7133 7133           * For NCQ commands, the software can determine which command has
7134 7134           * already been transmitted to the device by checking PxCI register.
7135 7135           */
7136 7136          port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7137 7137              (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
7138 7138  
7139 7139          issued_tags = ahci_portp->ahciport_pending_tags &
7140 7140              ~port_cmd_issue & AHCI_SLOT_MASK(ahci_ctlp);
7141 7141  
7142 7142          /* If the PxSACT/PxCI corrupts, don't complete the NCQ commmands. */
7143 7143          if (ahci_check_acc_handle(ahci_ctlp->ahcictl_ahci_acc_handle)
7144 7144              != DDI_FM_OK) {
7145 7145                  mutex_exit(&ahci_portp->ahciport_mutex);
7146 7146                  return (AHCI_FAILURE);
7147 7147          }
7148 7148  
7149 7149          AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7150 7150              "ahci_intr_set_device_bits: port %d pending_tags = 0x%x "
7151 7151              "port_cmd_issue = 0x%x", port,
7152 7152              ahci_portp->ahciport_pending_tags, port_cmd_issue);
7153 7153  
7154 7154          AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7155 7155              "ahci_intr_set_device_bits: issued_tags = 0x%x", issued_tags);
7156 7156  
7157 7157          /*
7158 7158           * Clear ahciport_pending_tags bit when the corresponding command
7159 7159           * is already sent down to the device.
7160 7160           */
7161 7161          while (issued_tags) {
7162 7162                  issued_slot = ddi_ffs(issued_tags) - 1;
7163 7163                  if (issued_slot == -1) {
7164 7164                          goto next;
7165 7165                  }
7166 7166                  CLEAR_BIT(ahci_portp->ahciport_pending_tags, issued_slot);
7167 7167                  CLEAR_BIT(issued_tags, issued_slot);
7168 7168          }
7169 7169  
7170 7170  next:
7171 7171          while (finished_tags) {
7172 7172                  finished_slot = ddi_ffs(finished_tags) - 1;
7173 7173                  if (finished_slot == -1) {
7174 7174                          goto out;
7175 7175                  }
7176 7176  
7177 7177                  /* The command is certainly transmitted to the device */
7178 7178                  ASSERT(!(ahci_portp->ahciport_pending_tags &
7179 7179                      (0x1 << finished_slot)));
7180 7180  
7181 7181                  satapkt = ahci_portp->ahciport_slot_pkts[finished_slot];
7182 7182                  ASSERT(satapkt != NULL);
7183 7183  
7184 7184                  AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7185 7185                      "ahci_intr_set_device_bits: sending up pkt 0x%p "
7186 7186                      "with SATA_PKT_COMPLETED", (void *)satapkt);
7187 7187  
7188 7188                  CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags, finished_slot);
7189 7189                  CLEAR_BIT(finished_tags, finished_slot);
7190 7190                  ahci_portp->ahciport_slot_pkts[finished_slot] = NULL;
7191 7191  
7192 7192                  ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
7193 7193          }
7194 7194  out:
7195 7195          AHCIDBG(AHCIDBG_PKTCOMP|AHCIDBG_NCQ, ahci_ctlp,
7196 7196              "ahci_intr_set_device_bits: port %d "
7197 7197              "pending_ncq_tags = 0x%x pending_tags = 0x%x",
7198 7198              port, ahci_portp->ahciport_pending_ncq_tags,
7199 7199              ahci_portp->ahciport_pending_tags);
7200 7200  
7201 7201          ahci_flush_doneq(ahci_portp);
7202 7202  
7203 7203          mutex_exit(&ahci_portp->ahciport_mutex);
7204 7204  
7205 7205          return (AHCI_SUCCESS);
7206 7206  }
7207 7207  
7208 7208  /*
7209 7209   * Port multiplier asynchronous notification event handler. Called upon a
7210 7210   * device is hot plugged/pulled.
7211 7211   *
7212 7212   * The async-notification event will only be recorded by ahcipmi_snotif_tags
7213 7213   * here and will be handled by ahci_probe_pmult().
7214 7214   *
7215 7215   * NOTE: called only from ahci_port_intr().
7216 7216   */
7217 7217  static int
7218 7218  ahci_intr_pmult_sntf_events(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
7219 7219      uint8_t port)
7220 7220  {
7221 7221          sata_device_t sdevice;
7222 7222  
7223 7223          AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
7224 7224              "ahci_intr_pmult_sntf_events enter: port %d ", port);
7225 7225  
7226 7226          /* no hot-plug while attaching process */
7227 7227          mutex_enter(&ahci_ctlp->ahcictl_mutex);
7228 7228          if (ahci_ctlp->ahcictl_flags & AHCI_ATTACH) {
7229 7229                  mutex_exit(&ahci_ctlp->ahcictl_mutex);
7230 7230                  return (AHCI_SUCCESS);
7231 7231          }
7232 7232          mutex_exit(&ahci_ctlp->ahcictl_mutex);
7233 7233  
7234 7234          mutex_enter(&ahci_portp->ahciport_mutex);
7235 7235          if (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) {
7236 7236                  mutex_exit(&ahci_portp->ahciport_mutex);
7237 7237                  return (AHCI_SUCCESS);
7238 7238          }
7239 7239  
7240 7240          ASSERT(ahci_portp->ahciport_pmult_info != NULL);
7241 7241  
7242 7242          ahci_portp->ahciport_pmult_info->ahcipmi_snotif_tags =
7243 7243              ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7244 7244              (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp, port));
7245 7245          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
7246 7246              (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp, port),
7247 7247              AHCI_SNOTIF_CLEAR_ALL);
7248 7248  
7249 7249          if (ahci_portp->ahciport_pmult_info->ahcipmi_snotif_tags == 0) {
7250 7250                  mutex_exit(&ahci_portp->ahciport_mutex);
7251 7251                  return (AHCI_SUCCESS);
7252 7252          }
7253 7253  
7254 7254          /* Port Multiplier sub-device hot-plug handler */
7255 7255          if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
7256 7256                  mutex_exit(&ahci_portp->ahciport_mutex);
7257 7257                  return (AHCI_SUCCESS);
7258 7258          }
7259 7259  
7260 7260          if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_PMULT_SNTF) {
7261 7261                  /* Not allowed to re-enter. */
7262 7262                  mutex_exit(&ahci_portp->ahciport_mutex);
7263 7263                  return (AHCI_SUCCESS);
7264 7264          }
7265 7265  
7266 7266          ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_PMULT_SNTF;
7267 7267  
7268 7268          /*
7269 7269           * NOTE:
7270 7270           * Even if Asynchronous Notification is supported (and enabled) by
7271 7271           * both controller and the port multiplier, the content of PxSNTF
7272 7272           * register is always set to 0x8000 by async notification event. We
7273 7273           * need to check GSCR[32] on the port multiplier to find out the
7274 7274           * owner of this event.
7275 7275           * This is not accord with SATA spec 2.6 and needs further
7276 7276           * clarification.
7277 7277           */
7278 7278          /* hot-plug will not reported while reseting. */
7279 7279          if (ahci_portp->ahciport_reset_in_progress == 1) {
7280 7280                  AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
7281 7281                      "port %d snotif event ignored", port);
7282 7282                  ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_PMULT_SNTF;
7283 7283                  mutex_exit(&ahci_portp->ahciport_mutex);
7284 7284                  return (AHCI_SUCCESS);
7285 7285          }
7286 7286  
7287 7287          AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
7288 7288              "PxSNTF is set to 0x%x by port multiplier",
7289 7289              ahci_portp->ahciport_pmult_info->ahcipmi_snotif_tags);
7290 7290  
7291 7291          /*
7292 7292           * Now we need do some necessary operation and inform SATA framework
7293 7293           * that link/device events has happened.
7294 7294           */
7295 7295          bzero((void *)&sdevice, sizeof (sata_device_t));
7296 7296          sdevice.satadev_addr.cport = ahci_ctlp->
7297 7297              ahcictl_port_to_cport[port];
7298 7298          sdevice.satadev_addr.pmport = SATA_PMULT_HOSTPORT;
7299 7299          sdevice.satadev_addr.qual = SATA_ADDR_PMULT;
7300 7300          sdevice.satadev_state = SATA_PSTATE_PWRON;
7301 7301  
7302 7302          /* Just reject packets, do not stop that port. */
7303 7303          ahci_reject_all_abort_pkts(ahci_ctlp, ahci_portp, port);
7304 7304  
7305 7305          mutex_exit(&ahci_portp->ahciport_mutex);
7306 7306          sata_hba_event_notify(
7307 7307              ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
7308 7308              &sdevice,
7309 7309              SATA_EVNT_PMULT_LINK_CHANGED);
7310 7310          mutex_enter(&ahci_portp->ahciport_mutex);
7311 7311  
7312 7312          ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_PMULT_SNTF;
7313 7313          mutex_exit(&ahci_portp->ahciport_mutex);
7314 7314  
7315 7315          return (AHCI_SUCCESS);
7316 7316  }
7317 7317  
7318 7318  /*
7319 7319   * 1=Change in Current Connect Status. 0=No change in Current Connect Status.
7320 7320   * This bit reflects the state of PxSERR.DIAG.X. This bit is only cleared
7321 7321   * when PxSERR.DIAG.X is cleared. When PxSERR.DIAG.X is set to one, it
7322 7322   * indicates a COMINIT signal was received.
7323 7323   *
7324 7324   * Hot plug insertion is detected by reception of a COMINIT signal from the
7325 7325   * device. On reception of unsolicited COMINIT, the HBA shall generate a
7326 7326   * COMRESET. If the COMINIT is in responce to a COMRESET, then the HBA shall
7327 7327   * begin the normal communication negotiation sequence as outlined in the
7328 7328   * Serial ATA 1.0a specification. When a COMRESET is sent to the device the
7329 7329   * PxSSTS.DET field shall be cleared to 0h. When a COMINIT is received, the
7330 7330   * PxSSTS.DET field shall be set to 1h. When the communication negotiation
7331 7331   * sequence is complete and PhyRdy is true the PxSSTS.DET field shall be set
7332 7332   * to 3h. Therefore, at the moment the ahci driver is going to check PhyRdy
7333 7333   * to handle hot plug insertion. In this interrupt handler, just do nothing
7334 7334   * but print some log message and clear the bit.
7335 7335   */
7336 7336  static int
7337 7337  ahci_intr_port_connect_change(ahci_ctl_t *ahci_ctlp,
7338 7338      ahci_port_t *ahci_portp, uint8_t port)
7339 7339  {
7340 7340  #if AHCI_DEBUG
7341 7341          uint32_t port_serror;
7342 7342  #endif
7343 7343  
7344 7344          mutex_enter(&ahci_portp->ahciport_mutex);
7345 7345  
7346 7346  #if AHCI_DEBUG
7347 7347          port_serror = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7348 7348              (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port));
7349 7349  
7350 7350          AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY, ahci_ctlp,
7351 7351              "ahci_intr_port_connect_change: port %d, "
7352 7352              "port_serror = 0x%x", port, port_serror);
7353 7353  #endif
7354 7354  
7355 7355          /* Clear PxSERR.DIAG.X to clear the interrupt bit */
7356 7356          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
7357 7357              (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
7358 7358              SERROR_EXCHANGED_ERR);
7359 7359  
7360 7360          mutex_exit(&ahci_portp->ahciport_mutex);
7361 7361  
7362 7362          return (AHCI_SUCCESS);
7363 7363  }
7364 7364  
7365 7365  /*
7366 7366   * Hot Plug Operation for platforms that support Mechanical Presence
7367 7367   * Switches.
7368 7368   *
7369 7369   * When set, it indicates that a mechanical presence switch attached to this
7370 7370   * port has been opened or closed, which may lead to a change in the connection
7371 7371   * state of the device. This bit is only valid if both CAP.SMPS and PxCMD.MPSP
7372 7372   * are set to '1'.
7373 7373   *
7374 7374   * At the moment, this interrupt is not needed and disabled and we just log
7375 7375   * the debug message.
7376 7376   */
7377 7377  static int
7378 7378  ahci_intr_device_mechanical_presence_status(ahci_ctl_t *ahci_ctlp,
7379 7379      ahci_port_t *ahci_portp, uint8_t port)
7380 7380  {
7381 7381          uint32_t cap_status, port_cmd_status;
7382 7382  
7383 7383          AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY, ahci_ctlp,
7384 7384              "ahci_intr_device_mechanical_presence_status enter, "
7385 7385              "port %d", port);
7386 7386  
7387 7387          cap_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7388 7388              (uint32_t *)AHCI_GLOBAL_CAP(ahci_ctlp));
7389 7389  
7390 7390          mutex_enter(&ahci_portp->ahciport_mutex);
7391 7391          port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7392 7392              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
7393 7393  
7394 7394          if (!(cap_status & AHCI_HBA_CAP_SMPS) ||
7395 7395              !(port_cmd_status & AHCI_CMD_STATUS_MPSP)) {
7396 7396                  AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7397 7397                      "CAP.SMPS or PxCMD.MPSP is not set, so just ignore "
7398 7398                      "the interrupt: cap_status = 0x%x, "
7399 7399                      "port_cmd_status = 0x%x", cap_status, port_cmd_status);
7400 7400                  mutex_exit(&ahci_portp->ahciport_mutex);
7401 7401  
7402 7402                  return (AHCI_SUCCESS);
7403 7403          }
7404 7404  
7405 7405  #if AHCI_DEBUG
7406 7406          if (port_cmd_status & AHCI_CMD_STATUS_MPSS) {
7407 7407                  AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7408 7408                      "The mechanical presence switch is open: "
7409 7409                      "port %d, port_cmd_status = 0x%x",
7410 7410                      port, port_cmd_status);
7411 7411          } else {
7412 7412                  AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7413 7413                      "The mechanical presence switch is close: "
7414 7414                      "port %d, port_cmd_status = 0x%x",
7415 7415                      port, port_cmd_status);
7416 7416          }
7417 7417  #endif
7418 7418  
7419 7419          mutex_exit(&ahci_portp->ahciport_mutex);
7420 7420  
7421 7421          return (AHCI_SUCCESS);
7422 7422  }
7423 7423  
7424 7424  /*
7425 7425   * Native Hot Plug Support.
7426 7426   *
7427 7427   * When set, it indicates that the internal PHYRDY signal changed state.
7428 7428   * This bit reflects the state of PxSERR.DIAG.N.
7429 7429   *
7430 7430   * There are three kinds of conditions to generate this interrupt event:
7431 7431   * 1. a device is inserted
7432 7432   * 2. a device is disconnected
7433 7433   * 3. when the link enters/exits a Partial or Slumber interface power
7434 7434   *    management state
7435 7435   *
7436 7436   * If inteface power management is enabled for a port, the PxSERR.DIAG.N
7437 7437   * bit may be set due to the link entering the Partial or Slumber power
7438 7438   * management state, rather than due to a hot plug insertion or removal
7439 7439   * event. So far, the interface power management is disabled, so the
7440 7440   * driver can reliably get removal detection notification via the
7441 7441   * PxSERR.DIAG.N bit.
7442 7442   */
7443 7443  static int
7444 7444  ahci_intr_phyrdy_change(ahci_ctl_t *ahci_ctlp,
7445 7445      ahci_port_t *ahci_portp, uint8_t port)
7446 7446  {
7447 7447          uint32_t port_sstatus = 0; /* No dev present & PHY not established. */
7448 7448          sata_device_t sdevice;
7449 7449          int dev_exists_now = 0;
7450 7450          int dev_existed_previously = 0;
7451 7451          ahci_addr_t port_addr;
7452 7452  
7453 7453          AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY, ahci_ctlp,
7454 7454              "ahci_intr_phyrdy_change enter, port %d", port);
7455 7455  
7456 7456          /* Clear PxSERR.DIAG.N to clear the interrupt bit */
7457 7457          mutex_enter(&ahci_portp->ahciport_mutex);
7458 7458          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
7459 7459              (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
7460 7460              SERROR_PHY_RDY_CHG);
7461 7461          mutex_exit(&ahci_portp->ahciport_mutex);
7462 7462  
7463 7463          mutex_enter(&ahci_ctlp->ahcictl_mutex);
7464 7464          if ((ahci_ctlp->ahcictl_sata_hba_tran == NULL) ||
7465 7465              (ahci_portp == NULL)) {
7466 7466                  /* The whole controller setup is not yet done. */
7467 7467                  mutex_exit(&ahci_ctlp->ahcictl_mutex);
7468 7468                  return (AHCI_SUCCESS);
7469 7469          }
7470 7470          mutex_exit(&ahci_ctlp->ahcictl_mutex);
7471 7471  
7472 7472          mutex_enter(&ahci_portp->ahciport_mutex);
7473 7473  
7474 7474          /* SStatus tells the presence of device. */
7475 7475          port_sstatus = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7476 7476              (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp, port));
7477 7477  
7478 7478          if (SSTATUS_GET_DET(port_sstatus) == SSTATUS_DET_DEVPRE_PHYCOM) {
7479 7479                  dev_exists_now = 1;
7480 7480          }
7481 7481  
7482 7482          if (ahci_portp->ahciport_device_type != SATA_DTYPE_NONE) {
7483 7483                  dev_existed_previously = 1;
7484 7484          }
7485 7485  
7486 7486          if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_NODEV) {
7487 7487                  ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_NODEV;
7488 7488                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
7489 7489                      "ahci_intr_phyrdy_change: port %d "
7490 7490                      "AHCI_PORT_FLAG_NODEV is cleared", port);
7491 7491                  if (dev_exists_now == 0)
7492 7492                          dev_existed_previously = 1;
7493 7493          }
7494 7494  
7495 7495          bzero((void *)&sdevice, sizeof (sata_device_t));
7496 7496          sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
7497 7497          sdevice.satadev_addr.qual = SATA_ADDR_CPORT;
7498 7498          sdevice.satadev_addr.pmport = 0;
7499 7499          sdevice.satadev_state = SATA_PSTATE_PWRON;
7500 7500          ahci_portp->ahciport_port_state = SATA_PSTATE_PWRON;
7501 7501  
7502 7502          AHCI_ADDR_SET_PORT(&port_addr, port);
7503 7503  
7504 7504          ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_HOTPLUG;
7505 7505          if (dev_exists_now) {
7506 7506                  if (dev_existed_previously) { /* 1 -> 1 */
7507 7507                          /* Things are fine now. The loss was temporary. */
7508 7508                          AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
7509 7509                              "ahci_intr_phyrdy_change  port %d "
7510 7510                              "device link lost/established", port);
7511 7511  
7512 7512                          mutex_exit(&ahci_portp->ahciport_mutex);
7513 7513                          sata_hba_event_notify(
7514 7514                              ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
7515 7515                              &sdevice,
7516 7516                              SATA_EVNT_LINK_LOST|SATA_EVNT_LINK_ESTABLISHED);
7517 7517                          mutex_enter(&ahci_portp->ahciport_mutex);
7518 7518  
7519 7519                  } else { /* 0 -> 1 */
7520 7520                          AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
7521 7521                              "ahci_intr_phyrdy_change: port %d "
7522 7522                              "device link established", port);
7523 7523  
7524 7524                          /*
7525 7525                           * A new device has been detected. The new device
7526 7526                           * might be a port multiplier instead of a drive, so
7527 7527                           * we cannot update the signature directly.
7528 7528                           */
7529 7529                          (void) ahci_initialize_port(ahci_ctlp,
7530 7530                              ahci_portp, &port_addr);
7531 7531  
7532 7532                          /* Try to start the port */
7533 7533                          if (ahci_start_port(ahci_ctlp, ahci_portp, port)
7534 7534                              != AHCI_SUCCESS) {
7535 7535                                  sdevice.satadev_state |= SATA_PSTATE_FAILED;
7536 7536                                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
7537 7537                                      "ahci_intr_phyrdy_change: port %d failed "
7538 7538                                      "at start port", port);
7539 7539                          }
7540 7540  
7541 7541                          /* Clear the max queue depth for inserted device */
7542 7542                          ahci_portp->ahciport_max_ncq_tags = 0;
7543 7543  
7544 7544                          mutex_exit(&ahci_portp->ahciport_mutex);
7545 7545                          sata_hba_event_notify(
7546 7546                              ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
7547 7547                              &sdevice,
7548 7548                              SATA_EVNT_LINK_ESTABLISHED);
7549 7549                          mutex_enter(&ahci_portp->ahciport_mutex);
7550 7550  
7551 7551                  }
7552 7552          } else { /* No device exists now */
7553 7553  
7554 7554                  if (dev_existed_previously) { /* 1 -> 0 */
7555 7555                          AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
7556 7556                              "ahci_intr_phyrdy_change: port %d "
7557 7557                              "device link lost", port);
7558 7558  
7559 7559                          ahci_reject_all_abort_pkts(ahci_ctlp, ahci_portp, port);
7560 7560                          (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
7561 7561                              ahci_portp, port);
7562 7562  
7563 7563                          if (ahci_portp->ahciport_device_type ==
7564 7564                              SATA_DTYPE_PMULT) {
7565 7565                                  ahci_dealloc_pmult(ahci_ctlp, ahci_portp);
7566 7566                          }
7567 7567  
7568 7568                          /* An existing device is lost. */
7569 7569                          ahci_portp->ahciport_device_type = SATA_DTYPE_NONE;
7570 7570                          ahci_portp->ahciport_port_state = SATA_STATE_UNKNOWN;
7571 7571  
7572 7572                          mutex_exit(&ahci_portp->ahciport_mutex);
7573 7573                          sata_hba_event_notify(
7574 7574                              ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
7575 7575                              &sdevice,
7576 7576                              SATA_EVNT_LINK_LOST);
7577 7577                          mutex_enter(&ahci_portp->ahciport_mutex);
7578 7578                  }
7579 7579          }
7580 7580          ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_HOTPLUG;
7581 7581  
7582 7582          mutex_exit(&ahci_portp->ahciport_mutex);
7583 7583  
7584 7584          return (AHCI_SUCCESS);
7585 7585  }
7586 7586  
7587 7587  /*
7588 7588   * PxIS.UFS - Unknown FIS Error
7589 7589   *
7590 7590   * This interrupt event means an unknown FIS was received and has been
7591 7591   * copied into system memory. An unknown FIS is not considered an illegal
7592 7592   * FIS, unless the length received is more than 64 bytes. If an unknown
7593 7593   * FIS arrives with length <= 64 bytes, it is posted and the HBA continues
7594 7594   * normal operation. If the unknown FIS is more than 64 bytes, then it
7595 7595   * won't be posted to memory and PxSERR.ERR.P will be set, which is then
7596 7596   * a fatal error.
7597 7597   *
7598 7598   * PxIS.IPMS - Incorrect Port Multiplier Status
7599 7599   *
7600 7600   * IPMS Indicates that the HBA received a FIS from a device that did not
7601 7601   * have a command outstanding. The IPMS bit may be set during enumeration
7602 7602   * of devices on a Port Multiplier due to the normal Port Multiplier
7603 7603   * enumeration process. It is recommended that IPMS only be used after
7604 7604   * enumeration is complete on the Port Multiplier (copied from spec).
7605 7605   *
7606 7606   * PxIS.OFS - Overflow Error
7607 7607   *
7608 7608   * Command list overflow is defined as software building a command table
7609 7609   * that has fewer total bytes than the transaction given to the device.
7610 7610   * On device writes, the HBA will run out of data, and on reads, there
7611 7611   * will be no room to put the data.
7612 7612   *
7613 7613   * For an overflow on data read, either PIO or DMA, the HBA will set
7614 7614   * PxIS.OFS, and the HBA will do a best effort to continue, and it's a
7615 7615   * non-fatal error when the HBA can continues. Sometimes, it will cause
7616 7616   * a fatal error and need the software to do something.
7617 7617   *
7618 7618   * For an overflow on data write, setting PxIS.OFS is optional for both
7619 7619   * DMA and PIO, and it's a fatal error, and a COMRESET is required by
7620 7620   * software to clean up from this serious error.
7621 7621   *
7622 7622   * PxIS.INFS - Interface Non-Fatal Error
7623 7623   *
7624 7624   * This interrupt event indicates that the HBA encountered an error on
7625 7625   * the Serial ATA interface but was able to continue operation. The kind
7626 7626   * of error usually occurred during a non-Data FIS, and under this condition
7627 7627   * the FIS will be re-transmitted by HBA automatically.
7628 7628   *
7629 7629   * When the FMA is implemented, there should be a stat structure to
7630 7630   * record how many every kind of error happens.
7631 7631   */
7632 7632  static int
7633 7633  ahci_intr_non_fatal_error(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
7634 7634      uint8_t port, uint32_t intr_status)
7635 7635  {
7636 7636          uint32_t port_serror;
7637 7637  #if AHCI_DEBUG
7638 7638          uint32_t port_cmd_status;
7639 7639          uint32_t port_cmd_issue;
7640 7640          uint32_t port_sactive;
7641 7641          int current_slot;
7642 7642          uint32_t current_tags;
7643 7643          sata_pkt_t *satapkt;
7644 7644          ahci_cmd_header_t *cmd_header;
7645 7645          uint32_t cmd_dmacount;
7646 7646  #endif
7647 7647  
7648 7648          mutex_enter(&ahci_portp->ahciport_mutex);
7649 7649  
7650 7650          port_serror = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7651 7651              (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port));
7652 7652  
7653 7653          AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY|AHCIDBG_ERRS, ahci_ctlp,
7654 7654              "ahci_intr_non_fatal_error: port %d, "
7655 7655              "PxSERR = 0x%x, PxIS = 0x%x ", port, port_serror, intr_status);
7656 7656  
7657 7657          ahci_log_serror_message(ahci_ctlp, port, port_serror, 1);
7658 7658  
7659 7659          if (intr_status & AHCI_INTR_STATUS_UFS) {
7660 7660                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
7661 7661                      "ahci port %d has unknown FIS error", port);
7662 7662  
7663 7663                  /* Clear the interrupt bit by clearing PxSERR.DIAG.F */
7664 7664                  ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
7665 7665                      (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
7666 7666                      SERROR_FIS_TYPE);
7667 7667          }
7668 7668  
7669 7669  #if AHCI_DEBUG
7670 7670          if (intr_status & AHCI_INTR_STATUS_IPMS) {
7671 7671                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci port %d "
7672 7672                      "has Incorrect Port Multiplier Status error", port);
7673 7673          }
7674 7674  
7675 7675          if (intr_status & AHCI_INTR_STATUS_OFS) {
7676 7676                  AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7677 7677                      "ahci port %d has overflow error", port);
7678 7678          }
7679 7679  
7680 7680          if (intr_status & AHCI_INTR_STATUS_INFS) {
7681 7681                  AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7682 7682                      "ahci port %d has interface non fatal error", port);
7683 7683          }
7684 7684  
7685 7685          /*
7686 7686           * Record the error occurred command's slot.
7687 7687           */
7688 7688          if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp) ||
7689 7689              ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
7690 7690                  port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7691 7691                      (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
7692 7692  
7693 7693                  current_slot = (port_cmd_status & AHCI_CMD_STATUS_CCS) >>
7694 7694                      AHCI_CMD_STATUS_CCS_SHIFT;
7695 7695  
7696 7696                  if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
7697 7697                          satapkt = ahci_portp->ahciport_err_retri_pkt;
7698 7698                          ASSERT(satapkt != NULL);
7699 7699                          ASSERT(current_slot == 0);
7700 7700                  } else {
7701 7701                          satapkt = ahci_portp->ahciport_slot_pkts[current_slot];
7702 7702                  }
7703 7703  
7704 7704                  if (satapkt != NULL) {
7705 7705                          AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7706 7706                              "ahci_intr_non_fatal_error: pending_tags = 0x%x "
7707 7707                              "cmd 0x%x", ahci_portp->ahciport_pending_tags,
7708 7708                              satapkt->satapkt_cmd.satacmd_cmd_reg);
7709 7709  
7710 7710                          AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7711 7711                              "ahci_intr_non_fatal_error: port %d, "
7712 7712                              "satapkt 0x%p is being processed when error occurs",
7713 7713                              port, (void *)satapkt);
7714 7714  
7715 7715                          /*
7716 7716                           * PRD Byte Count field of command header is not
7717 7717                           * required to reflect the total number of bytes
7718 7718                           * transferred when an overflow occurs, so here
7719 7719                           * just log the value.
7720 7720                           */
7721 7721                          cmd_dmacount =
7722 7722                              ahci_portp->ahciport_prd_bytecounts[current_slot];
7723 7723                          if (cmd_dmacount) {
7724 7724                                  cmd_header = &ahci_portp->
7725 7725                                      ahciport_cmd_list[current_slot];
7726 7726                                  AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7727 7727                                      "ahci_intr_non_fatal_error: port %d, "
7728 7728                                      "PRD Byte Count = 0x%x, "
7729 7729                                      "ahciport_prd_bytecounts = 0x%x", port,
7730 7730                                      cmd_header->ahcich_prd_byte_count,
7731 7731                                      cmd_dmacount);
7732 7732                          }
7733 7733                  }
7734 7734          } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
7735 7735                  /*
7736 7736                   * For queued command, list those command which have already
7737 7737                   * been transmitted to the device and still not completed.
7738 7738                   */
7739 7739                  port_sactive = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7740 7740                      (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
7741 7741  
7742 7742                  port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7743 7743                      (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
7744 7744  
7745 7745                  AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ|AHCIDBG_ERRS, ahci_ctlp,
7746 7746                      "ahci_intr_non_fatal_error: pending_ncq_tags = 0x%x "
7747 7747                      "port_sactive = 0x%x port_cmd_issue = 0x%x",
7748 7748                      ahci_portp->ahciport_pending_ncq_tags,
7749 7749                      port_sactive, port_cmd_issue);
7750 7750  
7751 7751                  current_tags = ahci_portp->ahciport_pending_ncq_tags &
7752 7752                      port_sactive & ~port_cmd_issue &
7753 7753                      AHCI_NCQ_SLOT_MASK(ahci_portp);
7754 7754  
7755 7755                  while (current_tags) {
7756 7756                          current_slot = ddi_ffs(current_tags) - 1;
7757 7757                          if (current_slot == -1) {
7758 7758                                  goto out;
7759 7759                          }
7760 7760  
7761 7761                          satapkt = ahci_portp->ahciport_slot_pkts[current_slot];
7762 7762                          AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ|AHCIDBG_ERRS,
7763 7763                              ahci_ctlp, "ahci_intr_non_fatal_error: "
7764 7764                              "port %d, satapkt 0x%p is outstanding when "
7765 7765                              "error occurs", port, (void *)satapkt);
7766 7766  
7767 7767                          CLEAR_BIT(current_tags, current_slot);
7768 7768                  }
7769 7769          }
7770 7770  out:
7771 7771  #endif
7772 7772          mutex_exit(&ahci_portp->ahciport_mutex);
7773 7773  
7774 7774          return (AHCI_SUCCESS);
7775 7775  }
7776 7776  
7777 7777  /*
7778 7778   * According to the AHCI spec, the error types include system memory
7779 7779   * errors, interface errors, port multiplier errors, device errors,
7780 7780   * command list overflow, command list underflow, native command
7781 7781   * queuing tag errors and pio data transfer errors.
7782 7782   *
7783 7783   * System memory errors such as target abort, master abort, and parity
7784 7784   * may cause the host to stop, and they are serious errors and needed
7785 7785   * to be recovered with software intervention. When system software
7786 7786   * has given a pointer to the HBA that doesn't exist in physical memory,
7787 7787   * a master/target abort error occurs, and PxIS.HBFS will be set. A
7788 7788   * data error such as CRC or parity occurs, the HBA aborts the transfer
7789 7789   * (if necessary) and PxIS.HBDS will be set.
7790 7790   *
7791 7791   * Interface errors are errors that occur due to electrical issues on
7792 7792   * the interface, or protocol miscommunication between the device and
7793 7793   * HBA, and the respective PxSERR register bit will be set. And PxIS.IFS
7794 7794   * (fatal) or PxIS.INFS (non-fatal) will be set. The conditions that
7795 7795   * causes PxIS.IFS/PxIS.INFS to be set are
7796 7796   *      1. in PxSERR.ERR, P bit is set to '1'
7797 7797   *      2. in PxSERR.DIAG, C or H bit is set to '1'
7798 7798   *      3. PhyRdy drop unexpectly, N bit is set to '1'
7799 7799   * If the error occurred during a non-data FIS, the FIS must be
7800 7800   * retransmitted, and the error is non-fatal and PxIS.INFS is set. If
7801 7801   * the error occurred during a data FIS, the transfer will stop, so
7802 7802   * the error is fatal and PxIS.IFS is set.
7803 7803   *
7804 7804   * When a FIS arrives that updates the taskfile, the HBA checks to see
7805 7805   * if PxTFD.STS.ERR is set. If yes, PxIS.TFES will be set and the HBA
7806 7806   * stops processing any more commands.
7807 7807   *
7808 7808   * Command list overflow is defined as software building a command table
7809 7809   * that has fewer total bytes than the transaction given to the device.
7810 7810   * On device writes, the HBA will run out of data, and on reads, there
7811 7811   * will be no room to put the data. For an overflow on data read, either
7812 7812   * PIO or DMA, the HBA will set PxIS.OFS, and it's a non-fatal error.
7813 7813   * For an overflow on data write, setting PxIS.OFS is optional for both
7814 7814   * DMA and PIO, and a COMRESET is required by software to clean up from
7815 7815   * this serious error.
7816 7816   *
7817 7817   * Command list underflow is defined as software building a command
7818 7818   * table that has more total bytes than the transaction given to the
7819 7819   * device. For data writes, both PIO and DMA, the device will detect
7820 7820   * an error and end the transfer. And these errors are most likely going
7821 7821   * to be fatal errors that will cause the port to be restarted. For
7822 7822   * data reads, the HBA updates its PRD byte count, and may be
7823 7823   * able to continue normally, but is not required to. And The HBA is
7824 7824   * not required to detect underflow conditions for native command
7825 7825   * queuing command.
7826 7826   *
7827 7827   * The HBA does not actively check incoming DMA Setup FISes to ensure
7828 7828   * that the PxSACT register bit for that slot is set. Existing error
7829 7829   * mechanisms, such as host bus failure, or bad protocol, are used to
7830 7830   * recover from this case.
7831 7831   *
7832 7832   * In accordance with Serial ATA 1.0a, DATA FISes prior to the final
7833 7833   * DATA FIS must be an integral number of Dwords. If the HBA receives
7834 7834   * a request which is not an integral number of Dwords, the HBA
7835 7835   * set PxSERR.ERR.P to '1', set PxIS.IFS to '1' and stop running until
7836 7836   * software restarts the port. And the HBA ensures that the size
7837 7837   * of the DATA FIS received during a PIO command matches the size in
7838 7838   * the Transfer Cound field of the preceding PIO Setup FIS, if not, the
7839 7839   * HBA sets PxSERR.ERR.P to '1', set PxIS.IFS to '1', and then
7840 7840   * stop running until software restarts the port.
7841 7841   */
7842 7842  /*
7843 7843   * the fatal errors include PxIS.IFS, PxIS.HBDS, PxIS.HBFS and PxIS.TFES.
7844 7844   *
7845 7845   * PxIS.IFS indicates that the hba encountered an error on the serial ata
7846 7846   * interface which caused the transfer to stop.
7847 7847   *
7848 7848   * PxIS.HBDS indicates that the hba encountered a data error
7849 7849   * (uncorrectable ecc/parity) when reading from or writing to system memory.
7850 7850   *
7851 7851   * PxIS.HBFS indicates that the hba encountered a host bus error that it
7852 7852   * cannot recover from, such as a bad software pointer.
7853 7853   *
7854 7854   * PxIS.TFES is set whenever the status register is updated by the device
7855 7855   * and the error bit (bit 0) is set.
7856 7856   */
7857 7857  static int
7858 7858  ahci_intr_fatal_error(ahci_ctl_t *ahci_ctlp,
7859 7859      ahci_port_t *ahci_portp, uint8_t port, uint32_t intr_status)
7860 7860  {
7861 7861          uint32_t port_cmd_status;
7862 7862          uint32_t port_serror;
7863 7863          uint32_t task_file_status;
7864 7864          int failed_slot;
7865 7865          sata_pkt_t *spkt = NULL;
7866 7866          uint8_t err_byte;
7867 7867          ahci_event_arg_t *args;
7868 7868          int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
7869 7869          uint32_t failed_tags = 0;
7870 7870          int task_fail_flag = 0, task_abort_flag = 0;
7871 7871          uint32_t slot_status;
7872 7872  
7873 7873          mutex_enter(&ahci_portp->ahciport_mutex);
7874 7874  
7875 7875          /*
7876 7876           * ahci_intr_phyrdy_change() may have rendered it to
7877 7877           * SATA_DTYPE_NONE.
7878 7878           */
7879 7879          if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
7880 7880                  AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
7881 7881                      "ahci_intr_fatal_error: port %d no device attached, "
7882 7882                      "and just return without doing anything", port);
7883 7883                  goto out0;
7884 7884          }
7885 7885  
7886 7886          if (intr_status & AHCI_INTR_STATUS_TFES) {
7887 7887                  task_file_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7888 7888                      (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
7889 7889                  AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7890 7890                      "ahci_intr_fatal_error: port %d "
7891 7891                      "task_file_status = 0x%x", port, task_file_status);
7892 7892                  task_fail_flag = 1;
7893 7893  
7894 7894                  err_byte = (task_file_status & AHCI_TFD_ERR_MASK)
7895 7895                      >> AHCI_TFD_ERR_SHIFT;
7896 7896                  if (err_byte == SATA_ERROR_ABORT)
7897 7897                          task_abort_flag = 1;
7898 7898          }
7899 7899  
7900 7900          /*
7901 7901           * Here we just log the fatal error info in interrupt context.
7902 7902           * Misc recovery processing will be handled in task queue.
7903 7903           */
7904 7904          if (task_fail_flag  == 1) {
7905 7905                  if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
7906 7906                          /*
7907 7907                           * Read PxCMD.CCS to determine the slot that the HBA
7908 7908                           * was processing when the error occurred.
7909 7909                           */
7910 7910                          port_cmd_status = ddi_get32(
7911 7911                              ahci_ctlp->ahcictl_ahci_acc_handle,
7912 7912                              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
7913 7913                          failed_slot = (port_cmd_status & AHCI_CMD_STATUS_CCS) >>
7914 7914                              AHCI_CMD_STATUS_CCS_SHIFT;
7915 7915                          failed_tags = 0x1 << failed_slot;
7916 7916  
7917 7917                          spkt = ahci_portp->ahciport_slot_pkts[failed_slot];
7918 7918                          AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7919 7919                              "ahci_intr_fatal_error: spkt 0x%p is being "
7920 7920                              "processed when fatal error occurred for port %d",
7921 7921                              spkt, port);
7922 7922  
7923 7923                          /*
7924 7924                           * Won't emit the error message if it is an IDENTIFY
7925 7925                           * DEVICE command sent to an ATAPI device.
7926 7926                           */
7927 7927                          if ((spkt != NULL) &&
7928 7928                              (spkt->satapkt_cmd.satacmd_cmd_reg ==
7929 7929                              SATAC_ID_DEVICE) &&
7930 7930                              (task_abort_flag == 1))
7931 7931                                  goto out1;
7932 7932  
7933 7933                          /*
7934 7934                           * Won't emit the error message if it is an ATAPI PACKET
7935 7935                           * command
7936 7936                           */
7937 7937                          if ((spkt != NULL) &&
7938 7938                              (spkt->satapkt_cmd.satacmd_cmd_reg == SATAC_PACKET))
7939 7939                                  goto out1;
7940 7940  
7941 7941                  } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
7942 7942                          slot_status = ddi_get32(
7943 7943                              ahci_ctlp->ahcictl_ahci_acc_handle,
7944 7944                              (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
7945 7945                          failed_tags = slot_status &
7946 7946                              AHCI_NCQ_SLOT_MASK(ahci_portp);
7947 7947                  }
7948 7948          }
7949 7949  
7950 7950          /* print the fatal error type */
7951 7951          ahci_log_fatal_error_message(ahci_ctlp, port, intr_status);
7952 7952          ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_ERRPRINT;
7953 7953  
7954 7954          port_serror = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7955 7955              (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port));
7956 7956  
7957 7957          /* print PxSERR related error message */
7958 7958          ahci_log_serror_message(ahci_ctlp, port, port_serror, 0);
7959 7959  
7960 7960          /* print task file register value */
7961 7961          if (task_fail_flag == 1) {
7962 7962                  cmn_err(CE_WARN, "!ahci%d: ahci port %d task_file_status "
7963 7963                      "= 0x%x", instance, port, task_file_status);
7964 7964                  if (task_abort_flag == 1) {
7965 7965                          cmn_err(CE_WARN, "!ahci%d: the below command (s) on "
7966 7966                              "port %d are aborted", instance, port);
7967 7967                          ahci_dump_commands(ahci_ctlp, port, failed_tags);
7968 7968                  }
7969 7969          }
7970 7970  
7971 7971  out1:
7972 7972          /* Prepare the argument for the taskq */
7973 7973          args = ahci_portp->ahciport_event_args;
7974 7974          args->ahciea_ctlp = (void *)ahci_ctlp;
7975 7975          args->ahciea_portp = (void *)ahci_portp;
7976 7976          args->ahciea_event = intr_status;
7977 7977          AHCI_ADDR_SET_PORT((ahci_addr_t *)args->ahciea_addrp, port);
7978 7978  
7979 7979          /* Start the taskq to handle error recovery */
7980 7980          if ((ddi_taskq_dispatch(ahci_portp->ahciport_event_taskq,
7981 7981              ahci_events_handler,
7982 7982              (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) {
7983 7983                  ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_ERRPRINT;
7984 7984                  cmn_err(CE_WARN, "!ahci%d: start taskq for error recovery "
7985 7985                      "port %d failed", instance, port);
7986 7986          }
7987 7987  out0:
7988 7988          mutex_exit(&ahci_portp->ahciport_mutex);
7989 7989  
7990 7990          return (AHCI_SUCCESS);
7991 7991  }
7992 7992  
7993 7993  /*
7994 7994   * Hot Plug Operation for platforms that support Cold Presence Detect.
7995 7995   *
7996 7996   * When set, a device status has changed as detected by the cold presence
7997 7997   * detect logic. This bit can either be set due to a non-connected port
7998 7998   * receiving a device, or a connected port having its device removed.
7999 7999   * This bit is only valid if the port supports cold presence detect as
8000 8000   * indicated by PxCMD.CPD set to '1'.
8001 8001   *
8002 8002   * At the moment, this interrupt is not needed and disabled and we just
8003 8003   * log the debug message.
8004 8004   */
8005 8005  static int
8006 8006  ahci_intr_cold_port_detect(ahci_ctl_t *ahci_ctlp,
8007 8007      ahci_port_t *ahci_portp, uint8_t port)
8008 8008  {
8009 8009          uint32_t port_cmd_status;
8010 8010          sata_device_t sdevice;
8011 8011  
8012 8012          AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8013 8013              "ahci_intr_cold_port_detect enter, port %d", port);
8014 8014  
8015 8015          mutex_enter(&ahci_portp->ahciport_mutex);
8016 8016  
8017 8017          port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8018 8018              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
8019 8019          if (!(port_cmd_status & AHCI_CMD_STATUS_CPD)) {
8020 8020                  AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8021 8021                      "port %d does not support cold presence detect, so "
8022 8022                      "we just ignore this interrupt", port);
8023 8023                  mutex_exit(&ahci_portp->ahciport_mutex);
8024 8024                  return (AHCI_SUCCESS);
8025 8025          }
8026 8026  
8027 8027          AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8028 8028              "port %d device status has changed", port);
8029 8029  
8030 8030          bzero((void *)&sdevice, sizeof (sata_device_t));
8031 8031          sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
8032 8032          sdevice.satadev_addr.qual = SATA_ADDR_CPORT;
8033 8033          sdevice.satadev_addr.pmport = 0;
8034 8034          sdevice.satadev_state = SATA_PSTATE_PWRON;
8035 8035  
8036 8036          if (port_cmd_status & AHCI_CMD_STATUS_CPS) {
8037 8037                  AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8038 8038                      "port %d: a device is hot plugged", port);
8039 8039                  mutex_exit(&ahci_portp->ahciport_mutex);
8040 8040                  sata_hba_event_notify(
8041 8041                      ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
8042 8042                      &sdevice,
8043 8043                      SATA_EVNT_DEVICE_ATTACHED);
8044 8044                  mutex_enter(&ahci_portp->ahciport_mutex);
8045 8045  
8046 8046          } else {
8047 8047                  AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8048 8048                      "port %d: a device is hot unplugged", port);
8049 8049                  mutex_exit(&ahci_portp->ahciport_mutex);
8050 8050                  sata_hba_event_notify(
8051 8051                      ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
8052 8052                      &sdevice,
8053 8053                      SATA_EVNT_DEVICE_DETACHED);
8054 8054                  mutex_enter(&ahci_portp->ahciport_mutex);
8055 8055          }
8056 8056  
8057 8057          mutex_exit(&ahci_portp->ahciport_mutex);
8058 8058  
8059 8059          return (AHCI_SUCCESS);
8060 8060  }
8061 8061  
8062 8062  /*
8063 8063   * Enable the interrupts for a particular port.
8064 8064   */
8065 8065  static void
8066 8066  ahci_enable_port_intrs(ahci_ctl_t *ahci_ctlp, uint8_t port)
8067 8067  {
8068 8068          ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
8069 8069  
8070 8070          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
8071 8071              "ahci_enable_port_intrs enter, port %d", port);
8072 8072  
8073 8073          /*
8074 8074           * Clear port interrupt status before enabling interrupt
8075 8075           */
8076 8076          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8077 8077              (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port),
8078 8078              AHCI_PORT_INTR_MASK);
8079 8079  
8080 8080          /*
8081 8081           * Clear the pending bit from IS.IPS
8082 8082           */
8083 8083          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8084 8084              (uint32_t *)AHCI_GLOBAL_IS(ahci_ctlp), (1 << port));
8085 8085  
8086 8086          /*
8087 8087           * Enable the following interrupts:
8088 8088           *      Device to Host Register FIS Interrupt (DHRS)
8089 8089           *      PIO Setup FIS Interrupt (PSS)
8090 8090           *      Set Device Bits Interrupt (SDBS)
8091 8091           *      Unknown FIS Interrupt (UFS)
8092 8092           *      Port Connect Change Status (PCS)
8093 8093           *      PhyRdy Change Status (PRCS)
8094 8094           *      Overflow Status (OFS)
8095 8095           *      Interface Non-fatal Error Status (INFS)
8096 8096           *      Interface Fatal Error Status (IFS)
8097 8097           *      Host Bus Data Error Status (HBDS)
8098 8098           *      Host Bus Fatal Error Status (HBFS)
8099 8099           *      Task File Error Status (TFES)
8100 8100           */
8101 8101          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8102 8102              (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port),
8103 8103              (AHCI_INTR_STATUS_DHRS |
8104 8104              AHCI_INTR_STATUS_PSS |
8105 8105              AHCI_INTR_STATUS_SDBS |
8106 8106              AHCI_INTR_STATUS_UFS |
8107 8107              AHCI_INTR_STATUS_DPS |
8108 8108              AHCI_INTR_STATUS_PCS |
8109 8109              AHCI_INTR_STATUS_PRCS |
8110 8110              AHCI_INTR_STATUS_OFS |
8111 8111              AHCI_INTR_STATUS_INFS |
8112 8112              AHCI_INTR_STATUS_IFS |
8113 8113              AHCI_INTR_STATUS_HBDS |
8114 8114              AHCI_INTR_STATUS_HBFS |
8115 8115              AHCI_INTR_STATUS_TFES));
8116 8116  }
8117 8117  
8118 8118  /*
8119 8119   * Enable interrupts for all the ports.
8120 8120   */
8121 8121  static void
8122 8122  ahci_enable_all_intrs(ahci_ctl_t *ahci_ctlp)
8123 8123  {
8124 8124          uint32_t ghc_control;
8125 8125  
8126 8126          ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_mutex));
8127 8127  
8128 8128          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_enable_all_intrs enter", NULL);
8129 8129  
8130 8130          ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8131 8131              (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
8132 8132  
8133 8133          ghc_control |= AHCI_HBA_GHC_IE;
8134 8134  
8135 8135          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8136 8136              (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
8137 8137  }
8138 8138  
8139 8139  /*
8140 8140   * Disable interrupts for a particular port.
8141 8141   */
8142 8142  static void
8143 8143  ahci_disable_port_intrs(ahci_ctl_t *ahci_ctlp, uint8_t port)
8144 8144  {
8145 8145          ASSERT(ahci_ctlp->ahcictl_flags & AHCI_QUIESCE ||
8146 8146              MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
8147 8147  
8148 8148          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
8149 8149              "ahci_disable_port_intrs enter, port %d", port);
8150 8150  
8151 8151          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8152 8152              (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port), 0);
8153 8153  }
8154 8154  
8155 8155  /*
8156 8156   * Disable interrupts for the whole HBA.
8157 8157   *
8158 8158   * The global bit is cleared, then all interrupt sources from all
8159 8159   * ports are disabled.
8160 8160   */
8161 8161  static void
8162 8162  ahci_disable_all_intrs(ahci_ctl_t *ahci_ctlp)
8163 8163  {
8164 8164          uint32_t ghc_control;
8165 8165  
8166 8166          ASSERT(ahci_ctlp->ahcictl_flags & (AHCI_ATTACH | AHCI_QUIESCE) ||
8167 8167              MUTEX_HELD(&ahci_ctlp->ahcictl_mutex));
8168 8168  
8169 8169          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_disable_all_intrs enter",
8170 8170              NULL);
8171 8171  
8172 8172          ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8173 8173              (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
8174 8174  
8175 8175          ghc_control &= ~AHCI_HBA_GHC_IE;
8176 8176  
8177 8177          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8178 8178              (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
8179 8179  }
8180 8180  
8181 8181  /*
8182 8182   * Handle FIXED or MSI interrupts.
8183 8183   */
8184 8184  /*
8185 8185   * According to AHCI spec, the HBA may support several interrupt modes:
8186 8186   *      * pin based interrupts (FIXED)
8187 8187   *      * single MSI message interrupts
8188 8188   *      * multiple MSI based message interrupts
8189 8189   *
8190 8190   * For pin based interrupts, the software interrupt handler need to check IS
8191 8191   * register to find out which port has pending interrupts. And then check
8192 8192   * PxIS register to find out which interrupt events happened on that port.
8193 8193   *
8194 8194   * For single MSI message interrupts, MSICAP.MC.MSIE is set with '1', and
8195 8195   * MSICAP.MC.MME is set with '0'. This mode is similar to pin based interrupts
8196 8196   * in that software interrupt handler need to check IS register to determine
8197 8197   * which port triggered the interrupts since it uses a single message for all
8198 8198   * port interrupts.
8199 8199   *
8200 8200   * HBA may optionally support multiple MSI message for better performance. In
8201 8201   * this mode, each port may have its own interrupt message, and thus generation
8202 8202   * of interrupts is no longer controlled through the IS register. MSICAP.MC.MMC
8203 8203   * represents a power-of-2 wrapper on the number of implemented ports, and
8204 8204   * the mapping of ports to interrupts is done in a 1-1 relationship, up to the
8205 8205   * maximum number of assigned interrupts. When the number of MSI messages
8206 8206   * allocated is less than the number requested, then hardware may have two
8207 8207   * implementation behaviors:
8208 8208   *      * assign each ports its own interrupt and then force all additional
8209 8209   *        ports to share the last interrupt message, and this condition is
8210 8210   *        indicated by clearing GHC.MRSM to '0'
8211 8211   *      * revert to single MSI mode, indicated by setting GHC.MRSM to '1'
8212 8212   * When multiple-message MSI is enabled, hardware will still set IS register
8213 8213   * as single message case. And this IS register may be used by software when
8214 8214   * fewer than the requested number of messages is granted in order to determine
8215 8215   * which port had the interrupt.
8216 8216   *
8217 8217   * Note: The current ahci driver only supports the first two interrupt modes:
8218 8218   * pin based interrupts and single MSI message interrupts, and the reason
8219 8219   * is indicated in below code.
8220 8220   */
8221 8221  static int
8222 8222  ahci_add_intrs(ahci_ctl_t *ahci_ctlp, int intr_type)
8223 8223  {
8224 8224          dev_info_t *dip = ahci_ctlp->ahcictl_dip;
8225 8225          int             count, avail, actual;
8226 8226          int             i, rc;
8227 8227  
8228 8228          AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
8229 8229              "ahci_add_intrs enter interrupt type 0x%x", intr_type);
8230 8230  
8231 8231          /* get number of interrupts. */
8232 8232          rc = ddi_intr_get_nintrs(dip, intr_type, &count);
8233 8233          if ((rc != DDI_SUCCESS) || (count == 0)) {
8234 8234                  AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8235 8235                      "ddi_intr_get_nintrs() failed, "
8236 8236                      "rc %d count %d\n", rc, count);
8237 8237                  return (DDI_FAILURE);
8238 8238          }
8239 8239  
8240 8240          /* get number of available interrupts. */
8241 8241          rc = ddi_intr_get_navail(dip, intr_type, &avail);
8242 8242          if ((rc != DDI_SUCCESS) || (avail == 0)) {
8243 8243                  AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8244 8244                      "ddi_intr_get_navail() failed, "
8245 8245                      "rc %d avail %d\n", rc, avail);
8246 8246                  return (DDI_FAILURE);
8247 8247          }
8248 8248  
8249 8249  #if AHCI_DEBUG
8250 8250          if (avail < count) {
8251 8251                  AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8252 8252                      "ddi_intr_get_nintrs returned %d, navail() returned %d",
8253 8253                      count, avail);
8254 8254          }
8255 8255  #endif
8256 8256  
8257 8257          /*
8258 8258           * Note: So far Solaris restricts the maximum number of messages for
8259 8259           * x86 to 2, that is avail is 2, so here we set the count with 1 to
8260 8260           * force the driver to use single MSI message interrupt. In future if
8261 8261           * Solaris remove the restriction, then we need to delete the below
8262 8262           * code and try to use multiple interrupt routine to gain better
8263 8263           * performance.
8264 8264           */
8265 8265          if ((intr_type == DDI_INTR_TYPE_MSI) && (count > 1)) {
8266 8266                  AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8267 8267                      "force to use one interrupt routine though the "
8268 8268                      "HBA supports %d interrupt", count);
8269 8269                  count = 1;
8270 8270          }
8271 8271  
8272 8272          /* Allocate an array of interrupt handles. */
8273 8273          ahci_ctlp->ahcictl_intr_size = count * sizeof (ddi_intr_handle_t);
8274 8274          ahci_ctlp->ahcictl_intr_htable =
8275 8275              kmem_alloc(ahci_ctlp->ahcictl_intr_size, KM_SLEEP);
8276 8276  
8277 8277          /* call ddi_intr_alloc(). */
8278 8278          rc = ddi_intr_alloc(dip, ahci_ctlp->ahcictl_intr_htable,
8279 8279              intr_type, 0, count, &actual, DDI_INTR_ALLOC_NORMAL);
8280 8280  
8281 8281          if ((rc != DDI_SUCCESS) || (actual == 0)) {
8282 8282                  AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8283 8283                      "ddi_intr_alloc() failed, rc %d count %d actual %d "
8284 8284                      "avail %d\n", rc, count, actual, avail);
8285 8285                  kmem_free(ahci_ctlp->ahcictl_intr_htable,
8286 8286                      ahci_ctlp->ahcictl_intr_size);
8287 8287                  return (DDI_FAILURE);
8288 8288          }
8289 8289  
8290 8290          /* use interrupt count returned */
8291 8291  #if AHCI_DEBUG
8292 8292          if (actual < count) {
8293 8293                  AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8294 8294                      "Requested: %d, Received: %d", count, actual);
8295 8295          }
8296 8296  #endif
8297 8297  
8298 8298          ahci_ctlp->ahcictl_intr_cnt = actual;
8299 8299  
8300 8300          /*
8301 8301           * Get priority for first, assume remaining are all the same.
8302 8302           */
8303 8303          if (ddi_intr_get_pri(ahci_ctlp->ahcictl_intr_htable[0],
8304 8304              &ahci_ctlp->ahcictl_intr_pri) != DDI_SUCCESS) {
8305 8305                  AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8306 8306                      "ddi_intr_get_pri() failed", NULL);
8307 8307  
8308 8308                  /* Free already allocated intr. */
8309 8309                  for (i = 0; i < actual; i++) {
8310 8310                          (void) ddi_intr_free(ahci_ctlp->ahcictl_intr_htable[i]);
8311 8311                  }
8312 8312  
8313 8313                  kmem_free(ahci_ctlp->ahcictl_intr_htable,
8314 8314                      ahci_ctlp->ahcictl_intr_size);
8315 8315                  return (DDI_FAILURE);
8316 8316          }
8317 8317  
8318 8318          /* Test for high level interrupt. */
8319 8319          if (ahci_ctlp->ahcictl_intr_pri >= ddi_intr_get_hilevel_pri()) {
8320 8320                  AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8321 8321                      "ahci_add_intrs: Hi level intr not supported", NULL);
8322 8322  
8323 8323                  /* Free already allocated intr. */
8324 8324                  for (i = 0; i < actual; i++) {
8325 8325                          (void) ddi_intr_free(ahci_ctlp->ahcictl_intr_htable[i]);
8326 8326                  }
8327 8327  
8328 8328                  kmem_free(ahci_ctlp->ahcictl_intr_htable,
8329 8329                      sizeof (ddi_intr_handle_t));
8330 8330  
8331 8331                  return (DDI_FAILURE);
8332 8332          }
8333 8333  
8334 8334          /* Call ddi_intr_add_handler(). */
8335 8335          for (i = 0; i < actual; i++) {
8336 8336                  if (ddi_intr_add_handler(ahci_ctlp->ahcictl_intr_htable[i],
8337 8337                      ahci_intr, (caddr_t)ahci_ctlp, NULL) != DDI_SUCCESS) {
8338 8338                          AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8339 8339                              "ddi_intr_add_handler() failed", NULL);
8340 8340  
8341 8341                          /* Free already allocated intr. */
8342 8342                          for (i = 0; i < actual; i++) {
8343 8343                                  (void) ddi_intr_free(
8344 8344                                      ahci_ctlp->ahcictl_intr_htable[i]);
8345 8345                          }
8346 8346  
8347 8347                          kmem_free(ahci_ctlp->ahcictl_intr_htable,
8348 8348                              ahci_ctlp->ahcictl_intr_size);
8349 8349                          return (DDI_FAILURE);
8350 8350                  }
8351 8351          }
8352 8352  
8353 8353          if (ddi_intr_get_cap(ahci_ctlp->ahcictl_intr_htable[0],
8354 8354              &ahci_ctlp->ahcictl_intr_cap) != DDI_SUCCESS) {
8355 8355                  AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8356 8356                      "ddi_intr_get_cap() failed", NULL);
8357 8357  
8358 8358                  /* Free already allocated intr. */
8359 8359                  for (i = 0; i < actual; i++) {
8360 8360                          (void) ddi_intr_free(
8361 8361                              ahci_ctlp->ahcictl_intr_htable[i]);
8362 8362                  }
8363 8363  
8364 8364                  kmem_free(ahci_ctlp->ahcictl_intr_htable,
8365 8365                      ahci_ctlp->ahcictl_intr_size);
8366 8366                  return (DDI_FAILURE);
8367 8367          }
8368 8368  
8369 8369          if (ahci_ctlp->ahcictl_intr_cap & DDI_INTR_FLAG_BLOCK) {
8370 8370                  /* Call ddi_intr_block_enable() for MSI. */
8371 8371                  (void) ddi_intr_block_enable(ahci_ctlp->ahcictl_intr_htable,
8372 8372                      ahci_ctlp->ahcictl_intr_cnt);
8373 8373          } else {
8374 8374                  /* Call ddi_intr_enable() for FIXED or MSI non block enable. */
8375 8375                  for (i = 0; i < ahci_ctlp->ahcictl_intr_cnt; i++) {
8376 8376                          (void) ddi_intr_enable(
8377 8377                              ahci_ctlp->ahcictl_intr_htable[i]);
8378 8378                  }
8379 8379          }
8380 8380  
8381 8381          return (DDI_SUCCESS);
8382 8382  }
8383 8383  
8384 8384  /*
8385 8385   * Removes the registered interrupts irrespective of whether they
8386 8386   * were legacy or MSI.
8387 8387   *
8388 8388   * NOTE: The controller interrupts must be disabled before calling
8389 8389   * this routine.
8390 8390   */
8391 8391  static void
8392 8392  ahci_rem_intrs(ahci_ctl_t *ahci_ctlp)
8393 8393  {
8394 8394          int x;
8395 8395  
8396 8396          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_rem_intrs entered", NULL);
8397 8397  
8398 8398          /* Disable all interrupts. */
8399 8399          if ((ahci_ctlp->ahcictl_intr_type == DDI_INTR_TYPE_MSI) &&
8400 8400              (ahci_ctlp->ahcictl_intr_cap & DDI_INTR_FLAG_BLOCK)) {
8401 8401                  /* Call ddi_intr_block_disable(). */
8402 8402                  (void) ddi_intr_block_disable(ahci_ctlp->ahcictl_intr_htable,
8403 8403                      ahci_ctlp->ahcictl_intr_cnt);
8404 8404          } else {
8405 8405                  for (x = 0; x < ahci_ctlp->ahcictl_intr_cnt; x++) {
8406 8406                          (void) ddi_intr_disable(
8407 8407                              ahci_ctlp->ahcictl_intr_htable[x]);
8408 8408                  }
8409 8409          }
8410 8410  
8411 8411          /* Call ddi_intr_remove_handler(). */
8412 8412          for (x = 0; x < ahci_ctlp->ahcictl_intr_cnt; x++) {
8413 8413                  (void) ddi_intr_remove_handler(
8414 8414                      ahci_ctlp->ahcictl_intr_htable[x]);
8415 8415                  (void) ddi_intr_free(ahci_ctlp->ahcictl_intr_htable[x]);
8416 8416          }
8417 8417  
8418 8418          kmem_free(ahci_ctlp->ahcictl_intr_htable, ahci_ctlp->ahcictl_intr_size);
8419 8419  }
8420 8420  
8421 8421  /*
8422 8422   * This routine tries to put port into P:NotRunning state by clearing
8423 8423   * PxCMD.ST. HBA will clear PxCI to 0h, PxSACT to 0h, PxCMD.CCS to 0h
8424 8424   * and PxCMD.CR to '0'.
8425 8425   */
8426 8426  static int
8427 8427  ahci_put_port_into_notrunning_state(ahci_ctl_t *ahci_ctlp,
8428 8428      ahci_port_t *ahci_portp, uint8_t port)
8429 8429  {
8430 8430          uint32_t port_cmd_status;
8431 8431          int loop_count;
8432 8432  
8433 8433          ASSERT(ahci_ctlp->ahcictl_flags & AHCI_QUIESCE ||
8434 8434              MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
8435 8435  
8436 8436          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
8437 8437              "ahci_put_port_into_notrunning_state enter: port %d", port);
8438 8438  
8439 8439          port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8440 8440              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
8441 8441  
8442 8442          port_cmd_status &= ~AHCI_CMD_STATUS_ST;
8443 8443          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8444 8444              (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port), port_cmd_status);
8445 8445  
8446 8446          /* Wait until PxCMD.CR is cleared */
8447 8447          loop_count = 0;
8448 8448          do {
8449 8449                  port_cmd_status =
8450 8450                      ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8451 8451                      (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
8452 8452  
8453 8453                  if (loop_count++ > AHCI_POLLRATE_PORT_IDLE) {
8454 8454                          AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
8455 8455                              "clearing port %d CMD.CR timeout, "
8456 8456                              "port_cmd_status = 0x%x", port,
8457 8457                              port_cmd_status);
8458 8458                          /*
8459 8459                           * We are effectively timing out after 0.5 sec.
8460 8460                           * This value is specified in AHCI spec.
8461 8461                           */
8462 8462                          break;
8463 8463                  }
8464 8464  
8465 8465                  /* Wait for 10 millisec */
8466 8466                  drv_usecwait(AHCI_10MS_USECS);
8467 8467          } while (port_cmd_status & AHCI_CMD_STATUS_CR);
8468 8468  
8469 8469          ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_STARTED;
8470 8470  
8471 8471          if (port_cmd_status & AHCI_CMD_STATUS_CR) {
8472 8472                  AHCIDBG(AHCIDBG_INIT|AHCIDBG_POLL_LOOP, ahci_ctlp,
8473 8473                      "ahci_put_port_into_notrunning_state: failed to clear "
8474 8474                      "PxCMD.CR to '0' after loop count: %d, and "
8475 8475                      "port_cmd_status = 0x%x", loop_count, port_cmd_status);
8476 8476                  return (AHCI_FAILURE);
8477 8477          } else {
8478 8478                  AHCIDBG(AHCIDBG_INIT|AHCIDBG_POLL_LOOP, ahci_ctlp,
8479 8479                      "ahci_put_port_into_notrunning_state: succeeded to clear "
8480 8480                      "PxCMD.CR to '0' after loop count: %d, and "
8481 8481                      "port_cmd_status = 0x%x", loop_count, port_cmd_status);
8482 8482                  return (AHCI_SUCCESS);
8483 8483          }
8484 8484  }
8485 8485  
8486 8486  /*
8487 8487   * First clear PxCMD.ST, and then check PxTFD. If both PxTFD.STS.BSY
8488 8488   * and PxTFD.STS.DRQ cleared to '0', it means the device is in a
8489 8489   * stable state, then set PxCMD.ST to '1' to start the port directly.
8490 8490   * If PxTFD.STS.BSY or PxTFD.STS.DRQ is set to '1', then issue a
8491 8491   * COMRESET to the device to put it in an idle state.
8492 8492   *
8493 8493   * The fifth argument returns whether the port reset is involved during
8494 8494   * the process.
8495 8495   *
8496 8496   * The routine will be called under following scenarios:
8497 8497   *      + To reset the HBA
8498 8498   *      + To abort the packet(s)
8499 8499   *      + To reset the port
8500 8500   *      + To activate the port
8501 8501   *      + Fatal error recovery
8502 8502   *      + To abort the timeout packet(s)
8503 8503   *
8504 8504   * NOTES!!! During this procedure, PxSERR register will be cleared, and
8505 8505   * according to the spec, the clearance of three bits will also clear
8506 8506   * three interrupt status bits.
8507 8507   *      1. PxSERR.DIAG.F will clear PxIS.UFS
8508 8508   *      2. PxSERR.DIAG.X will clear PxIS.PCS
8509 8509   *      3. PxSERR.DIAG.N will clear PxIS.PRCS
8510 8510   *
8511 8511   * Among these three interrupt events, the driver needs to take care of
8512 8512   * PxIS.PRCS, which is the hot plug event. When the driver found out
8513 8513   * a device was unplugged, it will call the interrupt handler.
8514 8514   */
8515 8515  static int
8516 8516  ahci_restart_port_wait_till_ready(ahci_ctl_t *ahci_ctlp,
8517 8517      ahci_port_t *ahci_portp, uint8_t port, int flag, int *reset_flag)
8518 8518  {
8519 8519          uint32_t port_sstatus;
8520 8520          uint32_t task_file_status;
8521 8521          sata_device_t sdevice;
8522 8522          int rval;
8523 8523          ahci_addr_t addr_port;
8524 8524          ahci_pmult_info_t *pminfo = NULL;
8525 8525          int dev_exists_begin = 0;
8526 8526          int dev_exists_end = 0;
8527 8527          uint32_t previous_dev_type = ahci_portp->ahciport_device_type;
8528 8528          int npmport = 0;
8529 8529          uint8_t cport = ahci_ctlp->ahcictl_port_to_cport[port];
8530 8530  
8531 8531          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
8532 8532  
8533 8533          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
8534 8534              "ahci_restart_port_wait_till_ready: port %d enter", port);
8535 8535  
8536 8536          AHCI_ADDR_SET_PORT(&addr_port, port);
8537 8537  
8538 8538          if (ahci_portp->ahciport_device_type != SATA_DTYPE_NONE)
8539 8539                  dev_exists_begin = 1;
8540 8540  
8541 8541          /* First clear PxCMD.ST */
8542 8542          rval = ahci_put_port_into_notrunning_state(ahci_ctlp, ahci_portp,
8543 8543              port);
8544 8544          if (rval != AHCI_SUCCESS)
8545 8545                  /*
8546 8546                   * If PxCMD.CR does not clear within a reasonable time, it
8547 8547                   * may assume the interface is in a hung condition and may
8548 8548                   * continue with issuing the port reset.
8549 8549                   */
8550 8550                  goto reset;
8551 8551  
8552 8552          /* Then clear PxSERR */
8553 8553          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8554 8554              (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
8555 8555              AHCI_SERROR_CLEAR_ALL);
8556 8556  
8557 8557          /* Then get PxTFD */
8558 8558          task_file_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8559 8559              (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
8560 8560  
8561 8561          /*
8562 8562           * Check whether the device is in a stable status, if yes,
8563 8563           * then start the port directly. However for ahci_tran_reset_dport,
8564 8564           * we may have to perform a port reset.
8565 8565           */
8566 8566          if (!(task_file_status & (AHCI_TFD_STS_BSY | AHCI_TFD_STS_DRQ)) &&
8567 8567              !(flag & AHCI_PORT_RESET))
8568 8568                  goto out;
8569 8569  
8570 8570  reset:
8571 8571          /*
8572 8572           * If PxTFD.STS.BSY or PxTFD.STS.DRQ is set to '1', then issue
8573 8573           * a COMRESET to the device
8574 8574           */
8575 8575          ahci_disable_port_intrs(ahci_ctlp, port);
8576 8576          rval = ahci_port_reset(ahci_ctlp, ahci_portp, &addr_port);
8577 8577          ahci_enable_port_intrs(ahci_ctlp, port);
8578 8578  
8579 8579  #ifdef AHCI_DEBUG
8580 8580          if (rval != AHCI_SUCCESS)
8581 8581                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8582 8582                      "ahci_restart_port_wait_till_ready: port %d failed",
8583 8583                      port);
8584 8584  #endif
8585 8585  
8586 8586          if (reset_flag != NULL)
8587 8587                  *reset_flag = 1;
8588 8588  
8589 8589          /* Indicate to the framework that a reset has happened. */
8590 8590          if ((ahci_portp->ahciport_device_type != SATA_DTYPE_NONE) &&
8591 8591              (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) &&
8592 8592              !(flag & AHCI_RESET_NO_EVENTS_UP)) {
8593 8593                  /* Set the reset in progress flag */
8594 8594                  ahci_portp->ahciport_reset_in_progress = 1;
8595 8595  
8596 8596                  bzero((void *)&sdevice, sizeof (sata_device_t));
8597 8597                  sdevice.satadev_addr.cport =
8598 8598                      ahci_ctlp->ahcictl_port_to_cport[port];
8599 8599                  sdevice.satadev_addr.pmport = 0;
8600 8600                  sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
8601 8601  
8602 8602                  sdevice.satadev_state = SATA_DSTATE_RESET |
8603 8603                      SATA_DSTATE_PWR_ACTIVE;
8604 8604                  if (ahci_ctlp->ahcictl_sata_hba_tran) {
8605 8605                          mutex_exit(&ahci_portp->ahciport_mutex);
8606 8606                          sata_hba_event_notify(
8607 8607                              ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
8608 8608                              &sdevice,
8609 8609                              SATA_EVNT_DEVICE_RESET);
8610 8610                          mutex_enter(&ahci_portp->ahciport_mutex);
8611 8611                  }
8612 8612  
8613 8613                  AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
8614 8614                      "port %d sending event up: SATA_EVNT_DEVICE_RESET", port);
8615 8615          } else {
8616 8616                  ahci_portp->ahciport_reset_in_progress = 0;
8617 8617          }
8618 8618  
8619 8619  out:
8620 8620          (void) ahci_start_port(ahci_ctlp, ahci_portp, port);
8621 8621  
8622 8622          /* SStatus tells the presence of device. */
8623 8623          port_sstatus = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8624 8624              (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp, port));
8625 8625  
8626 8626          if (SSTATUS_GET_DET(port_sstatus) == SSTATUS_DET_DEVPRE_PHYCOM) {
8627 8627                  dev_exists_end = 1;
8628 8628          }
8629 8629  
8630 8630          if (dev_exists_begin == 0 && dev_exists_end == 0) /* 0 -> 0 */
8631 8631                  return (rval);
8632 8632  
8633 8633          /* Check whether a hot plug event happened */
8634 8634          if (dev_exists_begin == 1 && dev_exists_end == 0) { /* 1 -> 0 */
8635 8635                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8636 8636                      "ahci_restart_port_wait_till_ready: port %d "
8637 8637                      "device is removed", port);
8638 8638                  ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_NODEV;
8639 8639                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8640 8640                      "ahci_restart_port_wait_till_ready: port %d "
8641 8641                      "AHCI_PORT_FLAG_NODEV flag is set", port);
8642 8642                  mutex_exit(&ahci_portp->ahciport_mutex);
8643 8643                  (void) ahci_intr_phyrdy_change(ahci_ctlp, ahci_portp, port);
8644 8644                  mutex_enter(&ahci_portp->ahciport_mutex);
8645 8645  
8646 8646                  return (rval);
8647 8647          }
8648 8648  
8649 8649  
8650 8650          /* 0/1 -> 1 : device may change */
8651 8651          /*
8652 8652           * May be called by ahci_fatal_error_recovery_handler, so
8653 8653           * don't issue software if the previous device is ATAPI.
8654 8654           */
8655 8655          if (ahci_portp->ahciport_device_type == SATA_DTYPE_ATAPI)
8656 8656                  return (rval);
8657 8657  
8658 8658          /*
8659 8659           * The COMRESET will make port multiplier enter legacy mode.
8660 8660           * Issue a software reset to make it work again.
8661 8661           */
8662 8662          ahci_disable_port_intrs(ahci_ctlp, port);
8663 8663          ahci_find_dev_signature(ahci_ctlp, ahci_portp, &addr_port);
8664 8664          ahci_enable_port_intrs(ahci_ctlp, port);
8665 8665  
8666 8666          /*
8667 8667           * Following codes are specific for the port multiplier
8668 8668           */
8669 8669          if (previous_dev_type != SATA_DTYPE_PMULT &&
8670 8670              ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) {
8671 8671                  /* in case previous_dev_type is corrupt */
8672 8672                  ahci_dealloc_pmult(ahci_ctlp, ahci_portp);
8673 8673                  (void) ahci_start_port(ahci_ctlp, ahci_portp, port);
8674 8674                  return (rval);
8675 8675          }
8676 8676  
8677 8677          /* Device change: PMult -> Non-PMult */
8678 8678          if (previous_dev_type == SATA_DTYPE_PMULT &&
8679 8679              ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) {
8680 8680                  /*
8681 8681                   * This might happen because
8682 8682                   * 1. Software reset failed. Port multiplier is not correctly
8683 8683                   *    enumerated.
8684 8684                   * 2. Another non-port-multiplier device is attached. Perhaps
8685 8685                   *    the port multiplier was replaced by another device by
8686 8686                   *    whatever reason, but AHCI driver missed hot-plug event.
8687 8687                   *
8688 8688                   * Now that the port has been initialized, we just need to
8689 8689                   * update the port structure according new device, then report
8690 8690                   * and wait SATA framework to probe new device.
8691 8691                   */
8692 8692  
8693 8693                  /* Force to release pmult resource */
8694 8694                  ahci_dealloc_pmult(ahci_ctlp, ahci_portp);
8695 8695                  (void) ahci_start_port(ahci_ctlp, ahci_portp, port);
8696 8696  
8697 8697                  bzero((void *)&sdevice, sizeof (sata_device_t));
8698 8698                  sdevice.satadev_addr.cport =
8699 8699                      ahci_ctlp->ahcictl_port_to_cport[port];
8700 8700                  sdevice.satadev_addr.pmport = 0;
8701 8701                  sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
8702 8702  
8703 8703                  sdevice.satadev_state = SATA_DSTATE_RESET |
8704 8704                      SATA_DSTATE_PWR_ACTIVE;
8705 8705  
8706 8706                  mutex_exit(&ahci_portp->ahciport_mutex);
8707 8707                  sata_hba_event_notify(
8708 8708                      ahci_ctlp->ahcictl_dip,
8709 8709                      &sdevice,
8710 8710                      SATA_EVNT_DEVICE_RESET);
8711 8711                  mutex_enter(&ahci_portp->ahciport_mutex);
8712 8712  
8713 8713                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8714 8714                      "Port multiplier is [Gone] at port %d ", port);
8715 8715                  AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
8716 8716                      "port %d sending event up: SATA_EVNT_DEVICE_RESET", port);
8717 8717  
8718 8718                  return (AHCI_SUCCESS);
8719 8719          }
8720 8720  
8721 8721          /* Device change: Non-PMult -> PMult */
8722 8722          if (ahci_portp->ahciport_device_type == SATA_DTYPE_PMULT) {
8723 8723  
8724 8724                  /* NOTE: The PxCMD.PMA may be cleared by HBA reset. */
8725 8725                  ahci_alloc_pmult(ahci_ctlp, ahci_portp);
8726 8726  
8727 8727                  (void) ahci_start_port(ahci_ctlp, ahci_portp, port);
8728 8728          }
8729 8729          pminfo = ahci_portp->ahciport_pmult_info;
8730 8730          ASSERT(pminfo != NULL);
8731 8731  
8732 8732          /* Device (may) change: PMult -> PMult */
8733 8733          /*
8734 8734           * First initialize port multiplier. Set state to READY and wait for
8735 8735           * probe entry point to initialize it
8736 8736           */
8737 8737          ahci_portp->ahciport_port_state = SATA_STATE_READY;
8738 8738  
8739 8739          /*
8740 8740           * It's a little complicated while target is a port multiplier. we
8741 8741           * need to COMRESET all pmports behind that PMult otherwise those
8742 8742           * sub-links between the PMult and the sub-devices will be in an
8743 8743           * inactive state (indicated by PSCR0/PxSSTS) and the following access
8744 8744           * to those sub-devices will be rejected by Link-Fatal-Error.
8745 8745           */
8746 8746          /*
8747 8747           * The PxSNTF will be set soon after the pmult is plugged. While the
8748 8748           * pmult itself is attaching, sata_hba_event_notfiy will fail. so we
8749 8749           * simply mark every sub-port as 'unknown', then ahci_probe_pmport
8750 8750           * will initialized it.
8751 8751           */
8752 8752          for (npmport = 0; npmport < pminfo->ahcipmi_num_dev_ports; npmport++)
8753 8753                  pminfo->ahcipmi_port_state[npmport] = SATA_STATE_UNKNOWN;
8754 8754  
8755 8755          /* Report reset event. */
8756 8756          ahci_portp->ahciport_reset_in_progress = 1;
8757 8757  
8758 8758          bzero((void *)&sdevice, sizeof (sata_device_t));
8759 8759          sdevice.satadev_addr.cport = cport;
8760 8760          sdevice.satadev_addr.pmport = SATA_PMULT_HOSTPORT;
8761 8761          sdevice.satadev_addr.qual = SATA_ADDR_PMULT;
8762 8762          sdevice.satadev_state = SATA_DSTATE_RESET | SATA_DSTATE_PWR_ACTIVE;
8763 8763          sata_hba_event_notify(ahci_ctlp->ahcictl_dip, &sdevice,
8764 8764              SATA_EVNT_DEVICE_RESET);
8765 8765  
8766 8766          return (rval);
8767 8767  }
8768 8768  
8769 8769  /*
8770 8770   * This routine may be called under four scenarios:
8771 8771   *      a) do the recovery from fatal error
8772 8772   *      b) or we need to timeout some commands
8773 8773   *      c) or we need to abort some commands
8774 8774   *      d) or we need reset device/port/controller
8775 8775   *
8776 8776   * In all these scenarios, we need to send any pending unfinished
8777 8777   * commands up to sata framework.
8778 8778   */
8779 8779  static void
8780 8780  ahci_mop_commands(ahci_ctl_t *ahci_ctlp,
8781 8781      ahci_port_t *ahci_portp,
8782 8782      uint32_t slot_status,
8783 8783      uint32_t failed_tags,
8784 8784      uint32_t timeout_tags,
8785 8785      uint32_t aborted_tags,
8786 8786      uint32_t reset_tags)
8787 8787  {
8788 8788          uint32_t finished_tags = 0;
8789 8789          uint32_t unfinished_tags = 0;
8790 8790          int tmp_slot;
8791 8791          sata_pkt_t *satapkt;
8792 8792          int ncq_cmd_in_progress = 0;
8793 8793          int err_retri_cmd_in_progress = 0;
8794 8794          int rdwr_pmult_cmd_in_progress = 0;
8795 8795  
8796 8796          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
8797 8797  
8798 8798          AHCIDBG(AHCIDBG_ERRS|AHCIDBG_ENTRY, ahci_ctlp,
8799 8799              "ahci_mop_commands entered: port: %d slot_status: 0x%x",
8800 8800              ahci_portp->ahciport_port_num, slot_status);
8801 8801  
8802 8802          AHCIDBG(AHCIDBG_ERRS|AHCIDBG_ENTRY, ahci_ctlp,
8803 8803              "ahci_mop_commands: failed_tags: 0x%x, "
8804 8804              "timeout_tags: 0x%x aborted_tags: 0x%x, "
8805 8805              "reset_tags: 0x%x", failed_tags,
8806 8806              timeout_tags, aborted_tags, reset_tags);
8807 8807  
8808 8808  #ifdef AHCI_DEBUG
8809 8809          if (ahci_debug_flags & AHCIDBG_ERRS) {
8810 8810                  int i;
8811 8811                  char msg_buf[200] = {0, };
8812 8812                  for (i = 0x1f; i >= 0; i--) {
8813 8813                          if (ahci_portp->ahciport_slot_pkts[i] != NULL)
8814 8814                                  msg_buf[i] = 'X';
8815 8815                          else
8816 8816                                  msg_buf[i] = '.';
8817 8817                  }
8818 8818                  msg_buf[0x20] = '\0';
8819 8819                  cmn_err(CE_NOTE, "port[%d] slots: %s",
8820 8820                      ahci_portp->ahciport_port_num, msg_buf);
8821 8821                  cmn_err(CE_NOTE, "[ERR-RT] %p [RW-PM] %p ",
8822 8822                      (void *)ahci_portp->ahciport_err_retri_pkt,
8823 8823                      (void *)ahci_portp->ahciport_rdwr_pmult_pkt);
8824 8824          }
8825 8825  #endif
8826 8826  
8827 8827          if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
8828 8828                  finished_tags = ahci_portp->ahciport_pending_tags &
8829 8829                      ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
8830 8830  
8831 8831                  unfinished_tags = slot_status &
8832 8832                      AHCI_SLOT_MASK(ahci_ctlp) &
8833 8833                      ~failed_tags &
8834 8834                      ~aborted_tags &
8835 8835                      ~reset_tags &
8836 8836                      ~timeout_tags;
8837 8837          } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
8838 8838                  ncq_cmd_in_progress = 1;
8839 8839                  finished_tags = ahci_portp->ahciport_pending_ncq_tags &
8840 8840                      ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
8841 8841  
8842 8842                  unfinished_tags = slot_status &
8843 8843                      AHCI_NCQ_SLOT_MASK(ahci_portp) &
8844 8844                      ~failed_tags &
8845 8845                      ~aborted_tags &
8846 8846                      ~reset_tags &
8847 8847                      ~timeout_tags;
8848 8848          } else if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
8849 8849  
8850 8850                  /*
8851 8851                   * When AHCI_PORT_FLAG_RQSENSE or AHCI_PORT_FLAG_RDLOGEXT is
8852 8852                   * set, it means REQUEST SENSE or READ LOG EXT command doesn't
8853 8853                   * complete successfully due to one of the following three
8854 8854                   * conditions:
8855 8855                   *
8856 8856                   *      1. Fatal error - failed_tags includes its slot
8857 8857                   *      2. Timed out - timeout_tags includes its slot
8858 8858                   *      3. Aborted when hot unplug - aborted_tags includes its
8859 8859                   *         slot
8860 8860                   *
8861 8861                   * Please note that the command is always sent down in Slot 0
8862 8862                   */
8863 8863                  err_retri_cmd_in_progress = 1;
8864 8864                  AHCIDBG(AHCIDBG_ERRS|AHCIDBG_NCQ, ahci_ctlp,
8865 8865                      "ahci_mop_commands is called for port %d while "
8866 8866                      "REQUEST SENSE or READ LOG EXT for error retrieval "
8867 8867                      "is being executed slot_status = 0x%x",
8868 8868                      ahci_portp->ahciport_port_num, slot_status);
8869 8869                  ASSERT(ahci_portp->ahciport_mop_in_progress > 1);
8870 8870                  ASSERT(slot_status == 0x1);
8871 8871          } else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
8872 8872                  rdwr_pmult_cmd_in_progress = 1;
8873 8873                  AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
8874 8874                      "ahci_mop_commands is called for port %d while "
8875 8875                      "READ/WRITE PORTMULT command is being executed",
8876 8876                      ahci_portp->ahciport_port_num);
8877 8877  
8878 8878                  ASSERT(slot_status == 0x1);
8879 8879          }
8880 8880  
8881 8881  #ifdef AHCI_DEBUG
8882 8882          AHCIDBG(AHCIDBG_ERRS|AHCIDBG_ENTRY, ahci_ctlp,
8883 8883              "ahci_mop_commands: finished_tags: 0x%x, "
8884 8884              "unfinished_tags 0x%x", finished_tags, unfinished_tags);
8885 8885  #endif
8886 8886  
8887 8887          /* Send up finished packets with SATA_PKT_COMPLETED */
8888 8888          while (finished_tags) {
8889 8889                  tmp_slot = ddi_ffs(finished_tags) - 1;
8890 8890                  if (tmp_slot == -1) {
8891 8891                          break;
8892 8892                  }
8893 8893  
8894 8894                  satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
8895 8895                  ASSERT(satapkt != NULL);
8896 8896  
8897 8897                  AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "ahci_mop_commands: "
8898 8898                      "sending up pkt 0x%p with SATA_PKT_COMPLETED",
8899 8899                      (void *)satapkt);
8900 8900  
8901 8901                  /*
8902 8902                   * Cannot fetch the return register content since the port
8903 8903                   * was restarted, so the corresponding tag will be set to
8904 8904                   * aborted tags.
8905 8905                   */
8906 8906                  if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
8907 8907                          CLEAR_BIT(finished_tags, tmp_slot);
8908 8908                          aborted_tags |= tmp_slot;
8909 8909                          continue;
8910 8910                  }
8911 8911  
8912 8912                  if (ncq_cmd_in_progress)
8913 8913                          CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
8914 8914                              tmp_slot);
8915 8915                  CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
8916 8916                  CLEAR_BIT(finished_tags, tmp_slot);
8917 8917                  ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
8918 8918  
8919 8919                  ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
8920 8920          }
8921 8921  
8922 8922          /* Send up failed packets with SATA_PKT_DEV_ERROR. */
8923 8923          while (failed_tags) {
8924 8924                  if (err_retri_cmd_in_progress) {
8925 8925                          satapkt = ahci_portp->ahciport_err_retri_pkt;
8926 8926                          ASSERT(satapkt != NULL);
8927 8927                          ASSERT(failed_tags == 0x1);
8928 8928  
8929 8929                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
8930 8930                              "sending up pkt 0x%p with SATA_PKT_DEV_ERROR",
8931 8931                              (void *)satapkt);
8932 8932                          ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_DEV_ERROR);
8933 8933                          break;
8934 8934                  }
8935 8935                  if (rdwr_pmult_cmd_in_progress) {
8936 8936                          satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
8937 8937                          ASSERT(satapkt != NULL);
8938 8938                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8939 8939                              "ahci_mop_commands: sending up "
8940 8940                              "rdwr pmult pkt 0x%p with SATA_PKT_DEV_ERROR",
8941 8941                              (void *)satapkt);
8942 8942                          ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_DEV_ERROR);
8943 8943                          break;
8944 8944                  }
8945 8945  
8946 8946                  tmp_slot = ddi_ffs(failed_tags) - 1;
8947 8947                  if (tmp_slot == -1) {
8948 8948                          break;
8949 8949                  }
8950 8950  
8951 8951                  satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
8952 8952                  ASSERT(satapkt != NULL);
8953 8953  
8954 8954                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
8955 8955                      "sending up pkt 0x%p with SATA_PKT_DEV_ERROR",
8956 8956                      (void *)satapkt);
8957 8957  
8958 8958                  if (ncq_cmd_in_progress)
8959 8959                          CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
8960 8960                              tmp_slot);
8961 8961                  CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
8962 8962                  CLEAR_BIT(failed_tags, tmp_slot);
8963 8963                  ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
8964 8964  
8965 8965                  ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_DEV_ERROR);
8966 8966          }
8967 8967  
8968 8968          /* Send up timeout packets with SATA_PKT_TIMEOUT. */
8969 8969          while (timeout_tags) {
8970 8970                  if (err_retri_cmd_in_progress) {
8971 8971                          satapkt = ahci_portp->ahciport_err_retri_pkt;
8972 8972                          ASSERT(satapkt != NULL);
8973 8973                          ASSERT(timeout_tags == 0x1);
8974 8974  
8975 8975                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
8976 8976                              "sending up pkt 0x%p with SATA_PKT_TIMEOUT",
8977 8977                              (void *)satapkt);
8978 8978                          ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_TIMEOUT);
8979 8979                          break;
8980 8980                  }
8981 8981                  if (rdwr_pmult_cmd_in_progress) {
8982 8982                          satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
8983 8983                          ASSERT(satapkt != NULL);
8984 8984                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8985 8985                              "ahci_mop_commands: sending up "
8986 8986                              "rdwr pmult pkt 0x%p with SATA_PKT_TIMEOUT",
8987 8987                              (void *)satapkt);
8988 8988                          ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_TIMEOUT);
8989 8989                          break;
8990 8990                  }
8991 8991  
8992 8992                  tmp_slot = ddi_ffs(timeout_tags) - 1;
8993 8993                  if (tmp_slot == -1) {
8994 8994                          break;
8995 8995                  }
8996 8996  
8997 8997                  satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
8998 8998                  ASSERT(satapkt != NULL);
8999 8999  
9000 9000                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
9001 9001                      "sending up pkt 0x%p with SATA_PKT_TIMEOUT",
9002 9002                      (void *)satapkt);
9003 9003  
9004 9004                  if (ncq_cmd_in_progress)
9005 9005                          CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
9006 9006                              tmp_slot);
9007 9007                  CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
9008 9008                  CLEAR_BIT(timeout_tags, tmp_slot);
9009 9009                  ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
9010 9010  
9011 9011                  ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_TIMEOUT);
9012 9012          }
9013 9013  
9014 9014          /* Send up aborted packets with SATA_PKT_ABORTED */
9015 9015          while (aborted_tags) {
9016 9016                  if (err_retri_cmd_in_progress) {
9017 9017                          satapkt = ahci_portp->ahciport_err_retri_pkt;
9018 9018                          ASSERT(satapkt != NULL);
9019 9019                          ASSERT(aborted_tags == 0x1);
9020 9020  
9021 9021                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
9022 9022                              "sending up pkt 0x%p with SATA_PKT_ABORTED",
9023 9023                              (void *)satapkt);
9024 9024                          ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_ABORTED);
9025 9025                          break;
9026 9026                  }
9027 9027                  if (rdwr_pmult_cmd_in_progress) {
9028 9028                          satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
9029 9029                          ASSERT(satapkt != NULL);
9030 9030                          ASSERT(aborted_tags == 0x1);
9031 9031                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9032 9032                              "ahci_mop_commands: sending up "
9033 9033                              "rdwr pmult pkt 0x%p with SATA_PKT_ABORTED",
9034 9034                              (void *)satapkt);
9035 9035                          ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_ABORTED);
9036 9036                          break;
9037 9037                  }
9038 9038  
9039 9039                  tmp_slot = ddi_ffs(aborted_tags) - 1;
9040 9040                  if (tmp_slot == -1) {
9041 9041                          break;
9042 9042                  }
9043 9043  
9044 9044                  satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9045 9045                  ASSERT(satapkt != NULL);
9046 9046  
9047 9047                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
9048 9048                      "sending up pkt 0x%p with SATA_PKT_ABORTED",
9049 9049                      (void *)satapkt);
9050 9050  
9051 9051                  if (ncq_cmd_in_progress)
9052 9052                          CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
9053 9053                              tmp_slot);
9054 9054                  CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
9055 9055                  CLEAR_BIT(aborted_tags, tmp_slot);
9056 9056                  ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
9057 9057  
9058 9058                  ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_ABORTED);
9059 9059          }
9060 9060  
9061 9061          /* Send up reset packets with SATA_PKT_RESET. */
9062 9062          while (reset_tags) {
9063 9063                  if (rdwr_pmult_cmd_in_progress) {
9064 9064                          satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
9065 9065                          ASSERT(satapkt != NULL);
9066 9066                          ASSERT(aborted_tags == 0x1);
9067 9067                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9068 9068                              "ahci_mop_commands: sending up "
9069 9069                              "rdwr pmult pkt 0x%p with SATA_PKT_RESET",
9070 9070                              (void *)satapkt);
9071 9071                          ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_RESET);
9072 9072                          break;
9073 9073                  }
9074 9074  
9075 9075                  tmp_slot = ddi_ffs(reset_tags) - 1;
9076 9076                  if (tmp_slot == -1) {
9077 9077                          break;
9078 9078                  }
9079 9079  
9080 9080                  satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9081 9081                  ASSERT(satapkt != NULL);
9082 9082  
9083 9083                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
9084 9084                      "sending up pkt 0x%p with SATA_PKT_RESET",
9085 9085                      (void *)satapkt);
9086 9086  
9087 9087                  if (ncq_cmd_in_progress)
9088 9088                          CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
9089 9089                              tmp_slot);
9090 9090                  CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
9091 9091                  CLEAR_BIT(reset_tags, tmp_slot);
9092 9092                  ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
9093 9093  
9094 9094                  ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_RESET);
9095 9095          }
9096 9096  
9097 9097          /* Send up unfinished packets with SATA_PKT_RESET */
9098 9098          while (unfinished_tags) {
9099 9099                  tmp_slot = ddi_ffs(unfinished_tags) - 1;
9100 9100                  if (tmp_slot == -1) {
9101 9101                          break;
9102 9102                  }
9103 9103  
9104 9104                  satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9105 9105                  ASSERT(satapkt != NULL);
9106 9106  
9107 9107                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
9108 9108                      "sending up pkt 0x%p with SATA_PKT_RESET",
9109 9109                      (void *)satapkt);
9110 9110  
9111 9111                  if (ncq_cmd_in_progress)
9112 9112                          CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
9113 9113                              tmp_slot);
9114 9114                  CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
9115 9115                  CLEAR_BIT(unfinished_tags, tmp_slot);
9116 9116                  ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
9117 9117  
9118 9118                  ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_RESET);
9119 9119          }
9120 9120  
9121 9121          ahci_portp->ahciport_mop_in_progress--;
9122 9122          ASSERT(ahci_portp->ahciport_mop_in_progress >= 0);
9123 9123  
9124 9124          if (ahci_portp->ahciport_mop_in_progress == 0)
9125 9125                  ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_MOPPING;
9126 9126  
9127 9127          ahci_flush_doneq(ahci_portp);
9128 9128  }
9129 9129  
9130 9130  /*
9131 9131   * This routine is going to first request a READ LOG EXT sata pkt from sata
9132 9132   * module, and then deliver it to the HBA to get the ncq failure context.
9133 9133   * The return value is the exactly failed tags.
9134 9134   */
9135 9135  static uint32_t
9136 9136  ahci_get_rdlogext_data(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
9137 9137      uint8_t port)
9138 9138  {
9139 9139          sata_device_t   sdevice;
9140 9140          sata_pkt_t      *rdlog_spkt, *spkt;
9141 9141          ddi_dma_handle_t buf_dma_handle;
9142 9142          ahci_addr_t     addr;
9143 9143          int             loop_count;
9144 9144          int             rval;
9145 9145          int             failed_slot;
9146 9146          uint32_t        failed_tags = 0;
9147 9147          struct sata_ncq_error_recovery_page *ncq_err_page;
9148 9148  
9149 9149          AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_NCQ, ahci_ctlp,
9150 9150              "ahci_get_rdlogext_data enter: port %d", port);
9151 9151  
9152 9152          /* Prepare the sdevice data */
9153 9153          bzero((void *)&sdevice, sizeof (sata_device_t));
9154 9154          sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
9155 9155  
9156 9156          sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
9157 9157          sdevice.satadev_addr.pmport = 0;
9158 9158  
9159 9159          /* Translate sata_device.satadev_addr -> ahci_addr */
9160 9160          ahci_get_ahci_addr(ahci_ctlp, &sdevice, &addr);
9161 9161  
9162 9162          /*
9163 9163           * Call the sata hba interface to get a rdlog spkt
9164 9164           */
9165 9165          loop_count = 0;
9166 9166  loop:
9167 9167          rdlog_spkt = sata_get_error_retrieval_pkt(ahci_ctlp->ahcictl_dip,
9168 9168              &sdevice, SATA_ERR_RETR_PKT_TYPE_NCQ);
9169 9169          if (rdlog_spkt == NULL) {
9170 9170                  if (loop_count++ < AHCI_POLLRATE_GET_SPKT) {
9171 9171                          /* Sleep for a while */
9172 9172                          drv_usecwait(AHCI_10MS_USECS);
9173 9173                          goto loop;
9174 9174                  }
9175 9175                  /* Timed out after 1s */
9176 9176                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9177 9177                      "failed to get rdlog spkt for port %d", port);
9178 9178                  return (failed_tags);
9179 9179          }
9180 9180  
9181 9181          ASSERT(rdlog_spkt->satapkt_op_mode & SATA_OPMODE_SYNCH);
9182 9182  
9183 9183          /*
9184 9184           * This flag is used to handle the specific error recovery when the
9185 9185           * READ LOG EXT command gets a failure (fatal error or time-out).
9186 9186           */
9187 9187          ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_RDLOGEXT;
9188 9188  
9189 9189          /*
9190 9190           * This start is not supposed to fail because after port is restarted,
9191 9191           * the whole command list is empty.
9192 9192           */
9193 9193          ahci_portp->ahciport_err_retri_pkt = rdlog_spkt;
9194 9194          (void) ahci_do_sync_start(ahci_ctlp, ahci_portp, &addr, rdlog_spkt);
9195 9195          ahci_portp->ahciport_err_retri_pkt = NULL;
9196 9196  
9197 9197          /* Remove the flag after READ LOG EXT command is completed */
9198 9198          ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_RDLOGEXT;
9199 9199  
9200 9200          if (rdlog_spkt->satapkt_reason == SATA_PKT_COMPLETED) {
9201 9201                  /* Update the request log data */
9202 9202                  buf_dma_handle = *(ddi_dma_handle_t *)
9203 9203                      (rdlog_spkt->satapkt_cmd.satacmd_err_ret_buf_handle);
9204 9204                  rval = ddi_dma_sync(buf_dma_handle, 0, 0,
9205 9205                      DDI_DMA_SYNC_FORKERNEL);
9206 9206                  if (rval == DDI_SUCCESS) {
9207 9207                          ncq_err_page =
9208 9208                              (struct sata_ncq_error_recovery_page *)rdlog_spkt->
9209 9209                              satapkt_cmd.satacmd_bp->b_un.b_addr;
9210 9210  
9211 9211                          /* Get the failed tag */
9212 9212                          failed_slot = ncq_err_page->ncq_tag;
9213 9213                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9214 9214                              "ahci_get_rdlogext_data: port %d "
9215 9215                              "failed slot %d", port, failed_slot);
9216 9216                          if (failed_slot & NQ) {
9217 9217                                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9218 9218                                      "the failed slot is not a valid tag", NULL);
9219 9219                                  goto out;
9220 9220                          }
9221 9221  
9222 9222                          failed_slot &= NCQ_TAG_MASK;
9223 9223                          spkt = ahci_portp->ahciport_slot_pkts[failed_slot];
9224 9224                          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9225 9225                              "ahci_get_rdlogext_data: failed spkt 0x%p",
9226 9226                              (void *)spkt);
9227 9227                          if (spkt == NULL) {
9228 9228                                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9229 9229                                      "the failed slot spkt is NULL", NULL);
9230 9230                                  goto out;
9231 9231                          }
9232 9232  
9233 9233                          failed_tags = 0x1 << failed_slot;
9234 9234  
9235 9235                          /* Fill out the error context */
9236 9236                          ahci_copy_ncq_err_page(&spkt->satapkt_cmd,
9237 9237                              ncq_err_page);
9238 9238                          ahci_update_sata_registers(ahci_ctlp, port,
9239 9239                              &spkt->satapkt_device);
9240 9240                  }
9241 9241          }
9242 9242  out:
9243 9243          sata_free_error_retrieval_pkt(rdlog_spkt);
9244 9244  
9245 9245          return (failed_tags);
9246 9246  }
9247 9247  
9248 9248  /*
9249 9249   * This routine is going to first request a REQUEST SENSE sata pkt from sata
9250 9250   * module, and then deliver it to the HBA to get the sense data and copy
9251 9251   * the sense data back to the orignal failed sata pkt, and free the REQUEST
9252 9252   * SENSE sata pkt later.
9253 9253   */
9254 9254  static void
9255 9255  ahci_get_rqsense_data(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
9256 9256      uint8_t port, sata_pkt_t *spkt)
9257 9257  {
9258 9258          sata_device_t   sdevice;
9259 9259          sata_pkt_t      *rs_spkt;
9260 9260          sata_cmd_t      *sata_cmd;
9261 9261          ddi_dma_handle_t buf_dma_handle;
9262 9262          ahci_addr_t     addr;
9263 9263          int             loop_count;
9264 9264  #if AHCI_DEBUG
9265 9265          struct scsi_extended_sense *rqsense;
9266 9266  #endif
9267 9267  
9268 9268          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
9269 9269              "ahci_get_rqsense_data enter: port %d", port);
9270 9270  
9271 9271          /* Prepare the sdevice data */
9272 9272          bzero((void *)&sdevice, sizeof (sata_device_t));
9273 9273          sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
9274 9274  
9275 9275          sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
9276 9276          sdevice.satadev_addr.pmport = 0;
9277 9277  
9278 9278          /* Translate sata_device.satadev_addr -> ahci_addr */
9279 9279          ahci_get_ahci_addr(ahci_ctlp, &sdevice, &addr);
9280 9280  
9281 9281          sata_cmd = &spkt->satapkt_cmd;
9282 9282  
9283 9283          /*
9284 9284           * Call the sata hba interface to get a rs spkt
9285 9285           */
9286 9286          loop_count = 0;
9287 9287  loop:
9288 9288          rs_spkt = sata_get_error_retrieval_pkt(ahci_ctlp->ahcictl_dip,
9289 9289              &sdevice, SATA_ERR_RETR_PKT_TYPE_ATAPI);
9290 9290          if (rs_spkt == NULL) {
9291 9291                  if (loop_count++ < AHCI_POLLRATE_GET_SPKT) {
9292 9292                          /* Sleep for a while */
9293 9293                          drv_usecwait(AHCI_10MS_USECS);
9294 9294                          goto loop;
9295 9295  
9296 9296                  }
9297 9297                  /* Timed out after 1s */
9298 9298                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9299 9299                      "failed to get rs spkt for port %d", port);
9300 9300                  return;
9301 9301          }
9302 9302  
9303 9303          ASSERT(rs_spkt->satapkt_op_mode & SATA_OPMODE_SYNCH);
9304 9304  
9305 9305          /*
9306 9306           * This flag is used to handle the specific error recovery when the
9307 9307           * REQUEST SENSE command gets a faiure (fatal error or time-out).
9308 9308           */
9309 9309          ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_RQSENSE;
9310 9310  
9311 9311          /*
9312 9312           * This start is not supposed to fail because after port is restarted,
9313 9313           * the whole command list is empty.
9314 9314           */
9315 9315          ahci_portp->ahciport_err_retri_pkt = rs_spkt;
9316 9316          (void) ahci_do_sync_start(ahci_ctlp, ahci_portp, &addr, rs_spkt);
9317 9317          ahci_portp->ahciport_err_retri_pkt = NULL;
9318 9318  
9319 9319          /* Remove the flag after REQUEST SENSE command is completed */
9320 9320          ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_RQSENSE;
9321 9321  
9322 9322          if (rs_spkt->satapkt_reason == SATA_PKT_COMPLETED) {
9323 9323                  /* Update the request sense data */
9324 9324                  buf_dma_handle = *(ddi_dma_handle_t *)
9325 9325                      (rs_spkt->satapkt_cmd.satacmd_err_ret_buf_handle);
9326 9326                  (void) ddi_dma_sync(buf_dma_handle, 0, 0,
9327 9327                      DDI_DMA_SYNC_FORKERNEL);
9328 9328                  /* Copy the request sense data */
9329 9329                  bcopy(rs_spkt->
9330 9330                      satapkt_cmd.satacmd_bp->b_un.b_addr,
9331 9331                      &sata_cmd->satacmd_rqsense,
9332 9332                      SATA_ATAPI_MIN_RQSENSE_LEN);
9333 9333  #if AHCI_DEBUG
9334 9334                  rqsense = (struct scsi_extended_sense *)
9335 9335                      sata_cmd->satacmd_rqsense;
9336 9336  
9337 9337                  /* Dump the sense data */
9338 9338                  AHCIDBG(AHCIDBG_SENSEDATA, ahci_ctlp, "\n", NULL);
9339 9339                  AHCIDBG(AHCIDBG_SENSEDATA, ahci_ctlp,
9340 9340                      "Sense data for satapkt %p ATAPI cmd 0x%x",
9341 9341                      spkt, sata_cmd->satacmd_acdb[0]);
9342 9342                  AHCIDBG(AHCIDBG_SENSEDATA, ahci_ctlp,
9343 9343                      "  es_code 0x%x es_class 0x%x "
9344 9344                      "es_key 0x%x es_add_code 0x%x "
9345 9345                      "es_qual_code 0x%x",
9346 9346                      rqsense->es_code, rqsense->es_class,
9347 9347                      rqsense->es_key, rqsense->es_add_code,
9348 9348                      rqsense->es_qual_code);
9349 9349  #endif
9350 9350          }
9351 9351  
9352 9352          sata_free_error_retrieval_pkt(rs_spkt);
9353 9353  }
9354 9354  
9355 9355  /*
9356 9356   * Fatal errors will cause the HBA to enter the ERR: Fatal state. To recover,
9357 9357   * the port must be restarted. When the HBA detects thus error, it may try
9358 9358   * to abort a transfer. And if the transfer was aborted, the device is
9359 9359   * expected to send a D2H Register FIS with PxTFD.STS.ERR set to '1' and both
9360 9360   * PxTFD.STS.BSY and PxTFD.STS.DRQ cleared to '0'. Then system software knows
9361 9361   * that the device is in a stable status and transfers may be restarted without
9362 9362   * issuing a COMRESET to the device. If PxTFD.STS.BSY or PxTFD.STS.DRQ is set,
9363 9363   * then the software will send the COMRESET to do the port reset.
9364 9364   *
9365 9365   * Software should perform the appropriate error recovery actions based on
9366 9366   * whether non-queued commands were being issued or natived command queuing
9367 9367   * commands were being issued.
9368 9368   *
9369 9369   * And software will complete the command that had the error with error mark
9370 9370   * to higher level software.
9371 9371   *
9372 9372   * Fatal errors include the following:
9373 9373   *      PxIS.IFS - Interface Fatal Error Status
9374 9374   *      PxIS.HBDS - Host Bus Data Error Status
9375 9375   *      PxIS.HBFS - Host Bus Fatal Error Status
9376 9376   *      PxIS.TFES - Task File Error Status
9377 9377   */
9378 9378  static void
9379 9379  ahci_fatal_error_recovery_handler(ahci_ctl_t *ahci_ctlp,
9380 9380      ahci_port_t *ahci_portp, ahci_addr_t *addrp, uint32_t intr_status)
9381 9381  {
9382 9382          uint32_t        port_cmd_status;
9383 9383          uint32_t        slot_status = 0;
9384 9384          uint32_t        failed_tags = 0;
9385 9385          int             failed_slot;
9386 9386          int             reset_flag = 0, flag = 0;
9387 9387          ahci_fis_d2h_register_t *ahci_rcvd_fisp;
9388 9388          sata_cmd_t      *sata_cmd = NULL;
9389 9389          sata_pkt_t      *spkt = NULL;
9390 9390  #if AHCI_DEBUG
9391 9391          ahci_cmd_header_t *cmd_header;
9392 9392  #endif
9393 9393          uint8_t         port = addrp->aa_port;
9394 9394          int             instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
9395 9395          int             rval;
9396 9396  
9397 9397          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
9398 9398  
9399 9399          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
9400 9400              "ahci_fatal_error_recovery_handler enter: port %d", port);
9401 9401  
9402 9402          /* Port multiplier error */
9403 9403          if (ahci_portp->ahciport_device_type == SATA_DTYPE_PMULT) {
9404 9404                  /* FBS code is neither completed nor tested. */
9405 9405                  ahci_pmult_error_recovery_handler(ahci_ctlp, ahci_portp,
9406 9406                      port, intr_status);
9407 9407  
9408 9408                  /* Force a port reset */
9409 9409                  flag = AHCI_PORT_RESET;
9410 9410          }
9411 9411  
9412 9412          if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp) ||
9413 9413              ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9414 9414  
9415 9415                  /* Read PxCI to see which commands are still outstanding */
9416 9416                  slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9417 9417                      (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
9418 9418  
9419 9419                  /*
9420 9420                   * Read PxCMD.CCS to determine the slot that the HBA
9421 9421                   * was processing when the error occurred.
9422 9422                   */
9423 9423                  port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9424 9424                      (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
9425 9425                  failed_slot = (port_cmd_status & AHCI_CMD_STATUS_CCS) >>
9426 9426                      AHCI_CMD_STATUS_CCS_SHIFT;
9427 9427  
9428 9428                  if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9429 9429                          spkt = ahci_portp->ahciport_err_retri_pkt;
9430 9430                          ASSERT(spkt != NULL);
9431 9431                  } else {
9432 9432                          spkt = ahci_portp->ahciport_slot_pkts[failed_slot];
9433 9433                          if (spkt == NULL) {
9434 9434                                  /* May happen when interface errors occur? */
9435 9435                                  goto next;
9436 9436                          }
9437 9437                  }
9438 9438  
9439 9439  #if AHCI_DEBUG
9440 9440                  /*
9441 9441                   * Debugging purpose...
9442 9442                   */
9443 9443                  if (ahci_portp->ahciport_prd_bytecounts[failed_slot]) {
9444 9444                          cmd_header =
9445 9445                              &ahci_portp->ahciport_cmd_list[failed_slot];
9446 9446                          AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
9447 9447                              "ahci_fatal_error_recovery_handler: port %d, "
9448 9448                              "PRD Byte Count = 0x%x, "
9449 9449                              "ahciport_prd_bytecounts = 0x%x", port,
9450 9450                              cmd_header->ahcich_prd_byte_count,
9451 9451                              ahci_portp->ahciport_prd_bytecounts[failed_slot]);
9452 9452                  }
9453 9453  #endif
9454 9454  
9455 9455                  sata_cmd = &spkt->satapkt_cmd;
9456 9456  
9457 9457                  /* Fill out the status and error registers for PxIS.TFES */
9458 9458                  if (intr_status & AHCI_INTR_STATUS_TFES) {
9459 9459                          ahci_rcvd_fisp = &(ahci_portp->ahciport_rcvd_fis->
9460 9460                              ahcirf_d2h_register_fis);
9461 9461  
9462 9462                          /* Copy the error context back to the sata_cmd */
9463 9463                          ahci_copy_err_cnxt(sata_cmd, ahci_rcvd_fisp);
9464 9464                  }
9465 9465  
9466 9466                  /* The failed command must be one of the outstanding commands */
9467 9467                  failed_tags = 0x1 << failed_slot;
9468 9468                  ASSERT(failed_tags & slot_status);
9469 9469  
9470 9470                  /* Update the sata registers, especially PxSERR register */
9471 9471                  ahci_update_sata_registers(ahci_ctlp, port,
9472 9472                      &spkt->satapkt_device);
9473 9473  
9474 9474          } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9475 9475                  /* Read PxSACT to see which commands are still outstanding */
9476 9476                  slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9477 9477                      (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
9478 9478          }
9479 9479  next:
9480 9480  
9481 9481  #if AHCI_DEBUG
9482 9482          /*
9483 9483           * When AHCI_PORT_FLAG_RQSENSE or AHCI_PORT_FLAG_RDLOGEXT flag is
9484 9484           * set, it means a fatal error happened after REQUEST SENSE command
9485 9485           * or READ LOG EXT command is delivered to the HBA during the error
9486 9486           * recovery process. At this time, the only outstanding command is
9487 9487           * supposed to be REQUEST SENSE command or READ LOG EXT command.
9488 9488           */
9489 9489          if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9490 9490                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9491 9491                      "ahci_fatal_error_recovery_handler: port %d REQUEST SENSE "
9492 9492                      "command or READ LOG EXT command for error data retrieval "
9493 9493                      "failed", port);
9494 9494                  ASSERT(slot_status == 0x1);
9495 9495                  ASSERT(failed_slot == 0);
9496 9496                  ASSERT(spkt->satapkt_cmd.satacmd_acdb[0] ==
9497 9497                      SCMD_REQUEST_SENSE ||
9498 9498                      spkt->satapkt_cmd.satacmd_cmd_reg ==
9499 9499                      SATAC_READ_LOG_EXT);
9500 9500          }
9501 9501  #endif
9502 9502  
9503 9503          ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
9504 9504          ahci_portp->ahciport_mop_in_progress++;
9505 9505  
9506 9506          rval = ahci_restart_port_wait_till_ready(ahci_ctlp, ahci_portp,
9507 9507              port, flag, &reset_flag);
9508 9508  
9509 9509          if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_ERRPRINT) {
9510 9510                  ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_ERRPRINT;
9511 9511                  if (rval == AHCI_SUCCESS)
9512 9512                          cmn_err(CE_WARN, "!ahci%d: error recovery for port %d "
9513 9513                              "succeed", instance, port);
9514 9514                  else
9515 9515                          cmn_err(CE_WARN, "!ahci%d: error recovery for port %d "
9516 9516                              "failed", instance, port);
9517 9517          }
9518 9518  
9519 9519          /*
9520 9520           * Won't retrieve error information:
9521 9521           * 1. Port reset was involved to recover
9522 9522           * 2. Device is gone
9523 9523           * 3. IDENTIFY DEVICE command sent to ATAPI device
9524 9524           * 4. REQUEST SENSE or READ LOG EXT command during error recovery
9525 9525           */
9526 9526          if (reset_flag ||
9527 9527              ahci_portp->ahciport_device_type == SATA_DTYPE_NONE ||
9528 9528              spkt && spkt->satapkt_cmd.satacmd_cmd_reg == SATAC_ID_DEVICE ||
9529 9529              ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
9530 9530                  goto out;
9531 9531  
9532 9532          /*
9533 9533           * Deliver READ LOG EXT to gather information about the error when
9534 9534           * a COMRESET has not been performed as part of the error recovery
9535 9535           * during NCQ command processing.
9536 9536           */
9537 9537          if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9538 9538                  failed_tags = ahci_get_rdlogext_data(ahci_ctlp,
9539 9539                      ahci_portp, port);
9540 9540                  goto out;
9541 9541          }
9542 9542  
9543 9543          /*
9544 9544           * Deliver REQUEST SENSE for ATAPI command to gather information about
9545 9545           * the error when a COMRESET has not been performed as part of the
9546 9546           * error recovery.
9547 9547           */
9548 9548          if (spkt && ahci_portp->ahciport_device_type == SATA_DTYPE_ATAPI)
9549 9549                  ahci_get_rqsense_data(ahci_ctlp, ahci_portp, port, spkt);
9550 9550  out:
9551 9551          AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9552 9552              "ahci_fatal_error_recovery_handler: port %d fatal error "
9553 9553              "occurred slot_status = 0x%x, pending_tags = 0x%x, "
9554 9554              "pending_ncq_tags = 0x%x failed_tags = 0x%x",
9555 9555              port, slot_status, ahci_portp->ahciport_pending_tags,
9556 9556              ahci_portp->ahciport_pending_ncq_tags, failed_tags);
9557 9557  
9558 9558          ahci_mop_commands(ahci_ctlp,
9559 9559              ahci_portp,
9560 9560              slot_status,
9561 9561              failed_tags, /* failed tags */
9562 9562              0, /* timeout tags */
9563 9563              0, /* aborted tags */
9564 9564              0); /* reset tags */
9565 9565  }
9566 9566  
9567 9567  /*
9568 9568   * Used to recovery a PMULT pmport fatal error under FIS-based switching.
9569 9569   *      1. device specific.PxFBS.SDE=1
9570 9570   *      2. Non Device specific.
9571 9571   * Nothing will be done when Command-based switching is employed.
9572 9572   *
9573 9573   * Currently code is neither completed nor tested.
9574 9574   */
9575 9575  static void
9576 9576  ahci_pmult_error_recovery_handler(ahci_ctl_t *ahci_ctlp,
9577 9577      ahci_port_t *ahci_portp, uint8_t port, uint32_t intr_status)
9578 9578  {
9579 9579  #ifndef __lock_lint
9580 9580          _NOTE(ARGUNUSED(intr_status))
9581 9581  #endif
9582 9582          uint32_t        port_fbs_ctrl;
9583 9583          int loop_count = 0;
9584 9584          ahci_addr_t     addr;
9585 9585  
9586 9586          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
9587 9587  
9588 9588          /* Nothing will be done under Command-based switching. */
9589 9589          if (!(ahci_ctlp->ahcictl_cap & AHCI_CAP_PMULT_FBSS))
9590 9590                  return;
9591 9591  
9592 9592          port_fbs_ctrl = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9593 9593              (uint32_t *)AHCI_PORT_PxFBS(ahci_ctlp, port));
9594 9594  
9595 9595          if (!(port_fbs_ctrl & AHCI_FBS_EN))
9596 9596                  /* FBS is not enabled. */
9597 9597                  return;
9598 9598  
9599 9599          /* Problem's getting complicated now. */
9600 9600          /*
9601 9601           * If FIS-based switching is used, we need to check
9602 9602           * the PxFBS to see the error type.
9603 9603           */
9604 9604          port_fbs_ctrl = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9605 9605              (uint32_t *)AHCI_PORT_PxFBS(ahci_ctlp, port));
9606 9606  
9607 9607          /* Refer to spec(v1.2) 9.3.6.1 */
9608 9608          if (port_fbs_ctrl & AHCI_FBS_SDE) {
9609 9609                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9610 9610                      "A Device Sepcific Error: port %d", port);
9611 9611                  /*
9612 9612                   * Controller has paused commands for all other
9613 9613                   * sub-devices until PxFBS.DEC is set.
9614 9614                   */
9615 9615                  ahci_reject_all_abort_pkts(ahci_ctlp,
9616 9616                      ahci_portp, 0);
9617 9617  
9618 9618                  ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
9619 9619                      (uint32_t *)AHCI_PORT_PxFBS(ahci_ctlp, port),
9620 9620                      port_fbs_ctrl | AHCI_FBS_DEC);
9621 9621  
9622 9622                  /*
9623 9623                   * Wait controller clear PxFBS.DEC,
9624 9624                   * then we can continue.
9625 9625                   */
9626 9626                  loop_count = 0;
9627 9627                  do {
9628 9628                          port_fbs_ctrl = ddi_get32(ahci_ctlp->
9629 9629                              ahcictl_ahci_acc_handle, (uint32_t *)
9630 9630                              AHCI_PORT_PxFBS(ahci_ctlp, port));
9631 9631  
9632 9632                          if (loop_count++ > 1000)
9633 9633                                  /*
9634 9634                                   * Esclate the error. Follow
9635 9635                                   * non-device specific error
9636 9636                                   * procedure.
9637 9637                                   */
9638 9638                                  return;
9639 9639  
9640 9640                          drv_usecwait(AHCI_100US_USECS);
9641 9641                  } while (port_fbs_ctrl & AHCI_FBS_DEC);
9642 9642  
9643 9643                  /*
9644 9644                   * Issue a software reset to ensure drive is in
9645 9645                   * a known state.
9646 9646                   */
9647 9647                  (void) ahci_software_reset(ahci_ctlp,
9648 9648                      ahci_portp, &addr);
9649 9649  
9650 9650          } else {
9651 9651  
9652 9652                  /* Process Non-Device Specific Error. */
9653 9653                  /* This will be handled later on. */
9654 9654                  cmn_err(CE_NOTE, "!FBS is not supported now.");
9655 9655          }
9656 9656  }
9657 9657  /*
9658 9658   * Handle events - fatal error recovery
9659 9659   */
9660 9660  static void
9661 9661  ahci_events_handler(void *args)
9662 9662  {
9663 9663          ahci_event_arg_t *ahci_event_arg;
9664 9664          ahci_ctl_t *ahci_ctlp;
9665 9665          ahci_port_t *ahci_portp;
9666 9666          ahci_addr_t *addrp;
9667 9667          uint32_t event;
9668 9668          int instance;
9669 9669  
9670 9670          ahci_event_arg = (ahci_event_arg_t *)args;
9671 9671  
9672 9672          ahci_ctlp = ahci_event_arg->ahciea_ctlp;
9673 9673          ahci_portp = ahci_event_arg->ahciea_portp;
9674 9674          addrp = ahci_event_arg->ahciea_addrp;
9675 9675          event = ahci_event_arg->ahciea_event;
9676 9676          instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
9677 9677  
9678 9678          AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
9679 9679              "ahci_events_handler enter: port %d intr_status = 0x%x",
9680 9680              ahci_portp->ahciport_port_num, event);
9681 9681  
9682 9682          mutex_enter(&ahci_portp->ahciport_mutex);
9683 9683  
9684 9684          /*
9685 9685           * ahci_intr_phyrdy_change() may have rendered it to
9686 9686           * SATA_DTYPE_NONE.
9687 9687           */
9688 9688          if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
9689 9689                  AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
9690 9690                      "ahci_events_handler: port %d no device attached, "
9691 9691                      "and just return without doing anything",
9692 9692                      ahci_portp->ahciport_port_num);
9693 9693  
9694 9694                  if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_ERRPRINT) {
9695 9695                          ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_ERRPRINT;
9696 9696                          cmn_err(CE_WARN, "!ahci%d: error recovery for port %d "
9697 9697                              "succeed", instance, ahci_portp->ahciport_port_num);
9698 9698                  }
9699 9699  
9700 9700                  goto out;
9701 9701          }
9702 9702  
9703 9703          if (event & (AHCI_INTR_STATUS_IFS |
9704 9704              AHCI_INTR_STATUS_HBDS |
9705 9705              AHCI_INTR_STATUS_HBFS |
9706 9706              AHCI_INTR_STATUS_TFES))
9707 9707                  ahci_fatal_error_recovery_handler(ahci_ctlp, ahci_portp,
9708 9708                      addrp, event);
9709 9709  
9710 9710  out:
9711 9711          mutex_exit(&ahci_portp->ahciport_mutex);
9712 9712  }
9713 9713  
9714 9714  /*
9715 9715   * ahci_watchdog_handler() and ahci_do_sync_start will call us if they
9716 9716   * detect there are some commands which are timed out.
9717 9717   */
9718 9718  static void
9719 9719  ahci_timeout_pkts(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
9720 9720      uint8_t port, uint32_t tmp_timeout_tags)
9721 9721  {
9722 9722          uint32_t slot_status = 0;
9723 9723          uint32_t finished_tags = 0;
9724 9724          uint32_t timeout_tags = 0;
9725 9725  
9726 9726          AHCIDBG(AHCIDBG_TIMEOUT|AHCIDBG_ENTRY, ahci_ctlp,
9727 9727              "ahci_timeout_pkts enter: port %d", port);
9728 9728  
9729 9729          mutex_enter(&ahci_portp->ahciport_mutex);
9730 9730  
9731 9731          if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp) ||
9732 9732              RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp) ||
9733 9733              ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9734 9734                  /* Read PxCI to see which commands are still outstanding */
9735 9735                  slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9736 9736                      (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
9737 9737          } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9738 9738                  /* Read PxSACT to see which commands are still outstanding */
9739 9739                  slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9740 9740                      (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
9741 9741          }
9742 9742  
9743 9743  #if AHCI_DEBUG
9744 9744          /*
9745 9745           * When AHCI_PORT_FLAG_RQSENSE or AHCI_PORT_FLAG_RDLOGEXT flag is
9746 9746           * set, it means a fatal error happened after REQUEST SENSE command
9747 9747           * or READ LOG EXT command is delivered to the HBA during the error
9748 9748           * recovery process. At this time, the only outstanding command is
9749 9749           * supposed to be REQUEST SENSE command or READ LOG EXT command.
9750 9750           */
9751 9751          if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9752 9752                  AHCIDBG(AHCIDBG_ERRS|AHCIDBG_TIMEOUT, ahci_ctlp,
9753 9753                      "ahci_timeout_pkts called while REQUEST SENSE "
9754 9754                      "command or READ LOG EXT command for error recovery "
9755 9755                      "timed out timeout_tags = 0x%x, slot_status = 0x%x, "
9756 9756                      "pending_tags = 0x%x, pending_ncq_tags = 0x%x",
9757 9757                      tmp_timeout_tags, slot_status,
9758 9758                      ahci_portp->ahciport_pending_tags,
9759 9759                      ahci_portp->ahciport_pending_ncq_tags);
9760 9760                  ASSERT(slot_status == 0x1);
9761 9761          } else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
9762 9762                  AHCIDBG(AHCIDBG_ERRS|AHCIDBG_TIMEOUT, ahci_ctlp,
9763 9763                      "ahci_timeout_pkts called while executing R/W PMULT "
9764 9764                      "command timeout_tags = 0x%x, slot_status = 0x%x",
9765 9765                      tmp_timeout_tags, slot_status);
9766 9766                  ASSERT(slot_status == 0x1);
9767 9767          }
9768 9768  #endif
9769 9769  
9770 9770          ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
9771 9771          ahci_portp->ahciport_mop_in_progress++;
9772 9772  
9773 9773          (void) ahci_restart_port_wait_till_ready(ahci_ctlp, ahci_portp,
9774 9774              port, AHCI_PORT_RESET, NULL);
9775 9775  
9776 9776          /*
9777 9777           * Re-identify timeout tags because some previously checked commands
9778 9778           * could already complete.
9779 9779           */
9780 9780          if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9781 9781                  finished_tags = ahci_portp->ahciport_pending_tags &
9782 9782                      ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
9783 9783                  timeout_tags = tmp_timeout_tags & ~finished_tags;
9784 9784  
9785 9785                  AHCIDBG(AHCIDBG_TIMEOUT, ahci_ctlp,
9786 9786                      "ahci_timeout_pkts: port %d, finished_tags = 0x%x, "
9787 9787                      "timeout_tags = 0x%x, port_cmd_issue = 0x%x, "
9788 9788                      "pending_tags = 0x%x ",
9789 9789                      port, finished_tags, timeout_tags,
9790 9790                      slot_status, ahci_portp->ahciport_pending_tags);
9791 9791          } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9792 9792                  finished_tags = ahci_portp->ahciport_pending_ncq_tags &
9793 9793                      ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
9794 9794                  timeout_tags = tmp_timeout_tags & ~finished_tags;
9795 9795  
9796 9796                  AHCIDBG(AHCIDBG_TIMEOUT|AHCIDBG_NCQ, ahci_ctlp,
9797 9797                      "ahci_timeout_pkts: port %d, finished_tags = 0x%x, "
9798 9798                      "timeout_tags = 0x%x, port_sactive = 0x%x, "
9799 9799                      "pending_ncq_tags = 0x%x ",
9800 9800                      port, finished_tags, timeout_tags,
9801 9801                      slot_status, ahci_portp->ahciport_pending_ncq_tags);
9802 9802          } else if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) ||
9803 9803              RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
9804 9804                  timeout_tags = tmp_timeout_tags;
9805 9805          }
9806 9806  
9807 9807          ahci_mop_commands(ahci_ctlp,
9808 9808              ahci_portp,
9809 9809              slot_status,
9810 9810              0,                  /* failed tags */
9811 9811              timeout_tags,       /* timeout tags */
9812 9812              0,                  /* aborted tags */
9813 9813              0);                 /* reset tags */
9814 9814  
9815 9815          mutex_exit(&ahci_portp->ahciport_mutex);
9816 9816  }
9817 9817  
9818 9818  /*
9819 9819   * Watchdog handler kicks in every 5 seconds to timeout any commands pending
9820 9820   * for long time.
9821 9821   */
9822 9822  static void
9823 9823  ahci_watchdog_handler(ahci_ctl_t *ahci_ctlp)
9824 9824  {
9825 9825          ahci_port_t *ahci_portp;
9826 9826          sata_pkt_t *spkt;
9827 9827          uint32_t pending_tags;
9828 9828          uint32_t timeout_tags;
9829 9829          uint32_t port_cmd_status;
9830 9830          uint32_t port_sactive;
9831 9831          uint8_t port;
9832 9832          int tmp_slot;
9833 9833          int current_slot;
9834 9834          uint32_t current_tags;
9835 9835          int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
9836 9836  
9837 9837          mutex_enter(&ahci_ctlp->ahcictl_mutex);
9838 9838  
9839 9839          AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
9840 9840              "ahci_watchdog_handler entered", NULL);
9841 9841  
9842 9842          current_slot = 0;
9843 9843          current_tags = 0;
9844 9844          for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
9845 9845                  if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
9846 9846                          continue;
9847 9847                  }
9848 9848  
9849 9849                  ahci_portp = ahci_ctlp->ahcictl_ports[port];
9850 9850  
9851 9851                  mutex_enter(&ahci_portp->ahciport_mutex);
9852 9852                  if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
9853 9853                          mutex_exit(&ahci_portp->ahciport_mutex);
9854 9854                          continue;
9855 9855                  }
9856 9856  
9857 9857                  /* Skip the check for those ports in error recovery */
9858 9858                  if ((ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) &&
9859 9859                      !(ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))) {
9860 9860                          mutex_exit(&ahci_portp->ahciport_mutex);
9861 9861                          continue;
9862 9862                  }
9863 9863  
9864 9864                  pending_tags = 0;
9865 9865                  port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9866 9866                      (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
9867 9867  
9868 9868                  if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) ||
9869 9869                      RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
9870 9870                          current_slot = 0;
9871 9871                          pending_tags = 0x1;
9872 9872                  } else if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9873 9873                          current_slot =
9874 9874                              (port_cmd_status & AHCI_CMD_STATUS_CCS) >>
9875 9875                              AHCI_CMD_STATUS_CCS_SHIFT;
9876 9876                          pending_tags = ahci_portp->ahciport_pending_tags;
9877 9877                  } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9878 9878                          port_sactive = ddi_get32(
9879 9879                              ahci_ctlp->ahcictl_ahci_acc_handle,
9880 9880                              (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
9881 9881                          current_tags = port_sactive &
9882 9882                              ~port_cmd_status &
9883 9883                              AHCI_NCQ_SLOT_MASK(ahci_portp);
9884 9884                          pending_tags = ahci_portp->ahciport_pending_ncq_tags;
9885 9885                  }
9886 9886  
9887 9887                  timeout_tags = 0;
9888 9888                  while (pending_tags) {
9889 9889                          tmp_slot = ddi_ffs(pending_tags) - 1;
9890 9890                          if (tmp_slot == -1) {
9891 9891                                  break;
9892 9892                          }
9893 9893  
9894 9894                          if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
9895 9895                                  spkt = ahci_portp->ahciport_err_retri_pkt;
9896 9896                          else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp))
9897 9897                                  spkt = ahci_portp->ahciport_rdwr_pmult_pkt;
9898 9898                          else
9899 9899                                  spkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9900 9900  
9901 9901                          if ((spkt != NULL) && spkt->satapkt_time &&
9902 9902                              !(spkt->satapkt_op_mode & SATA_OPMODE_POLLING)) {
9903 9903                                  /*
9904 9904                                   * If a packet has survived for more than it's
9905 9905                                   * max life cycles, it is a candidate for time
9906 9906                                   * out.
9907 9907                                   */
9908 9908                                  ahci_portp->ahciport_slot_timeout[tmp_slot] -=
9909 9909                                      ahci_watchdog_timeout;
9910 9910  
9911 9911                                  if (ahci_portp->ahciport_slot_timeout[tmp_slot]
9912 9912                                      > 0)
9913 9913                                          goto next;
9914 9914  
9915 9915  #if AHCI_DEBUG
9916 9916                                  if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9917 9917                                          AHCIDBG(AHCIDBG_ERRS|AHCIDBG_TIMEOUT,
9918 9918                                              ahci_ctlp, "watchdog: the current "
9919 9919                                              "tags is 0x%x", current_tags);
9920 9920                                  } else {
9921 9921                                          AHCIDBG(AHCIDBG_ERRS|AHCIDBG_TIMEOUT,
9922 9922                                              ahci_ctlp, "watchdog: the current "
9923 9923                                              "slot is %d", current_slot);
9924 9924                                  }
9925 9925  #endif
9926 9926  
9927 9927                                  /*
9928 9928                                   * We need to check whether the HBA has
9929 9929                                   * begun to execute the command, if not,
9930 9930                                   * then re-set the timer of the command.
9931 9931                                   */
9932 9932                                  if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp) &&
9933 9933                                      (tmp_slot != current_slot) ||
9934 9934                                      NCQ_CMD_IN_PROGRESS(ahci_portp) &&
9935 9935                                      ((0x1 << tmp_slot) & current_tags)) {
9936 9936                                          ahci_portp->ahciport_slot_timeout \
9937 9937                                              [tmp_slot] = spkt->satapkt_time;
9938 9938                                  } else {
9939 9939                                          timeout_tags |= (0x1 << tmp_slot);
9940 9940                                          cmn_err(CE_WARN, "!ahci%d: watchdog "
9941 9941                                              "port %d satapkt 0x%p timed out\n",
9942 9942                                              instance, port, (void *)spkt);
9943 9943                                  }
9944 9944                          }
9945 9945  next:
9946 9946                          CLEAR_BIT(pending_tags, tmp_slot);
9947 9947                  }
9948 9948  
9949 9949                  if (timeout_tags) {
9950 9950                          mutex_exit(&ahci_portp->ahciport_mutex);
9951 9951                          mutex_exit(&ahci_ctlp->ahcictl_mutex);
9952 9952                          ahci_timeout_pkts(ahci_ctlp, ahci_portp,
9953 9953                              port, timeout_tags);
9954 9954                          mutex_enter(&ahci_ctlp->ahcictl_mutex);
9955 9955                          mutex_enter(&ahci_portp->ahciport_mutex);
9956 9956                  }
9957 9957  
9958 9958                  mutex_exit(&ahci_portp->ahciport_mutex);
9959 9959          }
9960 9960  
9961 9961          /* Re-install the watchdog timeout handler */
9962 9962          if (ahci_ctlp->ahcictl_timeout_id != 0) {
9963 9963                  ahci_ctlp->ahcictl_timeout_id =
9964 9964                      timeout((void (*)(void *))ahci_watchdog_handler,
9965 9965                      (caddr_t)ahci_ctlp, ahci_watchdog_tick);
9966 9966          }
9967 9967  
9968 9968          mutex_exit(&ahci_ctlp->ahcictl_mutex);
9969 9969  }
9970 9970  
9971 9971  /*
9972 9972   * Fill the error context into sata_cmd for non-queued command error.
9973 9973   */
9974 9974  static void
9975 9975  ahci_copy_err_cnxt(sata_cmd_t *scmd, ahci_fis_d2h_register_t *rfisp)
9976 9976  {
9977 9977          scmd->satacmd_status_reg = GET_RFIS_STATUS(rfisp);
9978 9978          scmd->satacmd_error_reg = GET_RFIS_ERROR(rfisp);
9979 9979          scmd->satacmd_sec_count_lsb = GET_RFIS_SECTOR_COUNT(rfisp);
9980 9980          scmd->satacmd_lba_low_lsb = GET_RFIS_CYL_LOW(rfisp);
9981 9981          scmd->satacmd_lba_mid_lsb = GET_RFIS_CYL_MID(rfisp);
9982 9982          scmd->satacmd_lba_high_lsb = GET_RFIS_CYL_HI(rfisp);
9983 9983          scmd->satacmd_device_reg = GET_RFIS_DEV_HEAD(rfisp);
9984 9984  
9985 9985          if (scmd->satacmd_addr_type == ATA_ADDR_LBA48) {
9986 9986                  scmd->satacmd_sec_count_msb = GET_RFIS_SECTOR_COUNT_EXP(rfisp);
9987 9987                  scmd->satacmd_lba_low_msb = GET_RFIS_CYL_LOW_EXP(rfisp);
9988 9988                  scmd->satacmd_lba_mid_msb = GET_RFIS_CYL_MID_EXP(rfisp);
9989 9989                  scmd->satacmd_lba_high_msb = GET_RFIS_CYL_HI_EXP(rfisp);
9990 9990          }
9991 9991  }
9992 9992  
9993 9993  /*
9994 9994   * Fill the ncq error page into sata_cmd for queued command error.
9995 9995   */
9996 9996  static void
9997 9997  ahci_copy_ncq_err_page(sata_cmd_t *scmd,
9998 9998      struct sata_ncq_error_recovery_page *ncq_err_page)
9999 9999  {
10000 10000          scmd->satacmd_sec_count_msb = ncq_err_page->ncq_sector_count_ext;
10001 10001          scmd->satacmd_sec_count_lsb = ncq_err_page->ncq_sector_count;
10002 10002          scmd->satacmd_lba_low_msb = ncq_err_page->ncq_sector_number_ext;
10003 10003          scmd->satacmd_lba_low_lsb = ncq_err_page->ncq_sector_number;
10004 10004          scmd->satacmd_lba_mid_msb = ncq_err_page->ncq_cyl_low_ext;
10005 10005          scmd->satacmd_lba_mid_lsb = ncq_err_page->ncq_cyl_low;
10006 10006          scmd->satacmd_lba_high_msb = ncq_err_page->ncq_cyl_high_ext;
10007 10007          scmd->satacmd_lba_high_lsb = ncq_err_page->ncq_cyl_high;
10008 10008          scmd->satacmd_device_reg = ncq_err_page->ncq_dev_head;
10009 10009          scmd->satacmd_status_reg = ncq_err_page->ncq_status;
10010 10010          scmd->satacmd_error_reg = ncq_err_page->ncq_error;
10011 10011  }
10012 10012  
10013 10013  /*
10014 10014   * Put the respective register value to sata_cmd_t for satacmd_flags.
10015 10015   */
10016 10016  static void
10017 10017  ahci_copy_out_regs(sata_cmd_t *scmd, ahci_fis_d2h_register_t *rfisp)
10018 10018  {
10019 10019          if (scmd->satacmd_flags.sata_copy_out_sec_count_msb)
10020 10020                  scmd->satacmd_sec_count_msb = GET_RFIS_SECTOR_COUNT_EXP(rfisp);
10021 10021          if (scmd->satacmd_flags.sata_copy_out_lba_low_msb)
10022 10022                  scmd->satacmd_lba_low_msb = GET_RFIS_CYL_LOW_EXP(rfisp);
10023 10023          if (scmd->satacmd_flags.sata_copy_out_lba_mid_msb)
10024 10024                  scmd->satacmd_lba_mid_msb = GET_RFIS_CYL_MID_EXP(rfisp);
10025 10025          if (scmd->satacmd_flags.sata_copy_out_lba_high_msb)
10026 10026                  scmd->satacmd_lba_high_msb = GET_RFIS_CYL_HI_EXP(rfisp);
10027 10027          if (scmd->satacmd_flags.sata_copy_out_sec_count_lsb)
10028 10028                  scmd->satacmd_sec_count_lsb = GET_RFIS_SECTOR_COUNT(rfisp);
10029 10029          if (scmd->satacmd_flags.sata_copy_out_lba_low_lsb)
10030 10030                  scmd->satacmd_lba_low_lsb = GET_RFIS_CYL_LOW(rfisp);
10031 10031          if (scmd->satacmd_flags.sata_copy_out_lba_mid_lsb)
10032 10032                  scmd->satacmd_lba_mid_lsb = GET_RFIS_CYL_MID(rfisp);
10033 10033          if (scmd->satacmd_flags.sata_copy_out_lba_high_lsb)
10034 10034                  scmd->satacmd_lba_high_lsb = GET_RFIS_CYL_HI(rfisp);
10035 10035          if (scmd->satacmd_flags.sata_copy_out_device_reg)
10036 10036                  scmd->satacmd_device_reg = GET_RFIS_DEV_HEAD(rfisp);
10037 10037          if (scmd->satacmd_flags.sata_copy_out_error_reg)
10038 10038                  scmd->satacmd_error_reg = GET_RFIS_ERROR(rfisp);
10039 10039  }
10040 10040  
10041 10041  static void
10042 10042  ahci_log_fatal_error_message(ahci_ctl_t *ahci_ctlp, uint8_t port,
10043 10043      uint32_t intr_status)
10044 10044  {
10045 10045          int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
10046 10046  
10047 10047          if (intr_status & AHCI_INTR_STATUS_IFS)
10048 10048                  cmn_err(CE_WARN, "!ahci%d: ahci port %d has interface fatal "
10049 10049                      "error", instance, port);
10050 10050  
10051 10051          if (intr_status & AHCI_INTR_STATUS_HBDS)
10052 10052                  cmn_err(CE_WARN, "!ahci%d: ahci port %d has bus data error",
10053 10053                      instance, port);
10054 10054  
10055 10055          if (intr_status & AHCI_INTR_STATUS_HBFS)
10056 10056                  cmn_err(CE_WARN, "!ahci%d: ahci port %d has bus fatal error",
10057 10057                      instance, port);
10058 10058  
10059 10059          if (intr_status & AHCI_INTR_STATUS_TFES)
10060 10060                  cmn_err(CE_WARN, "!ahci%d: ahci port %d has task file error",
10061 10061                      instance, port);
10062 10062  
10063 10063          cmn_err(CE_WARN, "!ahci%d: ahci port %d is trying to do error "
10064 10064              "recovery", instance, port);
10065 10065  }
10066 10066  
10067 10067  static void
10068 10068  ahci_dump_commands(ahci_ctl_t *ahci_ctlp, uint8_t port,
10069 10069      uint32_t slot_tags)
10070 10070  {
10071 10071          ahci_port_t *ahci_portp;
10072 10072          int tmp_slot;
10073 10073          sata_pkt_t *spkt;
10074 10074          sata_cmd_t cmd;
10075 10075  
10076 10076          ahci_portp = ahci_ctlp->ahcictl_ports[port];
10077 10077          ASSERT(ahci_portp != NULL);
10078 10078  
10079 10079          while (slot_tags) {
10080 10080                  tmp_slot = ddi_ffs(slot_tags) - 1;
10081 10081                  if (tmp_slot == -1) {
10082 10082                          break;
10083 10083                  }
10084 10084  
10085 10085                  spkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
10086 10086                  if (spkt != NULL) {
10087 10087                          cmd = spkt->satapkt_cmd;
10088 10088  
10089 10089                          cmn_err(CE_WARN, "!satapkt 0x%p: cmd_reg = 0x%x "
10090 10090                              "features_reg = 0x%x sec_count_msb = 0x%x "
10091 10091                              "lba_low_msb = 0x%x lba_mid_msb = 0x%x "
10092 10092                              "lba_high_msb = 0x%x sec_count_lsb = 0x%x "
10093 10093                              "lba_low_lsb = 0x%x lba_mid_lsb = 0x%x "
10094 10094                              "lba_high_lsb = 0x%x device_reg = 0x%x "
10095 10095                              "addr_type = 0x%x cmd_flags = 0x%x", (void *)spkt,
10096 10096                              cmd.satacmd_cmd_reg, cmd.satacmd_features_reg,
10097 10097                              cmd.satacmd_sec_count_msb, cmd.satacmd_lba_low_msb,
10098 10098                              cmd.satacmd_lba_mid_msb, cmd.satacmd_lba_high_msb,
10099 10099                              cmd.satacmd_sec_count_lsb, cmd.satacmd_lba_low_lsb,
10100 10100                              cmd.satacmd_lba_mid_lsb, cmd.satacmd_lba_high_lsb,
10101 10101                              cmd.satacmd_device_reg, cmd.satacmd_addr_type,
10102 10102                              *((uint32_t *)&(cmd.satacmd_flags)));
10103 10103                  }
10104 10104  
10105 10105                  CLEAR_BIT(slot_tags, tmp_slot);
10106 10106          }
10107 10107  }
10108 10108  
10109 10109  /*
10110 10110   * Dump the serror message to the log.
10111 10111   */
10112 10112  static void
10113 10113  ahci_log_serror_message(ahci_ctl_t *ahci_ctlp, uint8_t port,
10114 10114      uint32_t port_serror, int debug_only)
10115 10115  {
10116 10116          static char err_buf[512];
10117 10117          static char err_msg_header[16];
10118 10118          char *err_msg = err_buf;
10119 10119  
10120 10120          *err_buf = '\0';
10121 10121          *err_msg_header = '\0';
10122 10122  
10123 10123          if (port_serror & SERROR_DATA_ERR_FIXED) {
10124 10124                  err_msg = strcat(err_msg,
10125 10125                      "\tRecovered Data Integrity Error (I)\n");
10126 10126          }
10127 10127  
10128 10128          if (port_serror & SERROR_COMM_ERR_FIXED) {
10129 10129                  err_msg = strcat(err_msg,
10130 10130                      "\tRecovered Communication Error (M)\n");
10131 10131          }
10132 10132  
10133 10133          if (port_serror & SERROR_DATA_ERR) {
10134 10134                  err_msg = strcat(err_msg,
10135 10135                      "\tTransient Data Integrity Error (T)\n");
10136 10136          }
10137 10137  
10138 10138          if (port_serror & SERROR_PERSISTENT_ERR) {
10139 10139                  err_msg = strcat(err_msg,
10140 10140                      "\tPersistent Communication or Data Integrity Error (C)\n");
10141 10141          }
10142 10142  
10143 10143          if (port_serror & SERROR_PROTOCOL_ERR) {
10144 10144                  err_msg = strcat(err_msg, "\tProtocol Error (P)\n");
10145 10145          }
10146 10146  
10147 10147          if (port_serror & SERROR_INT_ERR) {
10148 10148                  err_msg = strcat(err_msg, "\tInternal Error (E)\n");
10149 10149          }
10150 10150  
10151 10151          if (port_serror & SERROR_PHY_RDY_CHG) {
10152 10152                  err_msg = strcat(err_msg, "\tPhyRdy Change (N)\n");
10153 10153          }
10154 10154  
10155 10155          if (port_serror & SERROR_PHY_INT_ERR) {
10156 10156                  err_msg = strcat(err_msg, "\tPhy Internal Error (I)\n");
10157 10157          }
10158 10158  
10159 10159          if (port_serror & SERROR_COMM_WAKE) {
10160 10160                  err_msg = strcat(err_msg, "\tComm Wake (W)\n");
10161 10161          }
10162 10162  
10163 10163          if (port_serror & SERROR_10B_TO_8B_ERR) {
10164 10164                  err_msg = strcat(err_msg, "\t10B to 8B Decode Error (B)\n");
10165 10165          }
10166 10166  
10167 10167          if (port_serror & SERROR_DISPARITY_ERR) {
10168 10168                  err_msg = strcat(err_msg, "\tDisparity Error (D)\n");
10169 10169          }
10170 10170  
10171 10171          if (port_serror & SERROR_CRC_ERR) {
10172 10172                  err_msg = strcat(err_msg, "\tCRC Error (C)\n");
10173 10173          }
10174 10174  
10175 10175          if (port_serror & SERROR_HANDSHAKE_ERR) {
10176 10176                  err_msg = strcat(err_msg, "\tHandshake Error (H)\n");
10177 10177          }
10178 10178  
10179 10179          if (port_serror & SERROR_LINK_SEQ_ERR) {
10180 10180                  err_msg = strcat(err_msg, "\tLink Sequence Error (S)\n");
10181 10181          }
10182 10182  
10183 10183          if (port_serror & SERROR_TRANS_ERR) {
10184 10184                  err_msg = strcat(err_msg,
10185 10185                      "\tTransport state transition error (T)\n");
10186 10186          }
10187 10187  
10188 10188          if (port_serror & SERROR_FIS_TYPE) {
10189 10189                  err_msg = strcat(err_msg, "\tUnknown FIS Type (F)\n");
10190 10190          }
10191 10191  
10192 10192          if (port_serror & SERROR_EXCHANGED_ERR) {
10193 10193                  err_msg = strcat(err_msg, "\tExchanged (X)\n");
10194 10194          }
10195 10195  
10196 10196          if (*err_msg == '\0')
10197 10197                  return;
10198 10198  
10199 10199          if (debug_only) {
10200 10200                  (void) sprintf(err_msg_header, "port %d", port);
10201 10201                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, err_msg_header, NULL);
10202 10202                  AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, err_msg, NULL);
10203 10203          } else if (ahci_ctlp) {
10204 10204                  cmn_err(CE_WARN, "!ahci%d: %s %s",
10205 10205                      ddi_get_instance(ahci_ctlp->ahcictl_dip),
10206 10206                      err_msg_header, err_msg);
10207 10207  
10208 10208                  /* sata trace debug */
10209 10209                  sata_trace_debug(ahci_ctlp->ahcictl_dip,
10210 10210                      "ahci%d: %s %s", ddi_get_instance(ahci_ctlp->ahcictl_dip),
10211 10211                      err_msg_header, err_msg);
10212 10212          } else {
10213 10213                  cmn_err(CE_WARN, "!ahci: %s %s", err_msg_header, err_msg);
10214 10214  
10215 10215                  /* sata trace debug */
10216 10216                  sata_trace_debug(NULL, "ahci: %s %s", err_msg_header, err_msg);
10217 10217          }
10218 10218  }
10219 10219  
10220 10220  /*
10221 10221   * Translate the sata_address_t type into the ahci_addr_t type.
10222 10222   * sata_device.satadev_addr structure is used as source.
10223 10223   */
10224 10224  static void
10225 10225  ahci_get_ahci_addr(ahci_ctl_t *ahci_ctlp, sata_device_t *sd,
10226 10226      ahci_addr_t *ahci_addrp)
10227 10227  {
10228 10228          sata_address_t *sata_addrp = &sd->satadev_addr;
10229 10229          ahci_addrp->aa_port =
10230 10230              ahci_ctlp->ahcictl_cport_to_port[sata_addrp->cport];
10231 10231          ahci_addrp->aa_pmport = sata_addrp->pmport;
10232 10232  
10233 10233          switch (sata_addrp->qual) {
10234 10234          case SATA_ADDR_DCPORT:
10235 10235          case SATA_ADDR_CPORT:
10236 10236                  ahci_addrp->aa_qual = AHCI_ADDR_PORT;
10237 10237                  break;
10238 10238          case SATA_ADDR_PMULT:
10239 10239          case SATA_ADDR_PMULT_SPEC:
10240 10240                  ahci_addrp->aa_qual = AHCI_ADDR_PMULT;
10241 10241                  break;
10242 10242          case SATA_ADDR_DPMPORT:
10243 10243          case SATA_ADDR_PMPORT:
10244 10244                  ahci_addrp->aa_qual = AHCI_ADDR_PMPORT;
10245 10245                  break;
10246 10246          case SATA_ADDR_NULL:
10247 10247          default:
10248 10248                  /* something went wrong */
10249 10249                  ahci_addrp->aa_qual = AHCI_ADDR_NULL;
10250 10250                  break;
10251 10251          }
10252 10252  }
10253 10253  
10254 10254  /*
10255 10255   * This routine is to calculate the total number of ports implemented
10256 10256   * by the HBA.
10257 10257   */
10258 10258  static int
10259 10259  ahci_get_num_implemented_ports(uint32_t ports_implemented)
10260 10260  {
10261 10261          uint8_t i;
10262 10262          int num = 0;
10263 10263  
10264 10264          for (i = 0; i < AHCI_MAX_PORTS; i++) {
10265 10265                  if (((uint32_t)0x1 << i) & ports_implemented)
10266 10266                          num++;
10267 10267          }
10268 10268  
10269 10269          return (num);
10270 10270  }
10271 10271  
10272 10272  #if AHCI_DEBUG
10273 10273  static void
10274 10274  ahci_log(ahci_ctl_t *ahci_ctlp, uint_t level, char *fmt, ...)
10275 10275  {
10276 10276          static char name[16];
10277 10277          va_list ap;
10278 10278  
10279 10279          mutex_enter(&ahci_log_mutex);
10280 10280  
10281 10281          va_start(ap, fmt);
10282 10282          if (ahci_ctlp) {
10283 10283                  (void) sprintf(name, "ahci%d: ",
10284 10284                      ddi_get_instance(ahci_ctlp->ahcictl_dip));
10285 10285          } else {
10286 10286                  (void) sprintf(name, "ahci: ");
10287 10287          }
10288 10288  
10289 10289          (void) vsprintf(ahci_log_buf, fmt, ap);
10290 10290          va_end(ap);
10291 10291  
10292 10292          cmn_err(level, "%s%s", name, ahci_log_buf);
10293 10293  
10294 10294          mutex_exit(&ahci_log_mutex);
10295 10295  }
10296 10296  #endif
10297 10297  
10298 10298  /*
10299 10299   * quiesce(9E) entry point.
10300 10300   *
10301 10301   * This function is called when the system is single-threaded at high
10302 10302   * PIL with preemption disabled. Therefore, this function must not be
10303 10303   * blocked. Because no taskqs are running, there is no need for us to
10304 10304   * take any action for enclosure services which are running in the
10305 10305   * taskq context, especially as no interrupts are generated by it nor
10306 10306   * are any messages expected to come in.
10307 10307   *
10308 10308   * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
10309 10309   * DDI_FAILURE indicates an error condition and should almost never happen.
10310 10310   */
10311 10311  static int
10312 10312  ahci_quiesce(dev_info_t *dip)
10313 10313  {
10314 10314          ahci_ctl_t *ahci_ctlp;
10315 10315          ahci_port_t *ahci_portp;
10316 10316          int instance, port;
10317 10317  
10318 10318          instance = ddi_get_instance(dip);
10319 10319          ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
10320 10320  
10321 10321          if (ahci_ctlp == NULL)
10322 10322                  return (DDI_FAILURE);
10323 10323  
10324 10324  #if AHCI_DEBUG
10325 10325          ahci_debug_flags = 0;
10326 10326  #endif
10327 10327  
10328 10328          ahci_ctlp->ahcictl_flags |= AHCI_QUIESCE;
10329 10329  
10330 10330          /* disable all the interrupts. */
10331 10331          ahci_disable_all_intrs(ahci_ctlp);
10332 10332  
10333 10333          for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
10334 10334                  if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
10335 10335                          continue;
10336 10336                  }
10337 10337  
10338 10338                  ahci_portp = ahci_ctlp->ahcictl_ports[port];
10339 10339  
10340 10340                  /*
10341 10341                   * Stop the port by clearing PxCMD.ST
10342 10342                   *
10343 10343                   * Here we must disable the port interrupt because
10344 10344                   * ahci_disable_all_intrs only clear GHC.IE, and IS
10345 10345                   * register will be still set if PxIE is enabled.
10346 10346                   * When ahci shares one IRQ with other drivers, the
10347 10347                   * intr handler may claim the intr mistakenly.
10348 10348                   */
10349 10349                  ahci_disable_port_intrs(ahci_ctlp, port);
10350 10350                  (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
10351 10351                      ahci_portp, port);
10352 10352          }
10353 10353  
10354 10354          ahci_ctlp->ahcictl_flags &= ~AHCI_QUIESCE;
10355 10355  
10356 10356          return (DDI_SUCCESS);
10357 10357  }
10358 10358  
10359 10359  /*
10360 10360   * The function will add a sata packet to the done queue.
10361 10361   */
10362 10362  static void
10363 10363  ahci_add_doneq(ahci_port_t *ahci_portp, sata_pkt_t *satapkt, int reason)
10364 10364  {
10365 10365          ASSERT(satapkt != NULL);
10366 10366          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
10367 10367  
10368 10368          /* set the reason for all packets */
10369 10369          satapkt->satapkt_reason = reason;
10370 10370          satapkt->satapkt_hba_driver_private = NULL;
10371 10371  
10372 10372          if (! (satapkt->satapkt_op_mode & SATA_OPMODE_SYNCH) &&
10373 10373              satapkt->satapkt_comp) {
10374 10374                  /*
10375 10375                   * only add to queue when mode is not synch and there is
10376 10376                   * completion callback
10377 10377                   */
10378 10378                  *ahci_portp->ahciport_doneqtail = satapkt;
10379 10379                  ahci_portp->ahciport_doneqtail =
10380 10380                      (sata_pkt_t **)&(satapkt->satapkt_hba_driver_private);
10381 10381                  ahci_portp->ahciport_doneq_len++;
10382 10382  
10383 10383          } else if ((satapkt->satapkt_op_mode & SATA_OPMODE_SYNCH) &&
10384 10384              ! (satapkt->satapkt_op_mode & SATA_OPMODE_POLLING))
10385 10385                  /*
10386 10386                   * for sync/non-poll mode, just call cv_broadcast
10387 10387                   */
10388 10388                  cv_broadcast(&ahci_portp->ahciport_cv);
10389 10389  }
10390 10390  
10391 10391  /*
10392 10392   * The function will call completion callback of sata packet on the
10393 10393   * completed queue
10394 10394   */
10395 10395  static void
10396 10396  ahci_flush_doneq(ahci_port_t *ahci_portp)
10397 10397  {
10398 10398          sata_pkt_t *satapkt, *next;
10399 10399  
10400 10400          ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
10401 10401  
10402 10402          if (ahci_portp->ahciport_doneq) {
10403 10403                  satapkt = ahci_portp->ahciport_doneq;
10404 10404  
10405 10405                  ahci_portp->ahciport_doneq = NULL;
10406 10406                  ahci_portp->ahciport_doneqtail = &ahci_portp->ahciport_doneq;
10407 10407                  ahci_portp->ahciport_doneq_len = 0;
10408 10408  
10409 10409                  mutex_exit(&ahci_portp->ahciport_mutex);
10410 10410  
10411 10411                  while (satapkt != NULL) {
10412 10412                          next = satapkt->satapkt_hba_driver_private;
10413 10413                          satapkt->satapkt_hba_driver_private = NULL;
10414 10414  
10415 10415                          /* Call the callback */
10416 10416                          (*satapkt->satapkt_comp)(satapkt);
10417 10417  
10418 10418                          satapkt = next;
10419 10419                  }
10420 10420  
10421 10421                  mutex_enter(&ahci_portp->ahciport_mutex);
10422 10422          }
10423 10423  }
10424 10424  
10425 10425  /*
10426 10426   * Sets the state for the specified port on the controller to desired state.
10427 10427   * This must be run in the context of the enclosure taskq which ensures that
10428 10428   * only one event is outstanding at any time.
10429 10429   */
10430 10430  static boolean_t
10431 10431  ahci_em_set_led(ahci_ctl_t *ahci_ctlp, uint8_t port, ahci_em_led_state_t desire)
10432 10432  {
10433 10433          ahci_em_led_msg_t msg;
10434 10434          ahci_em_msg_hdr_t hdr;
10435 10435          uint32_t msgval, hdrval;
10436 10436          uint_t i, max_delay = ahci_em_tx_delay_count;
10437 10437  
10438 10438          msg.alm_hba = port;
10439 10439          msg.alm_pminfo = 0;
10440 10440          msg.alm_value = 0;
10441 10441  
10442 10442          if (desire & AHCI_EM_LED_IDENT_ENABLE) {
10443 10443                  msg.alm_value |= AHCI_LED_ON << AHCI_LED_IDENT_OFF;
10444 10444          }
10445 10445  
10446 10446          if (desire & AHCI_EM_LED_FAULT_ENABLE) {
10447 10447                  msg.alm_value |= AHCI_LED_ON << AHCI_LED_FAULT_OFF;
10448 10448          }
10449 10449  
10450 10450          if ((ahci_ctlp->ahcictl_em_ctl & AHCI_HBA_EM_CTL_ATTR_ALHD) == 0 &&
10451 10451              (desire & AHCI_EM_LED_ACTIVITY_DISABLE) == 0) {
10452 10452                  msg.alm_value |= AHCI_LED_ON << AHCI_LED_ACTIVITY_OFF;
10453 10453          }
10454 10454  
10455 10455          hdr.aemh_rsvd = 0;
10456 10456          hdr.aemh_mlen = sizeof (ahci_em_led_msg_t);
10457 10457          hdr.aemh_dlen = 0;
10458 10458          hdr.aemh_mtype = AHCI_EM_MSG_TYPE_LED;
10459 10459  
10460 10460          bcopy(&msg, &msgval, sizeof (msgval));
10461 10461          bcopy(&hdr, &hdrval, sizeof (hdrval));
10462 10462  
10463 10463          /*
10464 10464           * First, make sure we can transmit. We should not have been placed in a
10465 10465           * situation where an outstanding transmission is going on.
10466 10466           */
10467 10467          for (i = 0; i < max_delay; i++) {
10468 10468                  uint32_t val;
10469 10469  
10470 10470                  val = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
10471 10471                      (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp));
10472 10472                  if ((val & AHCI_HBA_EM_CTL_CTL_TM) == 0)
10473 10473                          break;
10474 10474  
10475 10475                  delay(drv_usectohz(ahci_em_tx_delay_ms * 1000));
10476 10476          }
10477 10477  
10478 10478          if (i == max_delay)
10479 10479                  return (B_FALSE);
10480 10480  
10481 10481          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
10482 10482              (uint32_t *)ahci_ctlp->ahcictl_em_tx_off, hdrval);
10483 10483          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
10484 10484              (uint32_t *)(ahci_ctlp->ahcictl_em_tx_off + 4), msgval);
10485 10485          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
10486 10486              (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp), AHCI_HBA_EM_CTL_CTL_TM);
10487 10487  
10488 10488          for (i = 0; i < max_delay; i++) {
10489 10489                  uint32_t val;
10490 10490  
10491 10491                  val = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
10492 10492                      (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp));
10493 10493                  if ((val & AHCI_HBA_EM_CTL_CTL_TM) == 0)
10494 10494                          break;
10495 10495  
10496 10496                  delay(drv_usectohz(ahci_em_tx_delay_ms * 1000));
10497 10497          }
10498 10498  
10499 10499          if (i == max_delay)
10500 10500                  return (B_FALSE);
10501 10501  
10502 10502          return (B_TRUE);
10503 10503  }
10504 10504  
10505 10505  typedef struct ahci_em_led_task_arg {
10506 10506          ahci_ctl_t              *aelta_ctl;
10507 10507          uint8_t                 aelta_port;
10508 10508          uint_t                  aelta_op;
10509 10509          ahci_em_led_state_t     aelta_state;
10510 10510          uint_t                  aelta_ret;
10511 10511          kcondvar_t              aelta_cv;
10512 10512          uint_t                  aelta_ref;
10513 10513  } ahci_em_led_task_arg_t;
10514 10514  
10515 10515  static void
10516 10516  ahci_em_led_task_free(ahci_em_led_task_arg_t *task)
10517 10517  {
10518 10518          ASSERT3U(task->aelta_ref, ==, 0);
10519 10519          cv_destroy(&task->aelta_cv);
10520 10520          kmem_free(task, sizeof (*task));
10521 10521  }
10522 10522  
10523 10523  static void
10524 10524  ahci_em_led_task(void *arg)
10525 10525  {
10526 10526          boolean_t ret, cleanup = B_FALSE;
10527 10527          ahci_em_led_task_arg_t *led = arg;
10528 10528          ahci_em_led_state_t state;
10529 10529  
10530 10530          mutex_enter(&led->aelta_ctl->ahcictl_mutex);
10531 10531          if (led->aelta_ctl->ahcictl_em_flags != AHCI_EM_USABLE) {
10532 10532                  led->aelta_ret = EIO;
10533 10533                  mutex_exit(&led->aelta_ctl->ahcictl_mutex);
10534 10534                  return;
10535 10535          }
10536 10536  
10537 10537          state = led->aelta_ctl->ahcictl_em_state[led->aelta_port];
10538 10538          mutex_exit(&led->aelta_ctl->ahcictl_mutex);
10539 10539  
10540 10540          switch (led->aelta_op) {
10541 10541          case AHCI_EM_IOC_SET_OP_ADD:
10542 10542                  state |= led->aelta_state;
10543 10543                  break;
10544 10544          case AHCI_EM_IOC_SET_OP_REM:
10545 10545                  state &= ~led->aelta_state;
10546 10546                  break;
10547 10547          case AHCI_EM_IOC_SET_OP_SET:
10548 10548                  state = led->aelta_state;
10549 10549                  break;
10550 10550          default:
10551 10551                  led->aelta_ret = ENOTSUP;
10552 10552                  return;
10553 10553          }
10554 10554  
10555 10555          ret = ahci_em_set_led(led->aelta_ctl, led->aelta_port, state);
10556 10556  
10557 10557          mutex_enter(&led->aelta_ctl->ahcictl_mutex);
10558 10558          if (ret) {
10559 10559                  led->aelta_ctl->ahcictl_em_state[led->aelta_port] = state;
10560 10560                  led->aelta_ret = 0;
10561 10561          } else {
10562 10562                  led->aelta_ret = EIO;
10563 10563                  led->aelta_ctl->ahcictl_em_flags |= AHCI_EM_TIMEOUT;
10564 10564          }
10565 10565          led->aelta_ref--;
10566 10566          if (led->aelta_ref > 0) {
10567 10567                  cv_signal(&led->aelta_cv);
10568 10568          } else {
10569 10569                  cleanup = B_TRUE;
10570 10570          }
10571 10571          mutex_exit(&led->aelta_ctl->ahcictl_mutex);
10572 10572  
10573 10573          if (cleanup) {
10574 10574                  ahci_em_led_task_free(led);
10575 10575          }
10576 10576  }
10577 10577  
10578 10578  static void
10579 10579  ahci_em_reset(void *arg)
10580 10580  {
10581 10581          uint_t i, max_delay = ahci_em_reset_delay_count;
10582 10582          ahci_ctl_t *ahci_ctlp = arg;
10583 10583  
10584 10584          /*
10585 10585           * We've been asked to reset the device. The caller should have set the
10586 10586           * resetting flag. Make sure that we don't have a request to quiesce.
10587 10587           */
10588 10588          mutex_enter(&ahci_ctlp->ahcictl_mutex);
10589 10589          ASSERT(ahci_ctlp->ahcictl_em_flags & AHCI_EM_RESETTING);
10590 10590          if (ahci_ctlp->ahcictl_em_flags & AHCI_EM_QUIESCE) {
10591 10591                  ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_RESETTING;
10592 10592                  mutex_exit(&ahci_ctlp->ahcictl_mutex);
10593 10593                  return;
10594 10594          }
10595 10595          mutex_exit(&ahci_ctlp->ahcictl_mutex);
10596 10596  
10597 10597          ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
10598 10598              (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp), AHCI_HBA_EM_CTL_CTL_RST);
10599 10599          for (i = 0; i < max_delay; i++) {
10600 10600                  uint32_t val;
10601 10601  
10602 10602                  val = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
10603 10603                      (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp));
10604 10604                  if ((val & AHCI_HBA_EM_CTL_CTL_RST) == 0)
10605 10605                          break;
10606 10606  
10607 10607                  delay(drv_usectohz(ahci_em_reset_delay_ms * 1000));
10608 10608          }
10609 10609  
10610 10610          if (i == max_delay) {
10611 10611                  mutex_enter(&ahci_ctlp->ahcictl_mutex);
10612 10612                  ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_RESETTING;
10613 10613                  ahci_ctlp->ahcictl_em_flags |= AHCI_EM_TIMEOUT;
10614 10614                  mutex_exit(&ahci_ctlp->ahcictl_mutex);
10615 10615                  cmn_err(CE_WARN, "!ahci%d: enclosure timed out resetting",
10616 10616                      ddi_get_instance(ahci_ctlp->ahcictl_dip));
10617 10617                  return;
10618 10618          }
10619 10619  
10620 10620          for (i = 0; i < ahci_ctlp->ahcictl_num_ports; i++) {
10621 10621  
10622 10622                  if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, i))
10623 10623                          continue;
10624 10624  
10625 10625                  /*
10626 10626                   * Try to flush all the LEDs as part of reset. If it fails,
10627 10627                   * drive on.
10628 10628                   */
10629 10629                  if (!ahci_em_set_led(ahci_ctlp, i,
10630 10630                      ahci_ctlp->ahcictl_em_state[i])) {
10631 10631                          mutex_enter(&ahci_ctlp->ahcictl_mutex);
10632 10632                          ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_RESETTING;
10633 10633                          ahci_ctlp->ahcictl_em_flags |= AHCI_EM_TIMEOUT;
10634 10634                          mutex_exit(&ahci_ctlp->ahcictl_mutex);
10635 10635                          cmn_err(CE_WARN, "!ahci%d: enclosure timed out "
10636 10636                              "setting port %u",
10637 10637                              ddi_get_instance(ahci_ctlp->ahcictl_dip), i);
10638 10638                          return;
10639 10639                  }
10640 10640          }
10641 10641  
10642 10642          mutex_enter(&ahci_ctlp->ahcictl_mutex);
10643 10643          ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_RESETTING;
10644 10644          ahci_ctlp->ahcictl_em_flags |= AHCI_EM_READY;
10645 10645          mutex_exit(&ahci_ctlp->ahcictl_mutex);
10646 10646  }
10647 10647  
10648 10648  static boolean_t
10649 10649  ahci_em_init(ahci_ctl_t *ahci_ctlp)
10650 10650  {
10651 10651          char name[128];
10652 10652  
10653 10653          /*
10654 10654           * First make sure we actually have enclosure services and if so, that
10655 10655           * we have the hardware support that we care about for this.
10656 10656           */
10657 10657          if (ahci_ctlp->ahcictl_em_loc == 0 ||
10658 10658              (ahci_ctlp->ahcictl_em_ctl & AHCI_HBA_EM_CTL_SUPP_LED) == 0)
10659 10659                  return (B_TRUE);
10660 10660  
10661 10661          /*
10662 10662           * Next, make sure that the buffer is large enough for us. We need two
10663 10663           * dwords or 8 bytes. The location register is stored in dwords.
10664 10664           */
10665 10665          if ((ahci_ctlp->ahcictl_em_loc & AHCI_HBA_EM_LOC_SZ_MASK) <
10666 10666              AHCI_EM_BUFFER_MIN) {
10667 10667                  return (B_TRUE);
10668 10668          }
10669 10669  
10670 10670          ahci_ctlp->ahcictl_em_tx_off = ((ahci_ctlp->ahcictl_em_loc &
10671 10671              AHCI_HBA_EM_LOC_OFST_MASK) >> AHCI_HBA_EM_LOC_OFST_SHIFT) * 4;
10672 10672          ahci_ctlp->ahcictl_em_tx_off += ahci_ctlp->ahcictl_ahci_addr;
10673 10673  
10674 10674          bzero(ahci_ctlp->ahcictl_em_state,
10675 10675              sizeof (ahci_ctlp->ahcictl_em_state));
10676 10676  
10677 10677          (void) snprintf(name, sizeof (name), "ahcti_em_taskq%d",
10678 10678              ddi_get_instance(ahci_ctlp->ahcictl_dip));
10679 10679          if ((ahci_ctlp->ahcictl_em_taskq =
10680 10680              ddi_taskq_create(ahci_ctlp->ahcictl_dip, name, 1,
10681 10681              TASKQ_DEFAULTPRI, 0)) == NULL) {
10682 10682                  cmn_err(CE_WARN, "!ahci%d: ddi_tasq_create failed for em "
10683 10683                      "services", ddi_get_instance(ahci_ctlp->ahcictl_dip));
10684 10684                  return (B_FALSE);
10685 10685          }
10686 10686  
10687 10687          mutex_enter(&ahci_ctlp->ahcictl_mutex);
10688 10688          ahci_ctlp->ahcictl_em_flags |= AHCI_EM_PRESENT | AHCI_EM_RESETTING;
10689 10689          mutex_exit(&ahci_ctlp->ahcictl_mutex);
10690 10690          (void) ddi_taskq_dispatch(ahci_ctlp->ahcictl_em_taskq, ahci_em_reset,
10691 10691              ahci_ctlp, DDI_SLEEP);
10692 10692  
10693 10693          return (B_TRUE);
10694 10694  }
10695 10695  
10696 10696  static int
10697 10697  ahci_em_ioctl_get(ahci_ctl_t *ahci_ctlp, intptr_t arg)
10698 10698  {
10699 10699          int i;
10700 10700          ahci_ioc_em_get_t get;
10701 10701  
10702 10702          if ((ahci_ctlp->ahcictl_em_flags & AHCI_EM_PRESENT) == 0) {
10703 10703                  return (ENOTSUP);
10704 10704          }
10705 10705  
10706 10706          bzero(&get, sizeof (get));
10707 10707          get.aiemg_nports = ahci_ctlp->ahcictl_ports_implemented;
10708 10708          if ((ahci_ctlp->ahcictl_em_ctl & AHCI_HBA_EM_CTL_ATTR_ALHD) == 0) {
10709 10709                  get.aiemg_flags |= AHCI_EM_FLAG_CONTROL_ACTIVITY;
10710 10710          }
10711 10711  
10712 10712          mutex_enter(&ahci_ctlp->ahcictl_mutex);
10713 10713          for (i = 0; i < ahci_ctlp->ahcictl_num_ports; i++) {
10714 10714                  if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, i)) {
10715 10715                          continue;
10716 10716                  }
10717 10717                  get.aiemg_status[i] = ahci_ctlp->ahcictl_em_state[i];
10718 10718          }
10719 10719          mutex_exit(&ahci_ctlp->ahcictl_mutex);
10720 10720  
10721 10721          if (ddi_copyout(&get, (void *)arg, sizeof (get), 0) != 0)
10722 10722                  return (EFAULT);
10723 10723  
10724 10724          return (0);
10725 10725  }
10726 10726  
10727 10727  static int
10728 10728  ahci_em_ioctl_set(ahci_ctl_t *ahci_ctlp, intptr_t arg)
10729 10729  {
10730 10730          int ret;
10731 10731          ahci_ioc_em_set_t set;
10732 10732          ahci_em_led_task_arg_t *task;
10733 10733          boolean_t signal, cleanup;
10734 10734  
10735 10735          if (ddi_copyin((void *)arg, &set, sizeof (set), 0) != 0)
10736 10736                  return (EFAULT);
10737 10737  
10738 10738          if (set.aiems_port > ahci_ctlp->ahcictl_num_ports)
10739 10739                  return (EINVAL);
10740 10740  
10741 10741          if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, set.aiems_port)) {
10742 10742                  return (EINVAL);
10743 10743          }
10744 10744  
10745 10745          if ((set.aiems_leds & ~(AHCI_EM_LED_IDENT_ENABLE |
10746 10746              AHCI_EM_LED_FAULT_ENABLE |
10747 10747              AHCI_EM_LED_ACTIVITY_DISABLE)) != 0) {
10748 10748                  return (EINVAL);
10749 10749          }
10750 10750  
10751 10751          switch (set.aiems_op) {
10752 10752          case AHCI_EM_IOC_SET_OP_ADD:
10753 10753          case AHCI_EM_IOC_SET_OP_REM:
10754 10754          case AHCI_EM_IOC_SET_OP_SET:
10755 10755                  break;
10756 10756          default:
10757 10757                  return (EINVAL);
10758 10758          }
  
    | 
      ↓ open down ↓ | 
    10758 lines elided | 
    
      ↑ open up ↑ | 
  
10759 10759  
10760 10760          if ((ahci_ctlp->ahcictl_em_flags & AHCI_EM_PRESENT) == 0) {
10761 10761                  return (ENOTSUP);
10762 10762          }
10763 10763  
10764 10764          if ((set.aiems_leds & AHCI_EM_LED_ACTIVITY_DISABLE) != 0 &&
10765 10765              ((ahci_ctlp->ahcictl_em_ctl & AHCI_HBA_EM_CTL_ATTR_ALHD) != 0)) {
10766 10766                  return (ENOTSUP);
10767 10767          }
10768 10768  
10769      -        task = kmem_alloc(sizeof (*task), KM_NOSLEEP | KM_NORMALPRI);
     10769 +        task = kmem_alloc(sizeof (*task), KM_NOSLEEP_LAZY);
10770 10770          if (task == NULL) {
10771 10771                  return (ENOMEM);
10772 10772          }
10773 10773  
10774 10774          task->aelta_ctl = ahci_ctlp;
10775 10775          task->aelta_port = (uint8_t)set.aiems_port;
10776 10776          task->aelta_op = set.aiems_op;
10777 10777          task->aelta_state = set.aiems_leds;
10778 10778  
10779 10779          cv_init(&task->aelta_cv, NULL, CV_DRIVER, NULL);
10780 10780  
10781 10781          /*
10782 10782           * Initialize the reference count to two. One for us and one for the
10783 10783           * taskq. This will be used in case we get canceled.
10784 10784           */
10785 10785          task->aelta_ref = 2;
10786 10786  
10787 10787          /*
10788 10788           * Once dispatched, the task state is protected by our global mutex.
10789 10789           */
10790 10790          (void) ddi_taskq_dispatch(ahci_ctlp->ahcictl_em_taskq,
10791 10791              ahci_em_led_task, task, DDI_SLEEP);
10792 10792  
10793 10793          signal = B_FALSE;
10794 10794          mutex_enter(&ahci_ctlp->ahcictl_mutex);
10795 10795          while (task->aelta_ref > 1) {
10796 10796                  if (cv_wait_sig(&task->aelta_cv, &ahci_ctlp->ahcictl_mutex) ==
10797 10797                      0) {
10798 10798                          signal = B_TRUE;
10799 10799                          break;
10800 10800                  }
10801 10801          }
10802 10802  
10803 10803          /*
10804 10804           * Remove our reference count. If we were woken up because of a signal
10805 10805           * then the taskq may still be dispatched. In which case we shouldn't
10806 10806           * free this memory until it is done. In that case, the taskq will take
10807 10807           * care of it.
10808 10808           */
10809 10809          task->aelta_ref--;
10810 10810          cleanup = (task->aelta_ref == 0);
10811 10811          if (signal) {
10812 10812                  ret = EINTR;
10813 10813          } else {
10814 10814                  ret = task->aelta_ret;
10815 10815          }
10816 10816          mutex_exit(&ahci_ctlp->ahcictl_mutex);
10817 10817  
10818 10818          if (cleanup) {
10819 10819                  ahci_em_led_task_free(task);
10820 10820          }
10821 10821  
10822 10822          return (ret);
10823 10823  }
10824 10824  
10825 10825  static int
10826 10826  ahci_em_ioctl(dev_info_t *dip, int cmd, intptr_t arg)
10827 10827  {
10828 10828          int inst;
10829 10829          ahci_ctl_t *ahci_ctlp;
10830 10830  
10831 10831          inst = ddi_get_instance(dip);
10832 10832          if ((ahci_ctlp = ddi_get_soft_state(ahci_statep, inst)) == NULL) {
10833 10833                  return (ENXIO);
10834 10834          }
10835 10835  
10836 10836          switch (cmd) {
10837 10837          case AHCI_EM_IOC_GET:
10838 10838                  return (ahci_em_ioctl_get(ahci_ctlp, arg));
10839 10839          case AHCI_EM_IOC_SET:
10840 10840                  return (ahci_em_ioctl_set(ahci_ctlp, arg));
10841 10841          default:
10842 10842                  return (ENOTTY);
10843 10843          }
10844 10844  
10845 10845  }
10846 10846  
10847 10847  static void
10848 10848  ahci_em_quiesce(ahci_ctl_t *ahci_ctlp)
10849 10849  {
10850 10850          mutex_enter(&ahci_ctlp->ahcictl_mutex);
10851 10851          if ((ahci_ctlp->ahcictl_em_flags & AHCI_EM_PRESENT) == 0) {
10852 10852                  mutex_exit(&ahci_ctlp->ahcictl_mutex);
10853 10853                  return;
10854 10854          }
10855 10855          ahci_ctlp->ahcictl_em_flags |= AHCI_EM_QUIESCE;
10856 10856          mutex_exit(&ahci_ctlp->ahcictl_mutex);
10857 10857  
10858 10858          ddi_taskq_wait(ahci_ctlp->ahcictl_em_taskq);
10859 10859  }
10860 10860  
10861 10861  static void
10862 10862  ahci_em_suspend(ahci_ctl_t *ahci_ctlp)
10863 10863  {
10864 10864          ahci_em_quiesce(ahci_ctlp);
10865 10865  
10866 10866          mutex_enter(&ahci_ctlp->ahcictl_mutex);
10867 10867          ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_READY;
10868 10868          mutex_exit(&ahci_ctlp->ahcictl_mutex);
10869 10869  }
10870 10870  
10871 10871  static void
10872 10872  ahci_em_resume(ahci_ctl_t *ahci_ctlp)
10873 10873  {
10874 10874          mutex_enter(&ahci_ctlp->ahcictl_mutex);
10875 10875          if ((ahci_ctlp->ahcictl_em_flags & AHCI_EM_PRESENT) == 0) {
10876 10876                  mutex_exit(&ahci_ctlp->ahcictl_mutex);
10877 10877                  return;
10878 10878          }
10879 10879          ahci_ctlp->ahcictl_em_flags |= AHCI_EM_RESETTING;
10880 10880          mutex_exit(&ahci_ctlp->ahcictl_mutex);
10881 10881  
10882 10882          (void) ddi_taskq_dispatch(ahci_ctlp->ahcictl_em_taskq, ahci_em_reset,
10883 10883              ahci_ctlp, DDI_SLEEP);
10884 10884  }
10885 10885  
10886 10886  static void
10887 10887  ahci_em_fini(ahci_ctl_t *ahci_ctlp)
10888 10888  {
10889 10889          if ((ahci_ctlp->ahcictl_em_flags & AHCI_EM_PRESENT) == 0) {
10890 10890                  return;
10891 10891          }
10892 10892  
10893 10893          ahci_em_quiesce(ahci_ctlp);
10894 10894          ddi_taskq_destroy(ahci_ctlp->ahcictl_em_taskq);
10895 10895          ahci_ctlp->ahcictl_em_taskq = NULL;
10896 10896  }
  
    | 
      ↓ open down ↓ | 
    117 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX