1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 
  27 /*
  28  * SiliconImage 3124/3132/3531 sata controller driver
  29  */
  30 
  31 /*
  32  *
  33  *
  34  *                      Few Design notes
  35  *
  36  *
  37  * I. General notes
  38  *
  39  * Even though the driver is named as si3124, it is actually meant to
  40  * work with SiI3124, SiI3132 and SiI3531 controllers.
  41  *
  42  * The current file si3124.c is the main driver code. The si3124reg.h
  43  * holds the register definitions from SiI 3124/3132/3531 data sheets. The
  44  * si3124var.h holds the driver specific definitions which are not
  45  * directly derived from data sheets.
  46  *
  47  *
  48  * II. Data structures
  49  *
  50  * si_ctl_state_t: This holds the driver private information for each
  51  *      controller instance. Each of the sata ports within a single
  52  *      controller are represented by si_port_state_t. The
  53  *      sictl_global_acc_handle and sictl_global_address map the
  54  *      controller-wide global register space and are derived from pci
  55  *      BAR 0. The sictl_port_acc_handle and sictl_port_addr map the
  56  *      per-port register space and are derived from pci BAR 1.
  57  *
  58  * si_port_state_t: This holds the per port information. The siport_mutex
  59  *      holds the per port mutex. The siport_pending_tags is the bit mask of
  60  *      commands posted to controller. The siport_slot_pkts[] holds the
  61  *      pending sata packets. The siport_port_type holds the device type
  62  *      connected directly to the port while the siport_portmult_state
  63  *      holds the similar information for the devices behind a port
  64  *      multiplier.
  65  *
  66  * si_prb_t: This contains the PRB being posted to the controller.
  67  *      The two SGE entries contained within si_prb_t itself are not
  68  *      really used to hold any scatter gather entries. The scatter gather
  69  *      list is maintained external to PRB and is linked from one
  70  *      of the contained SGEs inside the PRB. For atapi devices, the
  71  *      first contained SGE holds the PACKET and second contained
  72  *      SGE holds the link to an external SGT. For non-atapi devices,
  73  *      the first contained SGE works as link to external SGT while
  74  *      second SGE is blank.
  75  *
  76  * external SGT tables: The external SGT tables pointed to from
  77  *      within si_prb_t are actually abstracted as si_sgblock_t. Each
  78  *      si_sgblock_t contains si_dma_sg_number number of
  79  *      SGT tables linked in a chain. Currently this default value of
  80  *      SGT tables per block is at 85 as  which translates
  81  *      to a maximum of 256 dma cookies per single dma transfer.
  82  *      This value can be changed through the global var: si_dma_sg_number
  83  *      in /etc/system, the maxium is at 21844 as which translates to 65535
  84  *      dma cookies per single dma transfer.
  85  *
  86  *
  87  * III. Driver operation
  88  *
  89  * Command Issuing: We use the "indirect method of command issuance". The
  90  *      PRB contains the command [and atapi PACKET] and a link to the
  91  *      external SGT chain. We write the physical address of the PRB into
  92  *      command activation register. There are 31 command slots for
  93  *      each port. After posting a command, we remember the posted slot &
  94  *      the sata packet in siport_pending_tags & siport_slot_pkts[]
  95  *      respectively.
  96  *
  97  * Command completion: On a successful completion, intr_command_complete()
  98  *      receives the control. The slot_status register holds the outstanding
  99  *      commands. Any reading of slot_status register automatically clears
 100  *      the interrupt. By comparing the slot_status register contents with
 101  *      per port siport_pending_tags, we determine which of the previously
 102  *      posted commands have finished.
 103  *
 104  * Timeout handling: Every 5 seconds, the watchdog handler scans thru the
 105  *      pending packets. The satapkt->satapkt_hba_driver_private field is
 106  *      overloaded with the count of watchdog cycles a packet has survived.
 107  *      If a packet has not completed within satapkt->satapkt_time, it is
 108  *      failed with error code of SATA_PKT_TIMEOUT. There is one watchdog
 109  *      handler running for each instance of controller.
 110  *
 111  * Error handling: For 3124, whenever any single command has encountered
 112  *      an error, the whole port execution completely stalls; there is no
 113  *      way of canceling or aborting the particular failed command. If
 114  *      the port is connected to a port multiplier, we can however RESUME
 115  *      other non-error devices connected to the port multiplier.
 116  *      The only way to recover the failed commands is to either initialize
 117  *      the port or reset the port/device. Both port initialize and reset
 118  *      operations result in discarding any of pending commands on the port.
 119  *      All such discarded commands are sent up to framework with PKT_RESET
 120  *      satapkt_reason. The assumption is that framework [and sd] would
 121  *      retry these commands again. The failed command itself however is
 122  *      sent up with PKT_DEV_ERROR.
 123  *
 124  *      Here is the implementation strategy based on SiliconImage email
 125  *      regarding how they handle the errors for their Windows driver:
 126  *
 127  *        a) for DEVICEERROR:
 128  *              If the port is connected to port multiplier, then
 129  *               1) Resume the port
 130  *               2) Wait for all the non-failed commands to complete
 131  *               3) Perform a Port Initialize
 132  *
 133  *              If the port is not connected to port multiplier, issue
 134  *              a Port Initialize.
 135  *
 136  *        b) for SDBERROR: [SDBERROR means failed command is an NCQ command]
 137  *              Handle exactly like DEVICEERROR handling.
 138  *              After the Port Initialize done, do a Read Log Extended.
 139  *
 140  *        c) for SENDFISERROR:
 141  *              If the port is connected to port multiplier, then
 142  *               1) Resume the port
 143  *               2) Wait for all the non-failed commands to complete
 144  *               3) Perform a Port Initialize
 145  *
 146  *              If the port is not connected to port multiplier, issue
 147  *              a Device Reset.
 148  *
 149  *        d) for DATAFISERROR:
 150  *              If the port was executing an NCQ command, issue a Device
 151  *              Reset.
 152  *
 153  *              Otherwise, follow the same error recovery as DEVICEERROR.
 154  *
 155  *        e) for any other error, simply issue a Device Reset.
 156  *
 157  *      To synchronize the interactions between various control flows (e.g.
 158  *      error recovery, timeout handling, si_poll_timeout, incoming flow
 159  *      from framework etc.), the following precautions are taken care of:
 160  *              a) During mopping_in_progress, no more commands are
 161  *              accepted from the framework.
 162  *
 163  *              b) While draining the port multiplier commands, we should
 164  *              handle the possibility of any of the other waited commands
 165  *              failing (possibly with a different error code)
 166  *
 167  * Atapi handling: For atapi devices, we use the first SGE within the PRB
 168  *      to fill the scsi cdb while the second SGE points to external SGT.
 169  *
 170  * Queuing: Queue management is achieved external to the driver inside sd.
 171  *      Based on sata_hba_tran->qdepth and IDENTIFY data, the framework
 172  *      enables or disables the queuing. The qdepth for si3124 is 31
 173  *      commands.
 174  *
 175  * Port Multiplier: Enumeration of port multiplier is handled during the
 176  *      controller initialization and also during the a hotplug operation.
 177  *      Current logic takes care of situation where a port multiplier
 178  *      is hotplugged into a port which had a cdisk connected previously
 179  *      and vice versa.
 180  *
 181  * Register poll timeouts: Currently most of poll timeouts on register
 182  *      reads is set to 0.5 seconds except for a value of 10 seconds
 183  *      while reading the device signature. [Such a big timeout values
 184  *      for device signature were found needed during cold reboots
 185  *      for devices behind port multiplier].
 186  *
 187  *
 188  * IV. Known Issues
 189  *
 190  * 1) Currently the atapi packet length is hard coded to 12 bytes
 191  *      This is wrong. The framework should determine it just like they
 192  *      determine ad_cdb_len in legacy atapi.c. It should even reject
 193  *      init_pkt() for greater CDB lengths. See atapi.c. Revisit this
 194  *      in 2nd phase of framework project.
 195  *
 196  * 2) Do real REQUEST SENSE command instead of faking for ATAPI case.
 197  *
 198  */
 199 
 200 
 201 #include <sys/note.h>
 202 #include <sys/scsi/scsi.h>
 203 #include <sys/pci.h>
 204 #include <sys/sata/sata_hba.h>
 205 #include <sys/sata/adapters/si3124/si3124reg.h>
 206 #include <sys/sata/adapters/si3124/si3124var.h>
 207 #include <sys/sdt.h>
 208 
 209 /*
 210  * FMA header files
 211  */
 212 #include <sys/ddifm.h>
 213 #include <sys/fm/protocol.h>
 214 #include <sys/fm/util.h>
 215 #include <sys/fm/io/ddi.h>
 216 
 217 /*
 218  * Function prototypes for driver entry points
 219  */
 220 static  int si_attach(dev_info_t *, ddi_attach_cmd_t);
 221 static  int si_detach(dev_info_t *, ddi_detach_cmd_t);
 222 static  int si_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
 223 static  int si_power(dev_info_t *, int, int);
 224 static  int si_quiesce(dev_info_t *);
 225 /*
 226  * Function prototypes for SATA Framework interfaces
 227  */
 228 static  int si_register_sata_hba_tran(si_ctl_state_t *);
 229 static  int si_unregister_sata_hba_tran(si_ctl_state_t *);
 230 
 231 static  int si_tran_probe_port(dev_info_t *, sata_device_t *);
 232 static  int si_tran_start(dev_info_t *, sata_pkt_t *spkt);
 233 static  int si_tran_abort(dev_info_t *, sata_pkt_t *, int);
 234 static  int si_tran_reset_dport(dev_info_t *, sata_device_t *);
 235 static  int si_tran_hotplug_port_activate(dev_info_t *, sata_device_t *);
 236 static  int si_tran_hotplug_port_deactivate(dev_info_t *, sata_device_t *);
 237 
 238 /*
 239  * Local function prototypes
 240  */
 241 
 242 static  int si_alloc_port_state(si_ctl_state_t *, int);
 243 static  void si_dealloc_port_state(si_ctl_state_t *, int);
 244 static  int si_alloc_sgbpool(si_ctl_state_t *, int);
 245 static  void si_dealloc_sgbpool(si_ctl_state_t *, int);
 246 static  int si_alloc_prbpool(si_ctl_state_t *, int);
 247 static  void si_dealloc_prbpool(si_ctl_state_t *, int);
 248 
 249 static void si_find_dev_signature(si_ctl_state_t *, si_port_state_t *,
 250                                                 int, int);
 251 static void si_poll_cmd(si_ctl_state_t *, si_port_state_t *, int, int,
 252                                                 sata_pkt_t *);
 253 static  int si_claim_free_slot(si_ctl_state_t *, si_port_state_t *, int);
 254 static  int si_deliver_satapkt(si_ctl_state_t *, si_port_state_t *, int,
 255                                                 sata_pkt_t *);
 256 
 257 static  int si_initialize_controller(si_ctl_state_t *);
 258 static  void si_deinitialize_controller(si_ctl_state_t *);
 259 static void si_init_port(si_ctl_state_t *, int);
 260 static  int si_enumerate_port_multiplier(si_ctl_state_t *,
 261                                                 si_port_state_t *, int);
 262 static int si_read_portmult_reg(si_ctl_state_t *, si_port_state_t *,
 263                                                 int, int, int, uint32_t *);
 264 static int si_write_portmult_reg(si_ctl_state_t *, si_port_state_t *,
 265                                                 int, int, int, uint32_t);
 266 static void si_set_sense_data(sata_pkt_t *, int);
 267 
 268 static uint_t si_intr(caddr_t, caddr_t);
 269 static int si_intr_command_complete(si_ctl_state_t *,
 270                                         si_port_state_t *, int);
 271 static void si_schedule_intr_command_error(si_ctl_state_t *,
 272                                         si_port_state_t *, int);
 273 static void si_do_intr_command_error(void *);
 274 static int si_intr_command_error(si_ctl_state_t *,
 275                                         si_port_state_t *, int);
 276 static void si_error_recovery_DEVICEERROR(si_ctl_state_t *,
 277                                         si_port_state_t *, int);
 278 static void si_error_recovery_SDBERROR(si_ctl_state_t *,
 279                                         si_port_state_t *, int);
 280 static void si_error_recovery_DATAFISERROR(si_ctl_state_t *,
 281                                         si_port_state_t *, int);
 282 static void si_error_recovery_SENDFISERROR(si_ctl_state_t *,
 283                                         si_port_state_t *, int);
 284 static void si_error_recovery_default(si_ctl_state_t *,
 285                                         si_port_state_t *, int);
 286 static uint8_t si_read_log_ext(si_ctl_state_t *,
 287                                         si_port_state_t *si_portp, int);
 288 static void si_log_error_message(si_ctl_state_t *, int, uint32_t);
 289 static int si_intr_port_ready(si_ctl_state_t *, si_port_state_t *, int);
 290 static int si_intr_pwr_change(si_ctl_state_t *, si_port_state_t *, int);
 291 static int si_intr_phy_ready_change(si_ctl_state_t *, si_port_state_t *, int);
 292 static int si_intr_comwake_rcvd(si_ctl_state_t *, si_port_state_t *, int);
 293 static int si_intr_unrecognised_fis(si_ctl_state_t *, si_port_state_t *, int);
 294 static int si_intr_dev_xchanged(si_ctl_state_t *, si_port_state_t *, int);
 295 static int si_intr_decode_err_threshold(si_ctl_state_t *,
 296                                         si_port_state_t *, int);
 297 static int si_intr_crc_err_threshold(si_ctl_state_t *, si_port_state_t *, int);
 298 static int si_intr_handshake_err_threshold(si_ctl_state_t *,
 299                                         si_port_state_t *, int);
 300 static int si_intr_set_devbits_notify(si_ctl_state_t *, si_port_state_t *, int);
 301 
 302 static  void si_enable_port_interrupts(si_ctl_state_t *, int);
 303 static  void si_enable_all_interrupts(si_ctl_state_t *);
 304 static  void si_disable_port_interrupts(si_ctl_state_t *, int);
 305 static  void si_disable_all_interrupts(si_ctl_state_t *);
 306 static  void fill_dev_sregisters(si_ctl_state_t *, int, sata_device_t *);
 307 static  int si_add_legacy_intrs(si_ctl_state_t *);
 308 static  int si_add_msi_intrs(si_ctl_state_t *);
 309 static  void si_rem_intrs(si_ctl_state_t *);
 310 
 311 static  int si_reset_dport_wait_till_ready(si_ctl_state_t *,
 312                                 si_port_state_t *, int, int);
 313 static int si_clear_port(si_ctl_state_t *, int);
 314 static void si_schedule_port_initialize(si_ctl_state_t *,
 315                                 si_port_state_t *, int);
 316 static void si_do_initialize_port(void *);
 317 static  int si_initialize_port_wait_till_ready(si_ctl_state_t *, int);
 318 
 319 static void si_timeout_pkts(si_ctl_state_t *, si_port_state_t *, int, uint32_t);
 320 static  void si_watchdog_handler(si_ctl_state_t *);
 321 
 322 /*
 323  * FMA Prototypes
 324  */
 325 static void si_fm_init(si_ctl_state_t *);
 326 static void si_fm_fini(si_ctl_state_t *);
 327 static int si_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void *);
 328 static int si_check_acc_handle(ddi_acc_handle_t);
 329 static int si_check_dma_handle(ddi_dma_handle_t);
 330 static int si_check_ctl_handles(si_ctl_state_t *);
 331 static int si_check_port_handles(si_port_state_t *);
 332 static void si_fm_ereport(si_ctl_state_t *, char *, char *);
 333 
 334 static  void si_log(si_ctl_state_t *, si_port_state_t *, char *, ...);
 335 
 336 static void si_copy_out_regs(sata_cmd_t *, si_ctl_state_t *, uint8_t, uint8_t);
 337 
 338 /*
 339  * DMA attributes for the data buffer
 340  */
 341 
 342 static ddi_dma_attr_t buffer_dma_attr = {
 343         DMA_ATTR_V0,            /* dma_attr_version */
 344         0,                      /* dma_attr_addr_lo: lowest bus address */
 345         0xffffffffffffffffull,  /* dma_attr_addr_hi: highest bus address */
 346         0xffffffffull,          /* dma_attr_count_max i.e. for one cookie */
 347         1,                      /* dma_attr_align: single byte aligned */
 348         1,                      /* dma_attr_burstsizes */
 349         1,                      /* dma_attr_minxfer */
 350         0xffffffffull,          /* dma_attr_maxxfer i.e. includes all cookies */
 351         0xffffffffull,          /* dma_attr_seg */
 352         SI_DEFAULT_SGL_LENGTH,  /* dma_attr_sgllen */
 353         512,                    /* dma_attr_granular */
 354         0,                      /* dma_attr_flags */
 355 };
 356 
 357 /*
 358  * DMA attributes for incore RPB and SGT pool
 359  */
 360 static ddi_dma_attr_t prb_sgt_dma_attr = {
 361         DMA_ATTR_V0,            /* dma_attr_version */
 362         0,                      /* dma_attr_addr_lo: lowest bus address */
 363         0xffffffffffffffffull,  /* dma_attr_addr_hi: highest bus address */
 364         0xffffffffull,          /* dma_attr_count_max i.e. for one cookie */
 365         8,                      /* dma_attr_align: quad word aligned */
 366         1,                      /* dma_attr_burstsizes */
 367         1,                      /* dma_attr_minxfer */
 368         0xffffffffull,          /* dma_attr_maxxfer i.e. includes all cookies */
 369         0xffffffffull,          /* dma_attr_seg */
 370         1,                      /* dma_attr_sgllen */
 371         1,                      /* dma_attr_granular */
 372         0,                      /* dma_attr_flags */
 373 };
 374 
 375 /* Device access attributes */
 376 static ddi_device_acc_attr_t accattr = {
 377     DDI_DEVICE_ATTR_V1,
 378     DDI_STRUCTURE_LE_ACC,
 379     DDI_STRICTORDER_ACC,
 380     DDI_DEFAULT_ACC
 381 };
 382 
 383 
 384 static struct dev_ops sictl_dev_ops = {
 385         DEVO_REV,               /* devo_rev */
 386         0,                      /* refcnt  */
 387         si_getinfo,             /* info */
 388         nulldev,                /* identify */
 389         nulldev,                /* probe */
 390         si_attach,              /* attach */
 391         si_detach,              /* detach */
 392         nodev,                  /* no reset */
 393         (struct cb_ops *)0,     /* driver operations */
 394         NULL,                   /* bus operations */
 395         si_power,               /* power */
 396         si_quiesce,             /* devo_quiesce */
 397 };
 398 
 399 static sata_tran_hotplug_ops_t si_tran_hotplug_ops = {
 400         SATA_TRAN_HOTPLUG_OPS_REV_1,
 401         si_tran_hotplug_port_activate,
 402         si_tran_hotplug_port_deactivate
 403 };
 404 
 405 
 406 static int si_watchdog_timeout = 5; /* 5 seconds */
 407 static int si_watchdog_tick;
 408 
 409 extern struct mod_ops mod_driverops;
 410 
 411 static  struct modldrv modldrv = {
 412         &mod_driverops,     /* driverops */
 413         "si3124 driver",
 414         &sictl_dev_ops,     /* driver ops */
 415 };
 416 
 417 static  struct modlinkage modlinkage = {
 418         MODREV_1,
 419         &modldrv,
 420         NULL
 421 };
 422 
 423 
 424 /* The following are needed for si_log() */
 425 static kmutex_t si_log_mutex;
 426 static char si_log_buf[SI_LOGBUF_LEN];
 427 uint32_t si_debug_flags =
 428     SIDBG_ERRS|SIDBG_INIT|SIDBG_EVENT|SIDBG_TIMEOUT|SIDBG_RESET;
 429 
 430 static int is_msi_supported = 0;
 431 
 432 /*
 433  * The below global variables are tunable via /etc/system
 434  *
 435  * si_dma_sg_number
 436  */
 437 
 438 int si_dma_sg_number = SI_DEFAULT_SGT_TABLES_PER_PRB;
 439 
 440 /* Opaque state pointer to be initialized by ddi_soft_state_init() */
 441 static void *si_statep  = NULL;
 442 
 443 /*
 444  *  si3124 module initialization.
 445  *
 446  */
 447 int
 448 _init(void)
 449 {
 450         int     error;
 451 
 452         error = ddi_soft_state_init(&si_statep, sizeof (si_ctl_state_t), 0);
 453         if (error != 0) {
 454                 return (error);
 455         }
 456 
 457         mutex_init(&si_log_mutex, NULL, MUTEX_DRIVER, NULL);
 458 
 459         if ((error = sata_hba_init(&modlinkage)) != 0) {
 460                 mutex_destroy(&si_log_mutex);
 461                 ddi_soft_state_fini(&si_statep);
 462                 return (error);
 463         }
 464 
 465         error = mod_install(&modlinkage);
 466         if (error != 0) {
 467                 sata_hba_fini(&modlinkage);
 468                 mutex_destroy(&si_log_mutex);
 469                 ddi_soft_state_fini(&si_statep);
 470                 return (error);
 471         }
 472 
 473         si_watchdog_tick = drv_usectohz((clock_t)si_watchdog_timeout * 1000000);
 474 
 475         return (error);
 476 }
 477 
 478 /*
 479  * si3124 module uninitialize.
 480  *
 481  */
 482 int
 483 _fini(void)
 484 {
 485         int     error;
 486 
 487         error = mod_remove(&modlinkage);
 488         if (error != 0) {
 489                 return (error);
 490         }
 491 
 492         /* Remove the resources allocated in _init(). */
 493         sata_hba_fini(&modlinkage);
 494         mutex_destroy(&si_log_mutex);
 495         ddi_soft_state_fini(&si_statep);
 496 
 497         return (error);
 498 }
 499 
 500 /*
 501  * _info entry point
 502  *
 503  */
 504 int
 505 _info(struct modinfo *modinfop)
 506 {
 507         return (mod_info(&modlinkage, modinfop));
 508 }
 509 
 510 
 511 /*
 512  * The attach entry point for dev_ops.
 513  *
 514  * We initialize the controller, initialize the soft state, register
 515  * the interrupt handlers and then register ourselves with sata framework.
 516  */
 517 static int
 518 si_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 519 {
 520         si_ctl_state_t *si_ctlp;
 521         int instance;
 522         int status;
 523         int attach_state;
 524         int intr_types;
 525         sata_device_t sdevice;
 526 
 527         SIDBG(SIDBG_ENTRY, "si_attach enter", NULL);
 528         instance = ddi_get_instance(dip);
 529         attach_state = ATTACH_PROGRESS_NONE;
 530 
 531         switch (cmd) {
 532 
 533         case DDI_ATTACH:
 534 
 535                 /* Allocate si_softc. */
 536                 status = ddi_soft_state_zalloc(si_statep, instance);
 537                 if (status != DDI_SUCCESS) {
 538                         goto err_out;
 539                 }
 540 
 541                 si_ctlp = ddi_get_soft_state(si_statep, instance);
 542                 si_ctlp->sictl_devinfop = dip;
 543 
 544                 attach_state |= ATTACH_PROGRESS_STATEP_ALLOC;
 545 
 546                 /* Initialize FMA */
 547                 si_ctlp->fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, dip,
 548                     DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable",
 549                     DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
 550                     DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
 551 
 552                 si_fm_init(si_ctlp);
 553 
 554                 attach_state |= ATTACH_PROGRESS_INIT_FMA;
 555 
 556                 /* Configure pci config space handle. */
 557                 status = pci_config_setup(dip, &si_ctlp->sictl_pci_conf_handle);
 558                 if (status != DDI_SUCCESS) {
 559                         goto err_out;
 560                 }
 561 
 562                 si_ctlp->sictl_devid =
 563                     pci_config_get16(si_ctlp->sictl_pci_conf_handle,
 564                     PCI_CONF_DEVID);
 565                 switch (si_ctlp->sictl_devid) {
 566                         case SI3124_DEV_ID:
 567                                 si_ctlp->sictl_num_ports = SI3124_MAX_PORTS;
 568                                 break;
 569 
 570                         case SI3132_DEV_ID:
 571                                 si_ctlp->sictl_num_ports = SI3132_MAX_PORTS;
 572                                 break;
 573 
 574                         case SI3531_DEV_ID:
 575                                 si_ctlp->sictl_num_ports = SI3531_MAX_PORTS;
 576                                 break;
 577 
 578                         default:
 579                                 /*
 580                                  * Driver should not have attatched if device
 581                                  * ID is not already known and is supported.
 582                                  */
 583                                 goto err_out;
 584                 }
 585 
 586                 attach_state |= ATTACH_PROGRESS_CONF_HANDLE;
 587 
 588                 /* Now map the bar0; the bar0 contains the global registers. */
 589                 status = ddi_regs_map_setup(dip,
 590                     PCI_BAR0,
 591                     (caddr_t *)&si_ctlp->sictl_global_addr,
 592                     0,
 593                     0,
 594                     &accattr,
 595                     &si_ctlp->sictl_global_acc_handle);
 596                 if (status != DDI_SUCCESS) {
 597                         goto err_out;
 598                 }
 599 
 600                 attach_state |= ATTACH_PROGRESS_BAR0_MAP;
 601 
 602                 /* Now map bar1; the bar1 contains the port registers. */
 603                 status = ddi_regs_map_setup(dip,
 604                     PCI_BAR1,
 605                     (caddr_t *)&si_ctlp->sictl_port_addr,
 606                     0,
 607                     0,
 608                     &accattr,
 609                     &si_ctlp->sictl_port_acc_handle);
 610                 if (status != DDI_SUCCESS) {
 611                         goto err_out;
 612                 }
 613 
 614                 attach_state |= ATTACH_PROGRESS_BAR1_MAP;
 615 
 616                 /*
 617                  * Disable all the interrupts before adding interrupt
 618                  * handler(s). The interrupts shall be re-enabled selectively
 619                  * out of si_init_port().
 620                  */
 621                 si_disable_all_interrupts(si_ctlp);
 622 
 623                 /* Get supported interrupt types. */
 624                 if (ddi_intr_get_supported_types(dip, &intr_types)
 625                     != DDI_SUCCESS) {
 626                         SIDBG_C(SIDBG_INIT, si_ctlp,
 627                             "ddi_intr_get_supported_types failed", NULL);
 628                         goto err_out;
 629                 }
 630 
 631                 SIDBG_C(SIDBG_INIT, si_ctlp,
 632                     "ddi_intr_get_supported_types() returned: 0x%x",
 633                     intr_types);
 634 
 635                 if (is_msi_supported && (intr_types & DDI_INTR_TYPE_MSI)) {
 636                         SIDBG_C(SIDBG_INIT, si_ctlp,
 637                             "Using MSI interrupt type", NULL);
 638 
 639                         /*
 640                          * Try MSI first, but fall back to legacy if MSI
 641                          * attach fails.
 642                          */
 643                         if (si_add_msi_intrs(si_ctlp) == DDI_SUCCESS) {
 644                                 si_ctlp->sictl_intr_type = DDI_INTR_TYPE_MSI;
 645                                 attach_state |= ATTACH_PROGRESS_INTR_ADDED;
 646                                 SIDBG_C(SIDBG_INIT, si_ctlp,
 647                                     "MSI interrupt setup done", NULL);
 648                         } else {
 649                                 SIDBG_C(SIDBG_INIT, si_ctlp,
 650                                     "MSI registration failed "
 651                                     "will try Legacy interrupts", NULL);
 652                         }
 653                 }
 654 
 655                 if (!(attach_state & ATTACH_PROGRESS_INTR_ADDED) &&
 656                     (intr_types & DDI_INTR_TYPE_FIXED)) {
 657                         /*
 658                          * Either the MSI interrupt setup has failed or only
 659                          * fixed interrupts are available on the system.
 660                          */
 661                         SIDBG_C(SIDBG_INIT, si_ctlp,
 662                             "Using Legacy interrupt type", NULL);
 663 
 664                         if (si_add_legacy_intrs(si_ctlp) == DDI_SUCCESS) {
 665                                 si_ctlp->sictl_intr_type = DDI_INTR_TYPE_FIXED;
 666                                 attach_state |= ATTACH_PROGRESS_INTR_ADDED;
 667                                 SIDBG_C(SIDBG_INIT, si_ctlp,
 668                                     "Legacy interrupt setup done", NULL);
 669                         } else {
 670                                 SIDBG_C(SIDBG_INIT, si_ctlp,
 671                                     "legacy interrupt setup failed", NULL);
 672                                 goto err_out;
 673                         }
 674                 }
 675 
 676                 if (!(attach_state & ATTACH_PROGRESS_INTR_ADDED)) {
 677                         SIDBG_C(SIDBG_INIT, si_ctlp,
 678                             "si3124: No interrupts registered", NULL);
 679                         goto err_out;
 680                 }
 681 
 682 
 683                 /* Initialize the mutex. */
 684                 mutex_init(&si_ctlp->sictl_mutex, NULL, MUTEX_DRIVER,
 685                     (void *)(uintptr_t)si_ctlp->sictl_intr_pri);
 686 
 687                 attach_state |= ATTACH_PROGRESS_MUTEX_INIT;
 688 
 689                 /*
 690                  * Initialize the controller and driver core.
 691                  */
 692                 si_ctlp->sictl_flags |= SI_ATTACH;
 693                 status = si_initialize_controller(si_ctlp);
 694                 si_ctlp->sictl_flags &= ~SI_ATTACH;
 695                 if (status) {
 696                         goto err_out;
 697                 }
 698 
 699                 attach_state |= ATTACH_PROGRESS_HW_INIT;
 700 
 701                 if (si_register_sata_hba_tran(si_ctlp)) {
 702                         SIDBG_C(SIDBG_INIT, si_ctlp,
 703                             "si3124: setting sata hba tran failed", NULL);
 704                         goto err_out;
 705                 }
 706 
 707                 si_ctlp->sictl_timeout_id = timeout(
 708                     (void (*)(void *))si_watchdog_handler,
 709                     (caddr_t)si_ctlp, si_watchdog_tick);
 710 
 711                 si_ctlp->sictl_power_level = PM_LEVEL_D0;
 712 
 713                 return (DDI_SUCCESS);
 714 
 715         case DDI_RESUME:
 716                 si_ctlp = ddi_get_soft_state(si_statep, instance);
 717 
 718                 status = si_initialize_controller(si_ctlp);
 719                 if (status) {
 720                         return (DDI_FAILURE);
 721                 }
 722 
 723                 si_ctlp->sictl_timeout_id = timeout(
 724                     (void (*)(void *))si_watchdog_handler,
 725                     (caddr_t)si_ctlp, si_watchdog_tick);
 726 
 727                 (void) pm_power_has_changed(dip, 0, PM_LEVEL_D0);
 728 
 729                 /* Notify SATA framework about RESUME. */
 730                 if (sata_hba_attach(si_ctlp->sictl_devinfop,
 731                     si_ctlp->sictl_sata_hba_tran,
 732                     DDI_RESUME) != DDI_SUCCESS) {
 733                         return (DDI_FAILURE);
 734                 }
 735 
 736                 /*
 737                  * Notify the "framework" that it should reprobe ports to see
 738                  * if any device got changed while suspended.
 739                  */
 740                 bzero((void *)&sdevice, sizeof (sata_device_t));
 741                 sata_hba_event_notify(dip, &sdevice,
 742                     SATA_EVNT_PWR_LEVEL_CHANGED);
 743                 SIDBG_C(SIDBG_INIT|SIDBG_EVENT, si_ctlp,
 744                     "sending event up: SATA_EVNT_PWR_LEVEL_CHANGED", NULL);
 745 
 746                 (void) pm_idle_component(si_ctlp->sictl_devinfop, 0);
 747 
 748                 si_ctlp->sictl_power_level = PM_LEVEL_D0;
 749 
 750                 return (DDI_SUCCESS);
 751 
 752         default:
 753                 return (DDI_FAILURE);
 754 
 755         }
 756 
 757 err_out:
 758         if (attach_state & ATTACH_PROGRESS_HW_INIT) {
 759                 si_ctlp->sictl_flags |= SI_DETACH;
 760                 /* We want to set SI_DETACH to deallocate all memory */
 761                 si_deinitialize_controller(si_ctlp);
 762                 si_ctlp->sictl_flags &= ~SI_DETACH;
 763         }
 764 
 765         if (attach_state & ATTACH_PROGRESS_MUTEX_INIT) {
 766                 mutex_destroy(&si_ctlp->sictl_mutex);
 767         }
 768 
 769         if (attach_state & ATTACH_PROGRESS_INTR_ADDED) {
 770                 si_rem_intrs(si_ctlp);
 771         }
 772 
 773         if (attach_state & ATTACH_PROGRESS_BAR1_MAP) {
 774                 ddi_regs_map_free(&si_ctlp->sictl_port_acc_handle);
 775         }
 776 
 777         if (attach_state & ATTACH_PROGRESS_BAR0_MAP) {
 778                 ddi_regs_map_free(&si_ctlp->sictl_global_acc_handle);
 779         }
 780 
 781         if (attach_state & ATTACH_PROGRESS_CONF_HANDLE) {
 782                 pci_config_teardown(&si_ctlp->sictl_pci_conf_handle);
 783         }
 784 
 785         if (attach_state & ATTACH_PROGRESS_INIT_FMA) {
 786                 si_fm_fini(si_ctlp);
 787         }
 788 
 789         if (attach_state & ATTACH_PROGRESS_STATEP_ALLOC) {
 790                 ddi_soft_state_free(si_statep, instance);
 791         }
 792 
 793         return (DDI_FAILURE);
 794 }
 795 
 796 
 797 /*
 798  * The detach entry point for dev_ops.
 799  *
 800  * We undo the things we did in si_attach().
 801  */
 802 static int
 803 si_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
 804 {
 805         si_ctl_state_t *si_ctlp;
 806         int instance;
 807 
 808         SIDBG(SIDBG_ENTRY, "si_detach enter", NULL);
 809         instance = ddi_get_instance(dip);
 810         si_ctlp = ddi_get_soft_state(si_statep, instance);
 811 
 812         switch (cmd) {
 813 
 814         case DDI_DETACH:
 815 
 816                 mutex_enter(&si_ctlp->sictl_mutex);
 817 
 818                 /* disable the interrupts for an uninterrupted detach */
 819                 si_disable_all_interrupts(si_ctlp);
 820 
 821                 mutex_exit(&si_ctlp->sictl_mutex);
 822                 /* unregister from the sata framework. */
 823                 if (si_unregister_sata_hba_tran(si_ctlp) != SI_SUCCESS) {
 824                         si_enable_all_interrupts(si_ctlp);
 825                         return (DDI_FAILURE);
 826                 }
 827                 mutex_enter(&si_ctlp->sictl_mutex);
 828 
 829                 /* now cancel the timeout handler. */
 830                 si_ctlp->sictl_flags |= SI_NO_TIMEOUTS;
 831                 (void) untimeout(si_ctlp->sictl_timeout_id);
 832                 si_ctlp->sictl_flags &= ~SI_NO_TIMEOUTS;
 833 
 834                 /* de-initialize the controller. */
 835                 si_ctlp->sictl_flags |= SI_DETACH;
 836                 si_deinitialize_controller(si_ctlp);
 837                 si_ctlp->sictl_flags &= ~SI_DETACH;
 838 
 839                 /* destroy any mutexes */
 840                 mutex_exit(&si_ctlp->sictl_mutex);
 841                 mutex_destroy(&si_ctlp->sictl_mutex);
 842 
 843                 /* remove the interrupts */
 844                 si_rem_intrs(si_ctlp);
 845 
 846                 /* remove the reg maps. */
 847                 ddi_regs_map_free(&si_ctlp->sictl_port_acc_handle);
 848                 ddi_regs_map_free(&si_ctlp->sictl_global_acc_handle);
 849                 pci_config_teardown(&si_ctlp->sictl_pci_conf_handle);
 850 
 851                 /* deinit FMA */
 852                 si_fm_fini(si_ctlp);
 853 
 854                 /* free the soft state. */
 855                 ddi_soft_state_free(si_statep, instance);
 856 
 857                 return (DDI_SUCCESS);
 858 
 859         case DDI_SUSPEND:
 860                 /* Inform SATA framework */
 861                 if (sata_hba_detach(dip, cmd) != DDI_SUCCESS) {
 862                         return (DDI_FAILURE);
 863                 }
 864 
 865                 mutex_enter(&si_ctlp->sictl_mutex);
 866 
 867                 /*
 868                  * Device needs to be at full power in case it is needed to
 869                  * handle dump(9e) to save CPR state after DDI_SUSPEND
 870                  * completes.  This is OK since presumably power will be
 871                  * removed anyways.  No outstanding transactions should be
 872                  * on the controller since the children are already quiesced.
 873                  *
 874                  * If any ioctls/cfgadm support is added that touches
 875                  * hardware, those entry points will need to check for
 876                  * suspend and then block or return errors until resume.
 877                  *
 878                  */
 879                 if (pm_busy_component(si_ctlp->sictl_devinfop, 0) ==
 880                     DDI_SUCCESS) {
 881                         mutex_exit(&si_ctlp->sictl_mutex);
 882                         (void) pm_raise_power(si_ctlp->sictl_devinfop, 0,
 883                             PM_LEVEL_D0);
 884                         mutex_enter(&si_ctlp->sictl_mutex);
 885                 }
 886 
 887                 si_deinitialize_controller(si_ctlp);
 888 
 889                 si_ctlp->sictl_flags |= SI_NO_TIMEOUTS;
 890                 (void) untimeout(si_ctlp->sictl_timeout_id);
 891                 si_ctlp->sictl_flags &= ~SI_NO_TIMEOUTS;
 892 
 893                 SIDBG_C(SIDBG_POWER, si_ctlp, "si3124%d: DDI_SUSPEND",
 894                     instance);
 895 
 896                 mutex_exit(&si_ctlp->sictl_mutex);
 897 
 898                 return (DDI_SUCCESS);
 899 
 900         default:
 901                 return (DDI_FAILURE);
 902 
 903         }
 904 
 905 }
 906 
 907 static int
 908 si_power(dev_info_t *dip, int component, int level)
 909 {
 910 #ifndef __lock_lint
 911         _NOTE(ARGUNUSED(component))
 912 #endif /* __lock_lint */
 913 
 914         si_ctl_state_t *si_ctlp;
 915         int instance = ddi_get_instance(dip);
 916         int rval = DDI_SUCCESS;
 917         int old_level;
 918         sata_device_t sdevice;
 919 
 920         si_ctlp = ddi_get_soft_state(si_statep, instance);
 921 
 922         if (si_ctlp == NULL) {
 923                 return (DDI_FAILURE);
 924         }
 925 
 926         SIDBG_C(SIDBG_ENTRY, si_ctlp, "si_power enter", NULL);
 927 
 928         mutex_enter(&si_ctlp->sictl_mutex);
 929         old_level = si_ctlp->sictl_power_level;
 930 
 931         switch (level) {
 932         case PM_LEVEL_D0: /* fully on */
 933                 pci_config_put16(si_ctlp->sictl_pci_conf_handle,
 934                     PM_CSR(si_ctlp->sictl_devid), PCI_PMCSR_D0);
 935 #ifndef __lock_lint
 936                 delay(drv_usectohz(10000));
 937 #endif  /* __lock_lint */
 938                 si_ctlp->sictl_power_level = PM_LEVEL_D0;
 939                 (void) pci_restore_config_regs(si_ctlp->sictl_devinfop);
 940 
 941                 SIDBG_C(SIDBG_POWER, si_ctlp,
 942                     "si3124%d: turning power ON. old level %d",
 943                     instance, old_level);
 944                 /*
 945                  * If called from attach, just raise device power,
 946                  * restore config registers (if they were saved
 947                  * from a previous detach that lowered power),
 948                  * and exit.
 949                  */
 950                 if (si_ctlp->sictl_flags & SI_ATTACH)
 951                         break;
 952 
 953                 mutex_exit(&si_ctlp->sictl_mutex);
 954                 (void) si_initialize_controller(si_ctlp);
 955                 mutex_enter(&si_ctlp->sictl_mutex);
 956 
 957                 si_ctlp->sictl_timeout_id = timeout(
 958                     (void (*)(void *))si_watchdog_handler,
 959                     (caddr_t)si_ctlp, si_watchdog_tick);
 960 
 961                 bzero((void *)&sdevice, sizeof (sata_device_t));
 962                 sata_hba_event_notify(
 963                     si_ctlp->sictl_sata_hba_tran->sata_tran_hba_dip,
 964                     &sdevice, SATA_EVNT_PWR_LEVEL_CHANGED);
 965                 SIDBG_C(SIDBG_EVENT|SIDBG_POWER, si_ctlp,
 966                     "sending event up: PWR_LEVEL_CHANGED", NULL);
 967 
 968                 break;
 969 
 970         case PM_LEVEL_D3: /* fully off */
 971                 if (!(si_ctlp->sictl_flags & SI_DETACH)) {
 972                         si_ctlp->sictl_flags |= SI_NO_TIMEOUTS;
 973                         (void) untimeout(si_ctlp->sictl_timeout_id);
 974                         si_ctlp->sictl_flags &= ~SI_NO_TIMEOUTS;
 975 
 976                         si_deinitialize_controller(si_ctlp);
 977 
 978                         si_ctlp->sictl_power_level = PM_LEVEL_D3;
 979                 }
 980 
 981                 (void) pci_save_config_regs(si_ctlp->sictl_devinfop);
 982 
 983                 pci_config_put16(si_ctlp->sictl_pci_conf_handle,
 984                     PM_CSR(si_ctlp->sictl_devid), PCI_PMCSR_D3HOT);
 985 
 986                 SIDBG_C(SIDBG_POWER, si_ctlp, "si3124%d: turning power OFF. "
 987                     "old level %d", instance, old_level);
 988 
 989                 break;
 990 
 991         default:
 992                 SIDBG_C(SIDBG_POWER, si_ctlp, "si3124%d: turning power OFF. "
 993                     "old level %d", instance, old_level);
 994                 rval = DDI_FAILURE;
 995                 break;
 996         }
 997 
 998         mutex_exit(&si_ctlp->sictl_mutex);
 999 
1000         return (rval);
1001 }
1002 
1003 
1004 /*
1005  * The info entry point for dev_ops.
1006  *
1007  */
1008 static int
1009 si_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd,
1010                 void *arg,
1011                 void **result)
1012 {
1013 #ifndef __lock_lint
1014         _NOTE(ARGUNUSED(dip))
1015 #endif /* __lock_lint */
1016         si_ctl_state_t *si_ctlp;
1017         int instance;
1018         dev_t dev;
1019 
1020         dev = (dev_t)arg;
1021         instance = getminor(dev);
1022 
1023         switch (infocmd) {
1024                 case DDI_INFO_DEVT2DEVINFO:
1025                         si_ctlp = ddi_get_soft_state(si_statep,  instance);
1026                         if (si_ctlp != NULL) {
1027                                 *result = si_ctlp->sictl_devinfop;
1028                                 return (DDI_SUCCESS);
1029                         } else {
1030                                 *result = NULL;
1031                                 return (DDI_FAILURE);
1032                         }
1033                 case DDI_INFO_DEVT2INSTANCE:
1034                         *(int *)result = instance;
1035                         break;
1036                 default:
1037                         break;
1038         }
1039         return (DDI_SUCCESS);
1040 }
1041 
1042 
1043 
1044 /*
1045  * Registers the si3124 with sata framework.
1046  */
1047 static int
1048 si_register_sata_hba_tran(si_ctl_state_t *si_ctlp)
1049 {
1050         struct  sata_hba_tran   *sata_hba_tran;
1051 
1052         SIDBG_C(SIDBG_ENTRY, si_ctlp,
1053             "si_register_sata_hba_tran entry", NULL);
1054 
1055         mutex_enter(&si_ctlp->sictl_mutex);
1056 
1057         /* Allocate memory for the sata_hba_tran  */
1058         sata_hba_tran = kmem_zalloc(sizeof (sata_hba_tran_t), KM_SLEEP);
1059 
1060         sata_hba_tran->sata_tran_hba_rev = SATA_TRAN_HBA_REV;
1061         sata_hba_tran->sata_tran_hba_dip = si_ctlp->sictl_devinfop;
1062 
1063         if (si_dma_sg_number > SI_MAX_SGT_TABLES_PER_PRB) {
1064                 si_dma_sg_number = SI_MAX_SGT_TABLES_PER_PRB;
1065         } else if (si_dma_sg_number < SI_MIN_SGT_TABLES_PER_PRB) {
1066                 si_dma_sg_number = SI_MIN_SGT_TABLES_PER_PRB;
1067         }
1068 
1069         if (si_dma_sg_number != SI_DEFAULT_SGT_TABLES_PER_PRB) {
1070                 buffer_dma_attr.dma_attr_sgllen = SGE_LENGTH(si_dma_sg_number);
1071         }
1072         sata_hba_tran->sata_tran_hba_dma_attr = &buffer_dma_attr;
1073 
1074         sata_hba_tran->sata_tran_hba_num_cports = si_ctlp->sictl_num_ports;
1075         sata_hba_tran->sata_tran_hba_features_support = 0;
1076         sata_hba_tran->sata_tran_hba_qdepth = SI_NUM_SLOTS;
1077 
1078         sata_hba_tran->sata_tran_probe_port = si_tran_probe_port;
1079         sata_hba_tran->sata_tran_start = si_tran_start;
1080         sata_hba_tran->sata_tran_abort = si_tran_abort;
1081         sata_hba_tran->sata_tran_reset_dport = si_tran_reset_dport;
1082         sata_hba_tran->sata_tran_selftest = NULL;
1083         sata_hba_tran->sata_tran_hotplug_ops = &si_tran_hotplug_ops;
1084         sata_hba_tran->sata_tran_pwrmgt_ops = NULL;
1085         sata_hba_tran->sata_tran_ioctl = NULL;
1086         mutex_exit(&si_ctlp->sictl_mutex);
1087 
1088         /* Attach it to SATA framework */
1089         if (sata_hba_attach(si_ctlp->sictl_devinfop, sata_hba_tran, DDI_ATTACH)
1090             != DDI_SUCCESS) {
1091                 kmem_free((void *)sata_hba_tran, sizeof (sata_hba_tran_t));
1092                 return (SI_FAILURE);
1093         }
1094 
1095         mutex_enter(&si_ctlp->sictl_mutex);
1096         si_ctlp->sictl_sata_hba_tran = sata_hba_tran;
1097         mutex_exit(&si_ctlp->sictl_mutex);
1098 
1099         return (SI_SUCCESS);
1100 }
1101 
1102 
1103 /*
1104  * Unregisters the si3124 with sata framework.
1105  */
1106 static int
1107 si_unregister_sata_hba_tran(si_ctl_state_t *si_ctlp)
1108 {
1109 
1110         /* Detach from the SATA framework. */
1111         if (sata_hba_detach(si_ctlp->sictl_devinfop, DDI_DETACH) !=
1112             DDI_SUCCESS) {
1113                 return (SI_FAILURE);
1114         }
1115 
1116         /* Deallocate sata_hba_tran. */
1117         kmem_free((void *)si_ctlp->sictl_sata_hba_tran,
1118             sizeof (sata_hba_tran_t));
1119 
1120         si_ctlp->sictl_sata_hba_tran = NULL;
1121 
1122         return (SI_SUCCESS);
1123 }
1124 
1125 /*
1126  * Called by sata framework to probe a port. We return the
1127  * cached information from a previous hardware probe.
1128  *
1129  * The actual hardware probing itself was done either from within
1130  * si_initialize_controller() during the driver attach or
1131  * from a phy ready change interrupt handler.
1132  */
1133 static int
1134 si_tran_probe_port(dev_info_t *dip, sata_device_t *sd)
1135 {
1136 
1137         si_ctl_state_t  *si_ctlp;
1138         uint8_t cport = sd->satadev_addr.cport;
1139         uint8_t pmport = sd->satadev_addr.pmport;
1140         uint8_t qual = sd->satadev_addr.qual;
1141         uint8_t port_type;
1142         si_port_state_t *si_portp;
1143         si_portmult_state_t *si_portmultp;
1144 
1145         si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
1146 
1147         SIDBG_C(SIDBG_ENTRY, si_ctlp,
1148             "si_tran_probe_port: cport: 0x%x, pmport: 0x%x, qual: 0x%x",
1149             cport, pmport, qual);
1150 
1151         if (cport >= SI_MAX_PORTS) {
1152                 sd->satadev_type = SATA_DTYPE_NONE;
1153                 sd->satadev_state = SATA_STATE_UNKNOWN; /* invalid port */
1154                 return (SATA_FAILURE);
1155         }
1156 
1157         mutex_enter(&si_ctlp->sictl_mutex);
1158         si_portp = si_ctlp->sictl_ports[cport];
1159         mutex_exit(&si_ctlp->sictl_mutex);
1160         if (si_portp == NULL) {
1161                 sd->satadev_type = SATA_DTYPE_NONE;
1162                 sd->satadev_state = SATA_STATE_UNKNOWN;
1163                 return (SATA_FAILURE);
1164         }
1165 
1166         mutex_enter(&si_portp->siport_mutex);
1167 
1168         if (qual == SATA_ADDR_PMPORT) {
1169                 if (pmport >= si_portp->siport_portmult_state.sipm_num_ports) {
1170                         sd->satadev_type = SATA_DTYPE_NONE;
1171                         sd->satadev_state = SATA_STATE_UNKNOWN;
1172                         mutex_exit(&si_portp->siport_mutex);
1173                         return (SATA_FAILURE);
1174                 } else {
1175                         si_portmultp =  &si_portp->siport_portmult_state;
1176                         port_type = si_portmultp->sipm_port_type[pmport];
1177                 }
1178         } else {
1179                 port_type = si_portp->siport_port_type;
1180         }
1181 
1182         switch (port_type) {
1183 
1184         case PORT_TYPE_DISK:
1185                 sd->satadev_type = SATA_DTYPE_ATADISK;
1186                 break;
1187 
1188         case PORT_TYPE_ATAPI:
1189                 sd->satadev_type = SATA_DTYPE_ATAPICD;
1190                 break;
1191 
1192         case PORT_TYPE_MULTIPLIER:
1193                 sd->satadev_type = SATA_DTYPE_PMULT;
1194                 sd->satadev_add_info =
1195                     si_portp->siport_portmult_state.sipm_num_ports;
1196                 break;
1197 
1198         case PORT_TYPE_UNKNOWN:
1199                 sd->satadev_type = SATA_DTYPE_UNKNOWN;
1200                 break;
1201 
1202         default:
1203                 /* we don't support any other device types. */
1204                 sd->satadev_type = SATA_DTYPE_NONE;
1205                 break;
1206         }
1207         sd->satadev_state = SATA_STATE_READY;
1208 
1209         if (qual == SATA_ADDR_PMPORT) {
1210                 (void) si_read_portmult_reg(si_ctlp, si_portp, cport,
1211                     pmport, PSCR_REG0, &sd->satadev_scr.sstatus);
1212                 (void) si_read_portmult_reg(si_ctlp, si_portp, cport,
1213                     pmport, PSCR_REG1, &sd->satadev_scr.serror);
1214                 (void) si_read_portmult_reg(si_ctlp, si_portp, cport,
1215                     pmport, PSCR_REG2, &sd->satadev_scr.scontrol);
1216                 (void) si_read_portmult_reg(si_ctlp, si_portp, cport,
1217                     pmport, PSCR_REG3, &sd->satadev_scr.sactive);
1218         } else {
1219                 fill_dev_sregisters(si_ctlp, cport, sd);
1220                 if (!(si_portp->siport_active)) {
1221                         /*
1222                          * Since we are implementing the port deactivation
1223                          * in software only, we need to fake a valid value
1224                          * for sstatus when the device is in deactivated state.
1225                          */
1226                         SSTATUS_SET_DET(sd->satadev_scr.sstatus,
1227                             SSTATUS_DET_PHYOFFLINE);
1228                         SSTATUS_SET_IPM(sd->satadev_scr.sstatus,
1229                             SSTATUS_IPM_NODEV_NOPHY);
1230                         sd->satadev_state = SATA_PSTATE_SHUTDOWN;
1231                 }
1232         }
1233 
1234         mutex_exit(&si_portp->siport_mutex);
1235         return (SATA_SUCCESS);
1236 }
1237 
1238 /*
1239  * Called by sata framework to transport a sata packet down stream.
1240  *
1241  * The actual work of building the FIS & transporting it to the hardware
1242  * is done out of the subroutine si_deliver_satapkt().
1243  */
1244 static int
1245 si_tran_start(dev_info_t *dip, sata_pkt_t *spkt)
1246 {
1247         si_ctl_state_t *si_ctlp;
1248         uint8_t cport;
1249         si_port_state_t *si_portp;
1250         int slot;
1251 
1252         cport = spkt->satapkt_device.satadev_addr.cport;
1253         si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
1254         mutex_enter(&si_ctlp->sictl_mutex);
1255         si_portp = si_ctlp->sictl_ports[cport];
1256         mutex_exit(&si_ctlp->sictl_mutex);
1257 
1258         SIDBG_P(SIDBG_ENTRY, si_portp,
1259             "si_tran_start entry", NULL);
1260 
1261         mutex_enter(&si_portp->siport_mutex);
1262 
1263         if ((si_portp->siport_port_type == PORT_TYPE_NODEV) ||
1264             !si_portp->siport_active) {
1265                 /*
1266                  * si_intr_phy_ready_change() may have rendered it to
1267                  * PORT_TYPE_NODEV. cfgadm operation may have rendered
1268                  * it inactive.
1269                  */
1270                 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1271                 fill_dev_sregisters(si_ctlp, cport, &spkt->satapkt_device);
1272                 mutex_exit(&si_portp->siport_mutex);
1273                 return (SATA_TRAN_PORT_ERROR);
1274         }
1275 
1276         if (spkt->satapkt_cmd.satacmd_flags.sata_clear_dev_reset) {
1277                 si_portp->siport_reset_in_progress = 0;
1278                 SIDBG_P(SIDBG_RESET, si_portp,
1279                     "si_tran_start clearing the "
1280                     "reset_in_progress for port", NULL);
1281         }
1282 
1283         if (si_portp->siport_reset_in_progress &&
1284             ! spkt->satapkt_cmd.satacmd_flags.sata_ignore_dev_reset &&
1285             ! ddi_in_panic()) {
1286 
1287                 spkt->satapkt_reason = SATA_PKT_BUSY;
1288                 SIDBG_P(SIDBG_RESET, si_portp,
1289                     "si_tran_start returning BUSY while "
1290                     "reset in progress for port", NULL);
1291                 mutex_exit(&si_portp->siport_mutex);
1292                 return (SATA_TRAN_BUSY);
1293         }
1294 
1295         if (si_portp->mopping_in_progress > 0) {
1296                 spkt->satapkt_reason = SATA_PKT_BUSY;
1297                 SIDBG_P(SIDBG_RESET, si_portp,
1298                     "si_tran_start returning BUSY while "
1299                     "mopping in progress for port", NULL);
1300                 mutex_exit(&si_portp->siport_mutex);
1301                 return (SATA_TRAN_BUSY);
1302         }
1303 
1304         if ((slot = si_deliver_satapkt(si_ctlp, si_portp, cport, spkt))
1305             == SI_FAILURE) {
1306                 spkt->satapkt_reason = SATA_PKT_QUEUE_FULL;
1307                 SIDBG_P(SIDBG_ERRS, si_portp,
1308                     "si_tran_start returning QUEUE_FULL",
1309                     NULL);
1310                 mutex_exit(&si_portp->siport_mutex);
1311                 return (SATA_TRAN_QUEUE_FULL);
1312         }
1313 
1314         if (spkt->satapkt_op_mode & (SATA_OPMODE_POLLING|SATA_OPMODE_SYNCH)) {
1315                 /* we need to poll now */
1316                 si_poll_cmd(si_ctlp, si_portp, cport, slot, spkt);
1317                 /*
1318                  * The command has completed, and spkt will be freed by the
1319                  * sata module, so don't keep a pointer to it lying around.
1320                  */
1321                 si_portp->siport_slot_pkts[slot] = NULL;
1322         }
1323 
1324         mutex_exit(&si_portp->siport_mutex);
1325         return (SATA_TRAN_ACCEPTED);
1326 }
1327 
1328 #define SENDUP_PACKET(si_portp, satapkt, reason)                        \
1329         if (satapkt) {                                                  \
1330                 if ((satapkt->satapkt_cmd.satacmd_cmd_reg ==         \
1331                                         SATAC_WRITE_FPDMA_QUEUED) ||    \
1332                     (satapkt->satapkt_cmd.satacmd_cmd_reg ==         \
1333                                         SATAC_READ_FPDMA_QUEUED)) {     \
1334                         si_portp->siport_pending_ncq_count--;                \
1335                 }                                                       \
1336                 satapkt->satapkt_reason = reason;                    \
1337                 /*                                                      \
1338                  * We set the satapkt_reason in both synch and          \
1339                  * non-synch cases.                                     \
1340                  */                                                     \
1341                 if (!(satapkt->satapkt_op_mode & SATA_OPMODE_SYNCH) &&   \
1342                         satapkt->satapkt_comp) {                     \
1343                         mutex_exit(&si_portp->siport_mutex);             \
1344                         (*satapkt->satapkt_comp)(satapkt);           \
1345                         mutex_enter(&si_portp->siport_mutex);            \
1346                 }                                                       \
1347         }
1348 
1349 /*
1350  * Mopping is necessitated because of the si3124 hardware limitation.
1351  * The only way to recover from errors or to abort a command is to
1352  * reset the port/device but such a reset also results in throwing
1353  * away all the unfinished pending commands.
1354  *
1355  * A port or device is reset in four scenarios:
1356  *      a) some commands failed with errors
1357  *      b) or we need to timeout some commands
1358  *      c) or we need to abort some commands
1359  *      d) or we need reset the port at the request of sata framework
1360  *
1361  * In all these scenarios, we need to send any pending unfinished
1362  * commands up to sata framework.
1363  *
1364  * WARNING!!! siport_mutex should be acquired before the function is called.
1365  */
1366 static void
1367 si_mop_commands(si_ctl_state_t *si_ctlp,
1368                 si_port_state_t *si_portp,
1369                 uint8_t port,
1370 
1371                 uint32_t slot_status,
1372                 uint32_t failed_tags,
1373                 uint32_t timedout_tags,
1374                 uint32_t aborting_tags,
1375                 uint32_t reset_tags)
1376 {
1377         uint32_t finished_tags, unfinished_tags;
1378         int tmpslot;
1379         sata_pkt_t *satapkt;
1380         struct sata_cmd_flags *flagsp;
1381 
1382         SIDBG_P(SIDBG_ERRS, si_portp,
1383             "si_mop_commands entered: slot_status: 0x%x",
1384             slot_status);
1385 
1386         SIDBG_P(SIDBG_ERRS, si_portp,
1387             "si_mop_commands: failed_tags: 0x%x, timedout_tags: 0x%x"
1388             "aborting_tags: 0x%x, reset_tags: 0x%x",
1389             failed_tags,
1390             timedout_tags,
1391             aborting_tags,
1392             reset_tags);
1393 
1394         /*
1395          * We could be here for four reasons: abort, reset,
1396          * timeout or error handling. Only one such mopping
1397          * is allowed at a time.
1398          */
1399 
1400         finished_tags =  si_portp->siport_pending_tags &
1401             ~slot_status & SI_SLOT_MASK;
1402 
1403         unfinished_tags = slot_status & SI_SLOT_MASK &
1404             ~failed_tags &
1405             ~aborting_tags &
1406             ~reset_tags &
1407             ~timedout_tags;
1408 
1409         /* Send up the finished_tags with SATA_PKT_COMPLETED. */
1410         while (finished_tags) {
1411                 tmpslot = ddi_ffs(finished_tags) - 1;
1412                 if (tmpslot == -1) {
1413                         break;
1414                 }
1415 
1416                 satapkt = si_portp->siport_slot_pkts[tmpslot];
1417 
1418                 if (satapkt != NULL &&
1419                     satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
1420                         si_copy_out_regs(&satapkt->satapkt_cmd, si_ctlp,
1421                             port, tmpslot);
1422                 }
1423 
1424                 SIDBG_P(SIDBG_ERRS, si_portp,
1425                     "si_mop_commands sending up completed satapkt: %x",
1426                     satapkt);
1427 
1428                 CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
1429                 CLEAR_BIT(finished_tags, tmpslot);
1430                 SENDUP_PACKET(si_portp, satapkt, SATA_PKT_COMPLETED);
1431         }
1432 
1433         ASSERT(finished_tags == 0);
1434 
1435         /* Send up failed_tags with SATA_PKT_DEV_ERROR. */
1436         while (failed_tags) {
1437                 tmpslot = ddi_ffs(failed_tags) - 1;
1438                 if (tmpslot == -1) {
1439                         break;
1440                 }
1441                 SIDBG_P(SIDBG_ERRS, si_portp, "si3124: si_mop_commands: "
1442                     "handling failed slot: 0x%x", tmpslot);
1443 
1444                 satapkt = si_portp->siport_slot_pkts[tmpslot];
1445 
1446                 if (satapkt != NULL) {
1447 
1448                         if (satapkt->satapkt_device.satadev_type ==
1449                             SATA_DTYPE_ATAPICD) {
1450                                 si_set_sense_data(satapkt, SATA_PKT_DEV_ERROR);
1451                         }
1452 
1453 
1454                         flagsp = &satapkt->satapkt_cmd.satacmd_flags;
1455 
1456                         flagsp->sata_copy_out_lba_low_msb = B_TRUE;
1457                         flagsp->sata_copy_out_lba_mid_msb = B_TRUE;
1458                         flagsp->sata_copy_out_lba_high_msb = B_TRUE;
1459                         flagsp->sata_copy_out_lba_low_lsb = B_TRUE;
1460                         flagsp->sata_copy_out_lba_mid_lsb = B_TRUE;
1461                         flagsp->sata_copy_out_lba_high_lsb = B_TRUE;
1462                         flagsp->sata_copy_out_error_reg = B_TRUE;
1463                         flagsp->sata_copy_out_sec_count_msb = B_TRUE;
1464                         flagsp->sata_copy_out_sec_count_lsb = B_TRUE;
1465                         flagsp->sata_copy_out_device_reg = B_TRUE;
1466 
1467                         si_copy_out_regs(&satapkt->satapkt_cmd, si_ctlp,
1468                             port, tmpslot);
1469 
1470                         /*
1471                          * In the case of NCQ command failures, the error is
1472                          * overwritten by the one obtained from issuing of a
1473                          * READ LOG EXTENDED command.
1474                          */
1475                         if (si_portp->siport_err_tags_SDBERROR &
1476                             (1 << tmpslot)) {
1477                                 satapkt->satapkt_cmd.satacmd_error_reg =
1478                                     si_read_log_ext(si_ctlp, si_portp, port);
1479                         }
1480                 }
1481 
1482                 CLEAR_BIT(failed_tags, tmpslot);
1483                 CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
1484                 SENDUP_PACKET(si_portp, satapkt, SATA_PKT_DEV_ERROR);
1485         }
1486 
1487         ASSERT(failed_tags == 0);
1488 
1489         /* Send up timedout_tags with SATA_PKT_TIMEOUT. */
1490         while (timedout_tags) {
1491                 tmpslot = ddi_ffs(timedout_tags) - 1;
1492                 if (tmpslot == -1) {
1493                         break;
1494                 }
1495 
1496                 satapkt = si_portp->siport_slot_pkts[tmpslot];
1497                 SIDBG_P(SIDBG_ERRS, si_portp,
1498                     "si_mop_commands sending "
1499                     "spkt up with PKT_TIMEOUT: %x",
1500                     satapkt);
1501 
1502                 CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
1503                 CLEAR_BIT(timedout_tags, tmpslot);
1504                 SENDUP_PACKET(si_portp, satapkt, SATA_PKT_TIMEOUT);
1505         }
1506 
1507         ASSERT(timedout_tags == 0);
1508 
1509         /* Send up aborting packets with SATA_PKT_ABORTED. */
1510         while (aborting_tags) {
1511                 tmpslot = ddi_ffs(aborting_tags) - 1;
1512                 if (tmpslot == -1) {
1513                         break;
1514                 }
1515 
1516                 satapkt = si_portp->siport_slot_pkts[tmpslot];
1517                 SIDBG_P(SIDBG_ERRS, si_portp,
1518                     "si_mop_commands aborting spkt: %x",
1519                     satapkt);
1520                 if (satapkt != NULL && satapkt->satapkt_device.satadev_type ==
1521                     SATA_DTYPE_ATAPICD) {
1522                         si_set_sense_data(satapkt, SATA_PKT_ABORTED);
1523                 }
1524 
1525                 CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
1526                 CLEAR_BIT(aborting_tags, tmpslot);
1527                 SENDUP_PACKET(si_portp, satapkt, SATA_PKT_ABORTED);
1528 
1529         }
1530 
1531         ASSERT(aborting_tags == 0);
1532 
1533         /* Reset tags are sent up to framework with SATA_PKT_RESET. */
1534         while (reset_tags) {
1535                 tmpslot = ddi_ffs(reset_tags) - 1;
1536                 if (tmpslot == -1) {
1537                         break;
1538                 }
1539                 satapkt = si_portp->siport_slot_pkts[tmpslot];
1540                 SIDBG_P(SIDBG_ERRS, si_portp,
1541                     "si_mop_commands sending PKT_RESET for "
1542                     "reset spkt: %x",
1543                     satapkt);
1544 
1545                 CLEAR_BIT(reset_tags, tmpslot);
1546                 CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
1547                 SENDUP_PACKET(si_portp, satapkt, SATA_PKT_RESET);
1548         }
1549 
1550         ASSERT(reset_tags == 0);
1551 
1552         /* Send up the unfinished_tags with SATA_PKT_RESET. */
1553         while (unfinished_tags) {
1554                 tmpslot = ddi_ffs(unfinished_tags) - 1;
1555                 if (tmpslot == -1) {
1556                         break;
1557                 }
1558                 satapkt = si_portp->siport_slot_pkts[tmpslot];
1559                 SIDBG_P(SIDBG_ERRS, si_portp,
1560                     "si_mop_commands sending SATA_PKT_RESET for "
1561                     "retry spkt: %x",
1562                     satapkt);
1563 
1564                 CLEAR_BIT(unfinished_tags, tmpslot);
1565                 CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
1566                 SENDUP_PACKET(si_portp, satapkt, SATA_PKT_RESET);
1567         }
1568 
1569         ASSERT(unfinished_tags == 0);
1570 
1571         si_portp->mopping_in_progress--;
1572         ASSERT(si_portp->mopping_in_progress >= 0);
1573 }
1574 
1575 /*
1576  * Called by the sata framework to abort the previously sent packet(s).
1577  *
1578  * We reset the device and mop the commands on the port.
1579  */
1580 static int
1581 si_tran_abort(dev_info_t *dip, sata_pkt_t *spkt, int flag)
1582 {
1583         uint32_t slot_status;
1584         uint8_t port;
1585         int tmpslot;
1586         uint32_t aborting_tags;
1587         uint32_t finished_tags;
1588         si_port_state_t *si_portp;
1589         si_ctl_state_t *si_ctlp;
1590 
1591         port = spkt->satapkt_device.satadev_addr.cport;
1592         si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
1593         mutex_enter(&si_ctlp->sictl_mutex);
1594         si_portp = si_ctlp->sictl_ports[port];
1595         mutex_exit(&si_ctlp->sictl_mutex);
1596 
1597         SIDBG_P(SIDBG_ERRS, si_portp, "si_tran_abort on port: %x", port);
1598 
1599         mutex_enter(&si_portp->siport_mutex);
1600 
1601         /*
1602          * If already mopping, then no need to abort anything.
1603          */
1604         if (si_portp->mopping_in_progress > 0) {
1605                 SIDBG_P(SIDBG_ERRS, si_portp,
1606                     "si_tran_abort: port %d mopping "
1607                     "in progress, so just return", port);
1608                 mutex_exit(&si_portp->siport_mutex);
1609                 return (SATA_SUCCESS);
1610         }
1611 
1612         if ((si_portp->siport_port_type == PORT_TYPE_NODEV) ||
1613             !si_portp->siport_active) {
1614                 /*
1615                  * si_intr_phy_ready_change() may have rendered it to
1616                  * PORT_TYPE_NODEV. cfgadm operation may have rendered
1617                  * it inactive.
1618                  */
1619                 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1620                 fill_dev_sregisters(si_ctlp, port, &spkt->satapkt_device);
1621                 mutex_exit(&si_portp->siport_mutex);
1622                 return (SATA_FAILURE);
1623         }
1624 
1625         if (flag == SATA_ABORT_ALL_PACKETS) {
1626                 aborting_tags = si_portp->siport_pending_tags;
1627         } else {
1628                 /*
1629                  * Need to abort a single packet.
1630                  * Search our siport_slot_pkts[] list for matching spkt.
1631                  */
1632                 aborting_tags = 0xffffffff; /* 0xffffffff is impossible tag */
1633                 for (tmpslot = 0; tmpslot < SI_NUM_SLOTS; tmpslot++) {
1634                         if (si_portp->siport_slot_pkts[tmpslot] == spkt) {
1635                                 aborting_tags = (0x1 << tmpslot);
1636                                 break;
1637                         }
1638                 }
1639 
1640                 if (aborting_tags == 0xffffffff) {
1641                         /* requested packet is not on pending list. */
1642                         fill_dev_sregisters(si_ctlp, port,
1643                             &spkt->satapkt_device);
1644                         mutex_exit(&si_portp->siport_mutex);
1645                         return (SATA_FAILURE);
1646                 }
1647         }
1648 
1649         si_portp->mopping_in_progress++;
1650 
1651         slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
1652             (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
1653         (void) si_reset_dport_wait_till_ready(si_ctlp, si_portp,
1654             port, SI_DEVICE_RESET);
1655 
1656         /*
1657          * Compute which have finished and which need to be retried.
1658          *
1659          * The finished tags are siport_pending_tags minus the slot_status.
1660          * The aborting_tags have to be reduced by finished_tags since we
1661          * can't possibly abort a tag which had finished already.
1662          */
1663         finished_tags =  si_portp->siport_pending_tags &
1664             ~slot_status & SI_SLOT_MASK;
1665         aborting_tags &= ~finished_tags;
1666 
1667         si_mop_commands(si_ctlp,
1668             si_portp,
1669             port,
1670             slot_status,
1671             0, /* failed_tags */
1672             0, /* timedout_tags */
1673             aborting_tags,
1674             0); /* reset_tags */
1675 
1676         fill_dev_sregisters(si_ctlp, port, &spkt->satapkt_device);
1677         mutex_exit(&si_portp->siport_mutex);
1678         return (SATA_SUCCESS);
1679 }
1680 
1681 
1682 /*
1683  * Used to reject all the pending packets on a port during a reset
1684  * operation.
1685  *
1686  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
1687  * before calling us.
1688  */
1689 static void
1690 si_reject_all_reset_pkts(
1691         si_ctl_state_t *si_ctlp,
1692         si_port_state_t *si_portp,
1693         int port)
1694 {
1695         uint32_t slot_status;
1696         uint32_t reset_tags;
1697 
1698         _NOTE(ASSUMING_PROTECTED(si_portp))
1699 
1700         SIDBG_P(SIDBG_RESET, si_portp,
1701             "si_reject_all_reset_pkts on port: %x",
1702             port);
1703 
1704         slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
1705             (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
1706 
1707         /* Compute which tags need to be sent up. */
1708         reset_tags = slot_status & SI_SLOT_MASK;
1709 
1710         si_portp->mopping_in_progress++;
1711 
1712         si_mop_commands(si_ctlp,
1713             si_portp,
1714             port,
1715             slot_status,
1716             0, /* failed_tags */
1717             0, /* timedout_tags */
1718             0, /* aborting_tags */
1719             reset_tags);
1720 }
1721 
1722 
1723 /*
1724  * Called by sata framework to reset a port(s) or device.
1725  *
1726  */
1727 static int
1728 si_tran_reset_dport(dev_info_t *dip, sata_device_t *sd)
1729 {
1730         si_ctl_state_t  *si_ctlp;
1731         uint8_t port = sd->satadev_addr.cport;
1732         int i;
1733         si_port_state_t *si_portp;
1734         int retval = SI_SUCCESS;
1735 
1736         si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
1737         SIDBG_C(SIDBG_RESET, si_ctlp,
1738             "si_tran_reset_port entry: port: 0x%x",
1739             port);
1740 
1741         switch (sd->satadev_addr.qual) {
1742         case SATA_ADDR_CPORT:
1743                 mutex_enter(&si_ctlp->sictl_mutex);
1744                 si_portp = si_ctlp->sictl_ports[port];
1745                 mutex_exit(&si_ctlp->sictl_mutex);
1746 
1747                 mutex_enter(&si_portp->siport_mutex);
1748 
1749                 /*
1750                  * If already mopping, then no need to reset or mop again.
1751                  */
1752                 if (si_portp->mopping_in_progress > 0) {
1753                         SIDBG_P(SIDBG_RESET, si_portp,
1754                             "si_tran_reset_dport: CPORT port %d mopping "
1755                             "in progress, so just return", port);
1756                         mutex_exit(&si_portp->siport_mutex);
1757                         retval = SI_SUCCESS;
1758                         break;
1759                 }
1760 
1761                 retval = si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
1762                     SI_PORT_RESET);
1763                 si_reject_all_reset_pkts(si_ctlp,  si_portp, port);
1764                 mutex_exit(&si_portp->siport_mutex);
1765 
1766                 break;
1767 
1768         case SATA_ADDR_DCPORT:
1769                 mutex_enter(&si_ctlp->sictl_mutex);
1770                 si_portp = si_ctlp->sictl_ports[port];
1771                 mutex_exit(&si_ctlp->sictl_mutex);
1772 
1773                 mutex_enter(&si_portp->siport_mutex);
1774 
1775                 if ((si_portp->siport_port_type == PORT_TYPE_NODEV) ||
1776                     !si_portp->siport_active) {
1777                         mutex_exit(&si_portp->siport_mutex);
1778                         retval = SI_FAILURE;
1779                         break;
1780                 }
1781 
1782                 /*
1783                  * If already mopping, then no need to reset or mop again.
1784                  */
1785                 if (si_portp->mopping_in_progress > 0) {
1786                         SIDBG_P(SIDBG_RESET, si_portp,
1787                             "si_tran_reset_dport: DCPORT port %d mopping "
1788                             "in progress, so just return", port);
1789                         mutex_exit(&si_portp->siport_mutex);
1790                         retval = SI_SUCCESS;
1791                         break;
1792                 }
1793 
1794                 retval = si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
1795                     SI_DEVICE_RESET);
1796                 si_reject_all_reset_pkts(si_ctlp,  si_portp, port);
1797                 mutex_exit(&si_portp->siport_mutex);
1798 
1799                 break;
1800 
1801         case SATA_ADDR_CNTRL:
1802                 for (i = 0; i < si_ctlp->sictl_num_ports; i++) {
1803                         mutex_enter(&si_ctlp->sictl_mutex);
1804                         si_portp = si_ctlp->sictl_ports[i];
1805                         mutex_exit(&si_ctlp->sictl_mutex);
1806 
1807                         mutex_enter(&si_portp->siport_mutex);
1808 
1809                         /*
1810                          * If mopping, then all the pending commands are being
1811                          * mopped, therefore there is nothing else to do.
1812                          */
1813                         if (si_portp->mopping_in_progress > 0) {
1814                                 SIDBG_P(SIDBG_RESET, si_portp,
1815                                     "si_tran_reset_dport: CNTRL port %d mopping"
1816                                     " in progress, so just return", i);
1817                                 mutex_exit(&si_portp->siport_mutex);
1818                                 retval = SI_SUCCESS;
1819                                 break;
1820                         }
1821 
1822                         retval = si_reset_dport_wait_till_ready(si_ctlp,
1823                             si_portp, i, SI_PORT_RESET);
1824                         if (retval) {
1825                                 mutex_exit(&si_portp->siport_mutex);
1826                                 break;
1827                         }
1828                         si_reject_all_reset_pkts(si_ctlp,  si_portp, i);
1829                         mutex_exit(&si_portp->siport_mutex);
1830                 }
1831                 break;
1832 
1833         case SATA_ADDR_PMPORT:
1834         case SATA_ADDR_DPMPORT:
1835                 SIDBG_P(SIDBG_RESET, si_portp,
1836                     "port mult reset not implemented yet", NULL);
1837                 /* FALLSTHROUGH */
1838 
1839         default:
1840                 retval = SI_FAILURE;
1841 
1842         }
1843 
1844         return (retval);
1845 }
1846 
1847 
1848 /*
1849  * Called by sata framework to activate a port as part of hotplug.
1850  *
1851  * Note: Not port-mult aware.
1852  */
1853 static int
1854 si_tran_hotplug_port_activate(dev_info_t *dip, sata_device_t *satadev)
1855 {
1856         si_ctl_state_t *si_ctlp;
1857         si_port_state_t *si_portp;
1858         uint8_t port;
1859 
1860         si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
1861         port = satadev->satadev_addr.cport;
1862         mutex_enter(&si_ctlp->sictl_mutex);
1863         si_portp = si_ctlp->sictl_ports[port];
1864         mutex_exit(&si_ctlp->sictl_mutex);
1865 
1866         SIDBG_P(SIDBG_EVENT, si_portp, "si_tran_hotplug_port_activate entry",
1867             NULL);
1868 
1869         mutex_enter(&si_portp->siport_mutex);
1870         si_enable_port_interrupts(si_ctlp, port);
1871 
1872         /*
1873          * Reset the device so that a si_find_dev_signature() would trigger.
1874          * But this reset is an internal operation; the sata framework does
1875          * not need to know about it.
1876          */
1877         (void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
1878             SI_DEVICE_RESET|SI_RESET_NO_EVENTS_UP);
1879 
1880         satadev->satadev_state = SATA_STATE_READY;
1881 
1882         si_portp->siport_active = PORT_ACTIVE;
1883 
1884         fill_dev_sregisters(si_ctlp, port, satadev);
1885 
1886         mutex_exit(&si_portp->siport_mutex);
1887         return (SATA_SUCCESS);
1888 }
1889 
1890 /*
1891  * Called by sata framework to deactivate a port as part of hotplug.
1892  *
1893  * Note: Not port-mult aware.
1894  */
1895 static int
1896 si_tran_hotplug_port_deactivate(dev_info_t *dip, sata_device_t *satadev)
1897 {
1898         si_ctl_state_t *si_ctlp;
1899         si_port_state_t *si_portp;
1900         uint8_t port;
1901 
1902         si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
1903         port = satadev->satadev_addr.cport;
1904         mutex_enter(&si_ctlp->sictl_mutex);
1905         si_portp = si_ctlp->sictl_ports[port];
1906         mutex_exit(&si_ctlp->sictl_mutex);
1907 
1908         SIDBG(SIDBG_EVENT, "si_tran_hotplug_port_deactivate entry", NULL);
1909 
1910         mutex_enter(&si_portp->siport_mutex);
1911         if (si_portp->siport_pending_tags & SI_SLOT_MASK) {
1912                 /*
1913                  * There are pending commands on this port.
1914                  * Fail the deactivate request.
1915                  */
1916                 satadev->satadev_state = SATA_STATE_READY;
1917                 mutex_exit(&si_portp->siport_mutex);
1918                 return (SATA_FAILURE);
1919         }
1920 
1921         /* mark the device as not accessible any more. */
1922         si_portp->siport_active = PORT_INACTIVE;
1923 
1924         /* disable the interrupts on the port. */
1925         si_disable_port_interrupts(si_ctlp, port);
1926 
1927         satadev->satadev_state = SATA_PSTATE_SHUTDOWN;
1928 
1929         fill_dev_sregisters(si_ctlp, port, satadev);
1930         /*
1931          * Since we are implementing the port deactivation in software only,
1932          * we need to fake a valid value for sstatus.
1933          */
1934         SSTATUS_SET_DET(satadev->satadev_scr.sstatus, SSTATUS_DET_PHYOFFLINE);
1935         SSTATUS_SET_IPM(satadev->satadev_scr.sstatus, SSTATUS_IPM_NODEV_NOPHY);
1936 
1937         mutex_exit(&si_portp->siport_mutex);
1938         return (SATA_SUCCESS);
1939 }
1940 
1941 
1942 /*
1943  * Allocates the si_port_state_t.
1944  */
1945 static int
1946 si_alloc_port_state(si_ctl_state_t *si_ctlp, int port)
1947 {
1948         si_port_state_t *si_portp;
1949 
1950         si_ctlp->sictl_ports[port] = (si_port_state_t *)kmem_zalloc(
1951             sizeof (si_port_state_t), KM_SLEEP);
1952 
1953         si_portp = si_ctlp->sictl_ports[port];
1954         mutex_init(&si_portp->siport_mutex, NULL, MUTEX_DRIVER,
1955             (void *)(uintptr_t)si_ctlp->sictl_intr_pri);
1956         mutex_enter(&si_portp->siport_mutex);
1957 
1958         /* allocate prb & sgt pkts for this port. */
1959         if (si_alloc_prbpool(si_ctlp, port)) {
1960                 mutex_exit(&si_portp->siport_mutex);
1961                 kmem_free(si_ctlp->sictl_ports[port], sizeof (si_port_state_t));
1962                 return (SI_FAILURE);
1963         }
1964         if (si_alloc_sgbpool(si_ctlp, port)) {
1965                 si_dealloc_prbpool(si_ctlp, port);
1966                 mutex_exit(&si_portp->siport_mutex);
1967                 kmem_free(si_ctlp->sictl_ports[port], sizeof (si_port_state_t));
1968                 return (SI_FAILURE);
1969         }
1970 
1971         /* Allocate the argument for the timeout */
1972         si_portp->siport_event_args =
1973             kmem_zalloc(sizeof (si_event_arg_t), KM_SLEEP);
1974 
1975         si_portp->siport_active = PORT_ACTIVE;
1976         mutex_exit(&si_portp->siport_mutex);
1977 
1978         return (SI_SUCCESS);
1979 
1980 }
1981 
1982 /*
1983  * Deallocates the si_port_state_t.
1984  */
1985 static void
1986 si_dealloc_port_state(si_ctl_state_t *si_ctlp, int port)
1987 {
1988         si_port_state_t *si_portp;
1989         si_portp = si_ctlp->sictl_ports[port];
1990 
1991         mutex_enter(&si_portp->siport_mutex);
1992         kmem_free(si_portp->siport_event_args, sizeof (si_event_arg_t));
1993         si_dealloc_sgbpool(si_ctlp, port);
1994         si_dealloc_prbpool(si_ctlp, port);
1995         mutex_exit(&si_portp->siport_mutex);
1996 
1997         mutex_destroy(&si_portp->siport_mutex);
1998 
1999         kmem_free(si_ctlp->sictl_ports[port], sizeof (si_port_state_t));
2000 
2001 }
2002 
2003 /*
2004  * Allocates the SGB (Scatter Gather Block) incore buffer.
2005  */
2006 static int
2007 si_alloc_sgbpool(si_ctl_state_t *si_ctlp, int port)
2008 {
2009         si_port_state_t *si_portp;
2010         uint_t cookie_count;
2011         size_t incore_sgbpool_size = SI_NUM_SLOTS * sizeof (si_sgblock_t)
2012             * si_dma_sg_number;
2013         size_t ret_len;
2014         ddi_dma_cookie_t sgbpool_dma_cookie;
2015 
2016         si_portp = si_ctlp->sictl_ports[port];
2017 
2018         /* allocate sgbpool dma handle. */
2019         if (ddi_dma_alloc_handle(si_ctlp->sictl_devinfop,
2020             &prb_sgt_dma_attr,
2021             DDI_DMA_SLEEP,
2022             NULL,
2023             &si_portp->siport_sgbpool_dma_handle) !=
2024             DDI_SUCCESS) {
2025 
2026                 return (SI_FAILURE);
2027         }
2028 
2029         /* allocate the memory for sgbpool. */
2030         if (ddi_dma_mem_alloc(si_portp->siport_sgbpool_dma_handle,
2031             incore_sgbpool_size,
2032             &accattr,
2033             DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2034             DDI_DMA_SLEEP,
2035             NULL,
2036             (caddr_t *)&si_portp->siport_sgbpool,
2037             &ret_len,
2038             &si_portp->siport_sgbpool_acc_handle) != NULL) {
2039 
2040                 /*  error.. free the dma handle. */
2041                 ddi_dma_free_handle(&si_portp->siport_sgbpool_dma_handle);
2042                 return (SI_FAILURE);
2043         }
2044 
2045         /* now bind it */
2046         if (ddi_dma_addr_bind_handle(si_portp->siport_sgbpool_dma_handle,
2047             NULL,
2048             (caddr_t)si_portp->siport_sgbpool,
2049             incore_sgbpool_size,
2050             DDI_DMA_CONSISTENT,
2051             DDI_DMA_SLEEP,
2052             NULL,
2053             &sgbpool_dma_cookie,
2054             &cookie_count) !=  DDI_DMA_MAPPED) {
2055                 /*  error.. free the dma handle & free the memory. */
2056                 ddi_dma_mem_free(&si_portp->siport_sgbpool_acc_handle);
2057                 ddi_dma_free_handle(&si_portp->siport_sgbpool_dma_handle);
2058                 return (SI_FAILURE);
2059         }
2060 
2061         si_portp->siport_sgbpool_physaddr = sgbpool_dma_cookie.dmac_laddress;
2062         return (SI_SUCCESS);
2063 }
2064 
2065 /*
2066  * Deallocates the SGB (Scatter Gather Block) incore buffer.
2067  */
2068 static void
2069 si_dealloc_sgbpool(si_ctl_state_t *si_ctlp, int port)
2070 {
2071         si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
2072 
2073         /* Unbind the dma handle first. */
2074         (void) ddi_dma_unbind_handle(si_portp->siport_sgbpool_dma_handle);
2075 
2076         /* Then free the underlying memory. */
2077         ddi_dma_mem_free(&si_portp->siport_sgbpool_acc_handle);
2078 
2079         /* Now free the handle itself. */
2080         ddi_dma_free_handle(&si_portp->siport_sgbpool_dma_handle);
2081 
2082 }
2083 
2084 /*
2085  * Allocates the PRB (Port Request Block) incore packets.
2086  */
2087 static int
2088 si_alloc_prbpool(si_ctl_state_t *si_ctlp, int port)
2089 {
2090         si_port_state_t *si_portp;
2091         uint_t cookie_count;
2092         size_t incore_pkt_size = SI_NUM_SLOTS * sizeof (si_prb_t);
2093         size_t ret_len;
2094         ddi_dma_cookie_t prbpool_dma_cookie;
2095 
2096         si_portp = si_ctlp->sictl_ports[port];
2097 
2098         /* allocate prb pkts. */
2099         if (ddi_dma_alloc_handle(si_ctlp->sictl_devinfop,
2100             &prb_sgt_dma_attr,
2101             DDI_DMA_SLEEP,
2102             NULL,
2103             &si_portp->siport_prbpool_dma_handle) !=
2104             DDI_SUCCESS) {
2105 
2106                 return (SI_FAILURE);
2107         }
2108 
2109         if (ddi_dma_mem_alloc(si_portp->siport_prbpool_dma_handle,
2110             incore_pkt_size,
2111             &accattr,
2112             DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2113             DDI_DMA_SLEEP,
2114             NULL,
2115             (caddr_t *)&si_portp->siport_prbpool,
2116             &ret_len,
2117             &si_portp->siport_prbpool_acc_handle) != NULL) {
2118 
2119                 /* error.. free the dma handle. */
2120                 ddi_dma_free_handle(&si_portp->siport_prbpool_dma_handle);
2121                 return (SI_FAILURE);
2122         }
2123 
2124         if (ddi_dma_addr_bind_handle(si_portp->siport_prbpool_dma_handle,
2125             NULL,
2126             (caddr_t)si_portp->siport_prbpool,
2127             incore_pkt_size,
2128             DDI_DMA_CONSISTENT,
2129             DDI_DMA_SLEEP,
2130             NULL,
2131             &prbpool_dma_cookie,
2132             &cookie_count) !=  DDI_DMA_MAPPED) {
2133                 /*  error.. free the dma handle & free the memory. */
2134                 ddi_dma_mem_free(&si_portp->siport_prbpool_acc_handle);
2135                 ddi_dma_free_handle(&si_portp->siport_prbpool_dma_handle);
2136                 return (SI_FAILURE);
2137         }
2138 
2139         si_portp->siport_prbpool_physaddr =
2140             prbpool_dma_cookie.dmac_laddress;
2141         return (SI_SUCCESS);
2142 }
2143 
2144 /*
2145  * Deallocates the PRB (Port Request Block) incore packets.
2146  */
2147 static void
2148 si_dealloc_prbpool(si_ctl_state_t *si_ctlp, int port)
2149 {
2150         si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
2151 
2152         /* Unbind the prb dma handle first. */
2153         (void) ddi_dma_unbind_handle(si_portp->siport_prbpool_dma_handle);
2154 
2155         /* Then free the underlying memory. */
2156         ddi_dma_mem_free(&si_portp->siport_prbpool_acc_handle);
2157 
2158         /* Now free the handle itself. */
2159         ddi_dma_free_handle(&si_portp->siport_prbpool_dma_handle);
2160 
2161 }
2162 
2163 
2164 
2165 /*
2166  * Soft-reset the port to find the signature of the device connected to
2167  * the port.
2168  */
2169 static void
2170 si_find_dev_signature(
2171         si_ctl_state_t *si_ctlp,
2172         si_port_state_t *si_portp,
2173         int port,
2174         int pmp)
2175 {
2176         si_prb_t *prb;
2177         uint32_t slot_status, signature;
2178         int slot, loop_count;
2179 
2180         SIDBG_P(SIDBG_INIT, si_portp,
2181             "si_find_dev_signature enter: port: %x, pmp: %x",
2182             port, pmp);
2183 
2184         /* Build a Soft Reset PRB in host memory. */
2185         mutex_enter(&si_portp->siport_mutex);
2186 
2187         slot = si_claim_free_slot(si_ctlp, si_portp, port);
2188         if (slot == SI_FAILURE) {
2189                 /* Empty slot could not be found. */
2190                 if (pmp != PORTMULT_CONTROL_PORT) {
2191                         /* We are behind port multiplier. */
2192                         si_portp->siport_portmult_state.sipm_port_type[pmp] =
2193                             PORT_TYPE_NODEV;
2194                 } else {
2195                         si_portp->siport_port_type = PORT_TYPE_NODEV;
2196                 }
2197 
2198                 mutex_exit(&si_portp->siport_mutex);
2199                 return;
2200         }
2201         prb = &si_portp->siport_prbpool[slot];
2202         bzero((void *)prb, sizeof (si_prb_t));
2203 
2204         SET_FIS_PMP(prb->prb_fis, pmp);
2205         SET_PRB_CONTROL_SOFT_RESET(prb);
2206 
2207 #if SI_DEBUG
2208         if (si_debug_flags & SIDBG_DUMP_PRB) {
2209                 char *ptr;
2210                 int j;
2211 
2212                 ptr = (char *)prb;
2213                 cmn_err(CE_WARN, "si_find_dev_signature, prb: ");
2214                 for (j = 0; j < (sizeof (si_prb_t)); j++) {
2215                         if (j%4 == 0) {
2216                                 cmn_err(CE_WARN, "----");
2217                         }
2218                         cmn_err(CE_WARN, "%x ", ptr[j]);
2219                 }
2220 
2221         }
2222 #endif /* SI_DEBUG */
2223 
2224         /* deliver soft reset prb to empty slot. */
2225         POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
2226 
2227         loop_count = 0;
2228         /* Loop till the soft reset is finished. */
2229         do {
2230                 slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
2231                     (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
2232 
2233                 if (loop_count++ > SI_POLLRATE_SOFT_RESET) {
2234                         /* We are effectively timing out after 10 sec. */
2235                         break;
2236                 }
2237 
2238                 /* Wait for 10 millisec */
2239 #ifndef __lock_lint
2240                 delay(SI_10MS_TICKS);
2241 #endif /* __lock_lint */
2242 
2243         } while (slot_status & SI_SLOT_MASK & (0x1 << slot));
2244 
2245         SIDBG_P(SIDBG_POLL_LOOP, si_portp,
2246             "si_find_dev_signature: loop count: %d, slot_status: 0x%x",
2247             loop_count, slot_status);
2248 
2249         CLEAR_BIT(si_portp->siport_pending_tags, slot);
2250 
2251         /* Read device signature from command slot. */
2252         signature = ddi_get32(si_ctlp->sictl_port_acc_handle,
2253             (uint32_t *)(PORT_SIGNATURE_MSB(si_ctlp, port, slot)));
2254         signature <<= 8;
2255         signature |= (0xff & ddi_get32(si_ctlp->sictl_port_acc_handle,
2256             (uint32_t *)(PORT_SIGNATURE_LSB(si_ctlp,
2257             port, slot))));
2258 
2259         SIDBG_P(SIDBG_INIT, si_portp, "Device signature: 0x%x", signature);
2260 
2261         if (signature == SI_SIGNATURE_PORT_MULTIPLIER) {
2262 
2263                 SIDBG_P(SIDBG_INIT, si_portp,
2264                     "Found multiplier at cport: 0x%d, pmport: 0x%x",
2265                     port, pmp);
2266 
2267                 if (pmp != PORTMULT_CONTROL_PORT) {
2268                         /*
2269                          * It is wrong to chain a port multiplier behind
2270                          * another port multiplier.
2271                          */
2272                         si_portp->siport_portmult_state.sipm_port_type[pmp] =
2273                             PORT_TYPE_NODEV;
2274                 } else {
2275                         si_portp->siport_port_type = PORT_TYPE_MULTIPLIER;
2276                         mutex_exit(&si_portp->siport_mutex);
2277                         (void) si_enumerate_port_multiplier(si_ctlp,
2278                             si_portp, port);
2279                         mutex_enter(&si_portp->siport_mutex);
2280                 }
2281                 si_init_port(si_ctlp, port);
2282 
2283         } else if (signature == SI_SIGNATURE_ATAPI) {
2284                 if (pmp != PORTMULT_CONTROL_PORT) {
2285                         /* We are behind port multiplier. */
2286                         si_portp->siport_portmult_state.sipm_port_type[pmp] =
2287                             PORT_TYPE_ATAPI;
2288                 } else {
2289                         si_portp->siport_port_type = PORT_TYPE_ATAPI;
2290                         si_init_port(si_ctlp, port);
2291                 }
2292                 SIDBG_P(SIDBG_INIT, si_portp,
2293                     "Found atapi at : cport: %x, pmport: %x",
2294                     port, pmp);
2295 
2296         } else if (signature == SI_SIGNATURE_DISK) {
2297 
2298                 if (pmp != PORTMULT_CONTROL_PORT) {
2299                         /* We are behind port multiplier. */
2300                         si_portp->siport_portmult_state.sipm_port_type[pmp] =
2301                             PORT_TYPE_DISK;
2302                 } else {
2303                         si_portp->siport_port_type = PORT_TYPE_DISK;
2304                         si_init_port(si_ctlp, port);
2305                 }
2306                 SIDBG_P(SIDBG_INIT, si_portp,
2307                     "found disk at : cport: %x, pmport: %x",
2308                     port, pmp);
2309 
2310         } else {
2311                 if (pmp != PORTMULT_CONTROL_PORT) {
2312                         /* We are behind port multiplier. */
2313                         si_portp->siport_portmult_state.sipm_port_type[pmp] =
2314                             PORT_TYPE_UNKNOWN;
2315                 } else {
2316                         si_portp->siport_port_type = PORT_TYPE_UNKNOWN;
2317                 }
2318                 SIDBG_P(SIDBG_INIT, si_portp,
2319                     "Found unknown signature 0x%x at: port: %x, pmp: %x",
2320                     signature, port, pmp);
2321         }
2322 
2323         mutex_exit(&si_portp->siport_mutex);
2324 }
2325 
2326 
2327 /*
2328  * Polls for the completion of the command. This is safe with both
2329  * interrupts enabled or disabled.
2330  */
2331 static void
2332 si_poll_cmd(
2333         si_ctl_state_t *si_ctlp,
2334         si_port_state_t *si_portp,
2335         int port,
2336         int slot,
2337         sata_pkt_t *satapkt)
2338 {
2339         uint32_t slot_status;
2340         int pkt_timeout_ticks;
2341         uint32_t port_intr_status;
2342         int in_panic = ddi_in_panic();
2343 
2344         SIDBG_P(SIDBG_ENTRY, si_portp, "si_poll_cmd entered: port: 0x%x", port);
2345 
2346         pkt_timeout_ticks = drv_usectohz((clock_t)satapkt->satapkt_time *
2347             1000000);
2348 
2349 
2350         /* we start out with SATA_PKT_COMPLETED as the satapkt_reason */
2351         satapkt->satapkt_reason = SATA_PKT_COMPLETED;
2352 
2353         do {
2354                 slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
2355                     (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
2356 
2357                 if (slot_status & SI_SLOT_MASK & (0x1 << slot)) {
2358                         if (in_panic) {
2359                                 /*
2360                                  * If we are in panic, we can't rely on
2361                                  * timers; so, busy wait instead of delay().
2362                                  */
2363                                 mutex_exit(&si_portp->siport_mutex);
2364                                 drv_usecwait(SI_1MS_USECS);
2365                                 mutex_enter(&si_portp->siport_mutex);
2366                         } else {
2367                                 mutex_exit(&si_portp->siport_mutex);
2368 #ifndef __lock_lint
2369                                 delay(SI_1MS_TICKS);
2370 #endif /* __lock_lint */
2371                                 mutex_enter(&si_portp->siport_mutex);
2372                         }
2373                 } else {
2374                         break;
2375                 }
2376 
2377                 pkt_timeout_ticks -= SI_1MS_TICKS;
2378 
2379         } while (pkt_timeout_ticks > 0);
2380 
2381         if (satapkt->satapkt_reason != SATA_PKT_COMPLETED) {
2382                 /* The si_mop_command() got to our packet before us */
2383 
2384                 return;
2385         }
2386 
2387         /*
2388          * Interrupts and timers may not be working properly in a crash dump
2389          * situation; we may need to handle all the three conditions here:
2390          * successful completion, packet failure and packet timeout.
2391          */
2392         if (IS_ATTENTION_RAISED(slot_status)) { /* error seen on port */
2393 
2394                 port_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
2395                     (uint32_t *)PORT_INTERRUPT_STATUS(si_ctlp, port));
2396 
2397                 SIDBG_P(SIDBG_VERBOSE, si_portp,
2398                     "si_poll_cmd: port_intr_status: 0x%x, port: %x",
2399                     port_intr_status, port);
2400 
2401                 if (port_intr_status & INTR_COMMAND_ERROR) {
2402                         mutex_exit(&si_portp->siport_mutex);
2403                         (void) si_intr_command_error(si_ctlp, si_portp, port);
2404                         mutex_enter(&si_portp->siport_mutex);
2405 
2406                         return;
2407 
2408                         /*
2409                          * Why do we need to call si_intr_command_error() ?
2410                          *
2411                          * Answer: Even if the current packet is not the
2412                          * offending command, we need to restart the stalled
2413                          * port; (may be, the interrupts are not working well
2414                          * in panic condition). The call to routine
2415                          * si_intr_command_error() will achieve that.
2416                          *
2417                          * What if the interrupts are working fine and the
2418                          * si_intr_command_error() gets called once more from
2419                          * interrupt context ?
2420                          *
2421                          * Answer: The second instance of routine
2422                          * si_intr_command_error() will not mop anything
2423                          * since the first error handler has already blown
2424                          * away the hardware pending queues through reset.
2425                          *
2426                          * Will the si_intr_command_error() hurt current
2427                          * packet ?
2428                          *
2429                          * Answer: No.
2430                          */
2431                 } else {
2432                         /* Ignore any non-error interrupts at this stage */
2433                         ddi_put32(si_ctlp->sictl_port_acc_handle,
2434                             (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp,
2435                             port)),
2436                             port_intr_status & INTR_MASK);
2437                 }
2438 
2439         } else if (slot_status & SI_SLOT_MASK & (0x1 << slot)) {
2440                 satapkt->satapkt_reason = SATA_PKT_TIMEOUT;
2441 
2442         } /* else: the command completed successfully */
2443 
2444         if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
2445                 si_copy_out_regs(&satapkt->satapkt_cmd, si_ctlp, port, slot);
2446         }
2447 
2448         if ((satapkt->satapkt_cmd.satacmd_cmd_reg ==
2449             SATAC_WRITE_FPDMA_QUEUED) ||
2450             (satapkt->satapkt_cmd.satacmd_cmd_reg ==
2451             SATAC_READ_FPDMA_QUEUED)) {
2452                 si_portp->siport_pending_ncq_count--;
2453         }
2454 
2455         CLEAR_BIT(si_portp->siport_pending_tags, slot);
2456 
2457         /*
2458          * tidbit: What is the interaction of abort with polling ?
2459          * What happens if the current polled pkt is aborted in parallel ?
2460          *
2461          * Answer: Assuming that the si_mop_commands() completes ahead
2462          * of polling, all it does is to set the satapkt_reason to
2463          * SPKT_PKT_ABORTED. That would be fine with us.
2464          *
2465          * The same logic applies to reset interacting with polling.
2466          */
2467 }
2468 
2469 
2470 /*
2471  * Searches for and claims a free slot.
2472  *
2473  * Returns:     SI_FAILURE if no slots found
2474  *              claimed slot number if successful
2475  *
2476  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
2477  * before calling us.
2478  */
2479 /*ARGSUSED*/
2480 static int
2481 si_claim_free_slot(si_ctl_state_t *si_ctlp, si_port_state_t *si_portp, int port)
2482 {
2483         uint32_t free_slots;
2484         int slot;
2485 
2486         _NOTE(ASSUMING_PROTECTED(si_portp))
2487 
2488         SIDBG_P(SIDBG_ENTRY, si_portp,
2489             "si_claim_free_slot entry: siport_pending_tags: %x",
2490             si_portp->siport_pending_tags);
2491 
2492         free_slots = (~si_portp->siport_pending_tags) & SI_SLOT_MASK;
2493         slot = ddi_ffs(free_slots) - 1;
2494         if (slot == -1) {
2495                 SIDBG_P(SIDBG_VERBOSE, si_portp,
2496                     "si_claim_free_slot: no empty slots", NULL);
2497                 return (SI_FAILURE);
2498         }
2499 
2500         si_portp->siport_pending_tags |= (0x1 << slot);
2501         SIDBG_P(SIDBG_VERBOSE, si_portp, "si_claim_free_slot: found slot: 0x%x",
2502             slot);
2503         return (slot);
2504 }
2505 
2506 /*
2507  * Builds the PRB for the sata packet and delivers it to controller.
2508  *
2509  * Returns:
2510  *      slot number if we can obtain a slot successfully
2511  *      otherwise, return SI_FAILURE
2512  *
2513  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
2514  * before calling us.
2515  */
2516 static int
2517 si_deliver_satapkt(
2518         si_ctl_state_t *si_ctlp,
2519         si_port_state_t *si_portp,
2520         int port,
2521         sata_pkt_t *spkt)
2522 {
2523         int slot;
2524         si_prb_t *prb;
2525         sata_cmd_t *cmd;
2526         si_sge_t *sgep; /* scatter gather entry pointer */
2527         si_sgt_t *sgtp; /* scatter gather table pointer */
2528         si_sgblock_t *sgbp; /* scatter gather block pointer */
2529         int i, j, cookie_index;
2530         int ncookies;
2531         int is_atapi = 0;
2532         ddi_dma_cookie_t cookie;
2533 
2534         _NOTE(ASSUMING_PROTECTED(si_portp))
2535 
2536         slot = si_claim_free_slot(si_ctlp, si_portp, port);
2537         if (slot == SI_FAILURE) {
2538                 return (SI_FAILURE);
2539         }
2540 
2541         if (spkt->satapkt_device.satadev_type == SATA_DTYPE_ATAPICD) {
2542                 is_atapi = 1;
2543         }
2544 
2545         if ((si_portp->siport_port_type == PORT_TYPE_NODEV) ||
2546             !si_portp->siport_active) {
2547                 /*
2548                  * si_intr_phy_ready_change() may have rendered it to
2549                  * PORT_TYPE_NODEV. cfgadm operation may have rendered
2550                  * it inactive.
2551                  */
2552                 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
2553                 fill_dev_sregisters(si_ctlp, port, &spkt->satapkt_device);
2554                 CLEAR_BIT(si_portp->siport_pending_tags, slot);
2555 
2556                 return (SI_FAILURE);
2557         }
2558 
2559 
2560         prb =  &(si_portp->siport_prbpool[slot]);
2561         bzero((void *)prb, sizeof (si_prb_t));
2562 
2563         cmd = &spkt->satapkt_cmd;
2564 
2565         SIDBG_P(SIDBG_ENTRY, si_portp,
2566             "si_deliver_satpkt entry: cmd_reg: 0x%x, slot: 0x%x, \
2567                 port: %x, satapkt: %x",
2568             cmd->satacmd_cmd_reg, slot, port, (uint32_t)(intptr_t)spkt);
2569 
2570         /* Now fill the prb. */
2571         if (is_atapi) {
2572                 if (spkt->satapkt_cmd.satacmd_flags.sata_data_direction ==
2573                     SATA_DIR_READ) {
2574                         SET_PRB_CONTROL_PKT_READ(prb);
2575                 } else if (spkt->satapkt_cmd.satacmd_flags.sata_data_direction
2576                     == SATA_DIR_WRITE) {
2577                         SET_PRB_CONTROL_PKT_WRITE(prb);
2578                 }
2579         }
2580 
2581         SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
2582         if ((spkt->satapkt_device.satadev_addr.qual == SATA_ADDR_PMPORT) ||
2583             (spkt->satapkt_device.satadev_addr.qual == SATA_ADDR_DPMPORT)) {
2584                 SET_FIS_PMP(prb->prb_fis,
2585                     spkt->satapkt_device.satadev_addr.pmport);
2586         }
2587         SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
2588         SET_FIS_COMMAND(prb->prb_fis, cmd->satacmd_cmd_reg);
2589         SET_FIS_FEATURES(prb->prb_fis, cmd->satacmd_features_reg);
2590         SET_FIS_SECTOR_COUNT(prb->prb_fis, cmd->satacmd_sec_count_lsb);
2591 
2592         switch (cmd->satacmd_addr_type) {
2593 
2594         case 0:
2595                 /*
2596                  * satacmd_addr_type will be 0 for the commands below:
2597                  *      SATAC_PACKET
2598                  *      SATAC_IDLE_IM
2599                  *      SATAC_STANDBY_IM
2600                  *      SATAC_DOWNLOAD_MICROCODE
2601                  *      SATAC_FLUSH_CACHE
2602                  *      SATAC_SET_FEATURES
2603                  *      SATAC_SMART
2604                  *      SATAC_ID_PACKET_DEVICE
2605                  *      SATAC_ID_DEVICE
2606                  *      SATAC_READ_PORTMULT
2607                  *      SATAC_WRITE_PORTMULT
2608                  */
2609                 /* FALLTHRU */
2610 
2611         case ATA_ADDR_LBA:
2612                 /* FALLTHRU */
2613 
2614         case ATA_ADDR_LBA28:
2615                 /* LBA[7:0] */
2616                 SET_FIS_SECTOR(prb->prb_fis, cmd->satacmd_lba_low_lsb);
2617 
2618                 /* LBA[15:8] */
2619                 SET_FIS_CYL_LOW(prb->prb_fis, cmd->satacmd_lba_mid_lsb);
2620 
2621                 /* LBA[23:16] */
2622                 SET_FIS_CYL_HI(prb->prb_fis, cmd->satacmd_lba_high_lsb);
2623 
2624                 /* LBA [27:24] (also called dev_head) */
2625                 SET_FIS_DEV_HEAD(prb->prb_fis, cmd->satacmd_device_reg);
2626 
2627                 break;
2628 
2629         case ATA_ADDR_LBA48:
2630                 /* LBA[7:0] */
2631                 SET_FIS_SECTOR(prb->prb_fis, cmd->satacmd_lba_low_lsb);
2632 
2633                 /* LBA[15:8] */
2634                 SET_FIS_CYL_LOW(prb->prb_fis, cmd->satacmd_lba_mid_lsb);
2635 
2636                 /* LBA[23:16] */
2637                 SET_FIS_CYL_HI(prb->prb_fis, cmd->satacmd_lba_high_lsb);
2638 
2639                 /* LBA [31:24] */
2640                 SET_FIS_SECTOR_EXP(prb->prb_fis, cmd->satacmd_lba_low_msb);
2641 
2642                 /* LBA [39:32] */
2643                 SET_FIS_CYL_LOW_EXP(prb->prb_fis, cmd->satacmd_lba_mid_msb);
2644 
2645                 /* LBA [47:40] */
2646                 SET_FIS_CYL_HI_EXP(prb->prb_fis, cmd->satacmd_lba_high_msb);
2647 
2648                 /* Set dev_head */
2649                 SET_FIS_DEV_HEAD(prb->prb_fis, cmd->satacmd_device_reg);
2650 
2651                 /* Set the extended sector count and features */
2652                 SET_FIS_SECTOR_COUNT_EXP(prb->prb_fis,
2653                     cmd->satacmd_sec_count_msb);
2654                 SET_FIS_FEATURES_EXP(prb->prb_fis,
2655                     cmd->satacmd_features_reg_ext);
2656 
2657                 break;
2658 
2659         }
2660 
2661         if (cmd->satacmd_flags.sata_queued) {
2662                 /*
2663                  * For queued commands, the TAG for the sector count lsb is
2664                  * generated from current slot number.
2665                  */
2666                 SET_FIS_SECTOR_COUNT(prb->prb_fis, slot << 3);
2667         }
2668 
2669         if ((cmd->satacmd_cmd_reg == SATAC_WRITE_FPDMA_QUEUED) ||
2670             (cmd->satacmd_cmd_reg == SATAC_READ_FPDMA_QUEUED)) {
2671                 si_portp->siport_pending_ncq_count++;
2672         }
2673 
2674         /* *** now fill the scatter gather list ******* */
2675 
2676         if (is_atapi) { /* It is an ATAPI drive */
2677                 /* atapi command goes into sge0 */
2678                 bcopy(cmd->satacmd_acdb, &prb->prb_sge0, sizeof (si_sge_t));
2679 
2680                 /* Now fill sge1 with pointer to external SGT. */
2681                 if (spkt->satapkt_cmd.satacmd_num_dma_cookies) {
2682                         prb->prb_sge1.sge_addr =
2683                             si_portp->siport_sgbpool_physaddr +
2684                             slot * sizeof (si_sgblock_t) * si_dma_sg_number;
2685                         SET_SGE_LNK(prb->prb_sge1);
2686                 } else {
2687                         SET_SGE_TRM(prb->prb_sge1);
2688                 }
2689         } else {
2690                 /* Fill the sge0 */
2691                 if (spkt->satapkt_cmd.satacmd_num_dma_cookies) {
2692                         prb->prb_sge0.sge_addr =
2693                             si_portp->siport_sgbpool_physaddr +
2694                             slot * sizeof (si_sgblock_t) * si_dma_sg_number;
2695                         SET_SGE_LNK(prb->prb_sge0);
2696 
2697                 } else {
2698                         SET_SGE_TRM(prb->prb_sge0);
2699                 }
2700 
2701                 /* sge1 is left empty in non-ATAPI case */
2702         }
2703 
2704         bzero(&si_portp->siport_sgbpool[slot * si_dma_sg_number],
2705             sizeof (si_sgblock_t) * si_dma_sg_number);
2706 
2707         ncookies = spkt->satapkt_cmd.satacmd_num_dma_cookies;
2708         ASSERT(ncookies <= (SGE_LENGTH(si_dma_sg_number)));
2709 
2710         SIDBG_P(SIDBG_COOKIES, si_portp, "total ncookies: %d", ncookies);
2711         if (ncookies == 0) {
2712                 sgbp = &si_portp->siport_sgbpool[slot * si_dma_sg_number];
2713                 sgtp = &sgbp->sgb_sgt[0];
2714                 sgep = &sgtp->sgt_sge[0];
2715 
2716                 /* No cookies. Terminate the chain. */
2717                 SIDBG_P(SIDBG_COOKIES, si_portp, "empty cookies: terminating.",
2718                     NULL);
2719 
2720                 sgep->sge_addr_low = 0;
2721                 sgep->sge_addr_high = 0;
2722                 sgep->sge_data_count = 0;
2723                 SET_SGE_TRM((*sgep));
2724 
2725                 goto sgl_fill_done;
2726         }
2727 
2728         for (i = 0, cookie_index = 0,
2729             sgbp = &si_portp->siport_sgbpool[slot * si_dma_sg_number];
2730             i < si_dma_sg_number; i++) {
2731 
2732                 sgtp = &sgbp->sgb_sgt[0] + i;
2733 
2734                 /* Now fill the first 3 entries of SGT in the loop below. */
2735                 for (j = 0, sgep = &sgtp->sgt_sge[0];
2736                     ((j < 3) && (cookie_index < ncookies-1));
2737                     j++, cookie_index++, sgep++)  {
2738                         ASSERT(cookie_index < ncookies);
2739                         SIDBG_P(SIDBG_COOKIES, si_portp,
2740                             "inner loop: cookie_index: %d, ncookies: %d",
2741                             cookie_index,
2742                             ncookies);
2743                         cookie = spkt->satapkt_cmd.
2744                             satacmd_dma_cookie_list[cookie_index];
2745 
2746                         sgep->sge_addr_low = cookie._dmu._dmac_la[0];
2747                         sgep->sge_addr_high = cookie._dmu._dmac_la[1];
2748                         sgep->sge_data_count = (uint32_t)cookie.dmac_size;
2749                 }
2750 
2751                 /*
2752                  * If this happens to be the last cookie, we terminate it here.
2753                  * Otherwise, we link to next SGT.
2754                  */
2755 
2756                 if (cookie_index == ncookies-1) {
2757                         /* This is the last cookie. Terminate the chain. */
2758                         SIDBG_P(SIDBG_COOKIES, si_portp,
2759                             "filling the last: cookie_index: %d, "
2760                             "ncookies: %d",
2761                             cookie_index,
2762                             ncookies);
2763                         cookie = spkt->satapkt_cmd.
2764                             satacmd_dma_cookie_list[cookie_index];
2765 
2766                         sgep->sge_addr_low = cookie._dmu._dmac_la[0];
2767                         sgep->sge_addr_high = cookie._dmu._dmac_la[1];
2768                         sgep->sge_data_count = (uint32_t)cookie.dmac_size;
2769                         SET_SGE_TRM((*sgep));
2770 
2771                         break; /* we break the loop */
2772 
2773                 } else {
2774                         /* This is not the last one. So link it. */
2775                         SIDBG_P(SIDBG_COOKIES, si_portp,
2776                             "linking SGT: cookie_index: %d, ncookies: %d",
2777                             cookie_index,
2778                             ncookies);
2779                         sgep->sge_addr = si_portp->siport_sgbpool_physaddr +
2780                             slot * sizeof (si_sgblock_t) * si_dma_sg_number +
2781                             (i+1) * sizeof (si_sgt_t);
2782 
2783                         SET_SGE_LNK((*sgep));
2784                 }
2785 
2786         }
2787 
2788         /* *** finished filling the scatter gather list ******* */
2789 
2790 sgl_fill_done:
2791         /* Now remember the sata packet in siport_slot_pkts[]. */
2792         si_portp->siport_slot_pkts[slot] = spkt;
2793 
2794         /*
2795          * We are overloading satapkt_hba_driver_private with
2796          * watched_cycle count.
2797          */
2798         spkt->satapkt_hba_driver_private = (void *)(intptr_t)0;
2799 
2800         if (is_atapi) {
2801                 /* program the packet_lenth if it is atapi device. */
2802 
2803 
2804 #ifdef ATAPI_2nd_PHASE
2805                 /*
2806                  * Framework needs to calculate the acdb_len based on
2807                  * identify packet data. This needs to be accomplished
2808                  * in second phase of the project.
2809                  */
2810                 ASSERT((cmd->satacmd_acdb_len == 12) ||
2811                     (cmd->satacmd_acdb_len == 16));
2812                 SIDBG_P(SIDBG_VERBOSE, si_portp, "deliver: acdb_len: %d",
2813                     cmd->satacmd_acdb_len);
2814 
2815                 if (cmd->satacmd_acdb_len == 16) {
2816                         ddi_put32(si_ctlp->sictl_port_acc_handle,
2817                             (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
2818                             PORT_CONTROL_SET_BITS_PACKET_LEN);
2819                 } else {
2820                         ddi_put32(si_ctlp->sictl_port_acc_handle,
2821                             (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
2822                             PORT_CONTROL_CLEAR_BITS_PACKET_LEN);
2823                 }
2824 
2825 #else /* ATAPI_2nd_PHASE */
2826                 /* hard coding for now to 12 bytes */
2827                 ddi_put32(si_ctlp->sictl_port_acc_handle,
2828                     (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
2829                     PORT_CONTROL_CLEAR_BITS_PACKET_LEN);
2830 #endif /* ATAPI_2nd_PHASE */
2831         }
2832 
2833 
2834 #if SI_DEBUG
2835         if (si_debug_flags & SIDBG_DUMP_PRB) {
2836                 if (!(is_atapi && (prb->prb_sge0.sge_addr_low == 0))) {
2837                         /*
2838                          * Do not dump the atapi Test-Unit-Ready commands.
2839                          * The sd_media_watch spews too many of these.
2840                          */
2841                         int *ptr;
2842                         si_sge_t *tmpsgep;
2843                         int j;
2844 
2845                         ptr = (int *)(void *)prb;
2846                         cmn_err(CE_WARN, "si_deliver_satpkt prb: ");
2847                         for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
2848                                 cmn_err(CE_WARN, "%x ", ptr[j]);
2849                         }
2850 
2851                         cmn_err(CE_WARN,
2852                             "si_deliver_satpkt sgt: low, high, count link");
2853                         for (j = 0,
2854                             tmpsgep = (si_sge_t *)
2855                             &si_portp->siport_sgbpool[slot * si_dma_sg_number];
2856                             j < (sizeof (si_sgblock_t)/ sizeof (si_sge_t))
2857                             *si_dma_sg_number;
2858                             j++, tmpsgep++) {
2859                                 ptr = (int *)(void *)tmpsgep;
2860                                 cmn_err(CE_WARN, "%x %x %x %x",
2861                                     ptr[0],
2862                                     ptr[1],
2863                                     ptr[2],
2864                                     ptr[3]);
2865                                 if (IS_SGE_TRM_SET((*tmpsgep))) {
2866                                         break;
2867                                 }
2868 
2869                         }
2870                 }
2871 
2872         }
2873 #endif  /* SI_DEBUG */
2874 
2875         /* Deliver PRB */
2876         POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
2877 
2878         return (slot);
2879 }
2880 
2881 /*
2882  * Initialize the controller and set up driver data structures.
2883  *
2884  * This routine can be called from three separate cases: DDI_ATTACH, PM_LEVEL_D0
2885  * and DDI_RESUME. The DDI_ATTACH case is different from other two cases; the
2886  * memory allocation & device signature probing are attempted only during
2887  * DDI_ATTACH case. In the case of PM_LEVEL_D0 & DDI_RESUME, we are starting
2888  * from a previously initialized state; so there is no need to allocate memory
2889  * or to attempt probing the device signatures.
2890  */
2891 static int
2892 si_initialize_controller(si_ctl_state_t *si_ctlp)
2893 {
2894         uint32_t port_status;
2895         uint32_t SStatus;
2896         uint32_t SControl;
2897         uint8_t port;
2898         int loop_count = 0;
2899         si_port_state_t *si_portp;
2900 
2901         SIDBG_C(SIDBG_INIT, si_ctlp,
2902             "si3124: si_initialize_controller entered", NULL);
2903 
2904         mutex_enter(&si_ctlp->sictl_mutex);
2905 
2906         /* Remove the Global Reset. */
2907         ddi_put32(si_ctlp->sictl_global_acc_handle,
2908             (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp),
2909             GLOBAL_CONTROL_REG_BITS_CLEAR);
2910 
2911         for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
2912 
2913                 if (si_ctlp->sictl_flags & SI_ATTACH) {
2914                         /*
2915                          * We allocate the port state only during attach
2916                          * sequence. We don't want to do it during
2917                          * suspend/resume sequence.
2918                          */
2919                         if (si_alloc_port_state(si_ctlp, port)) {
2920                                 mutex_exit(&si_ctlp->sictl_mutex);
2921                                 return (SI_FAILURE);
2922                         }
2923                 }
2924 
2925                 si_portp = si_ctlp->sictl_ports[port];
2926                 mutex_enter(&si_portp->siport_mutex);
2927                 si_portp->siport_ctlp = si_ctlp;
2928                 si_portp->siport_port_num = port;
2929 
2930                 /* Clear Port Reset. */
2931                 ddi_put32(si_ctlp->sictl_port_acc_handle,
2932                     (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
2933                     PORT_CONTROL_SET_BITS_PORT_RESET);
2934                 ddi_put32(si_ctlp->sictl_port_acc_handle,
2935                     (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
2936                     PORT_CONTROL_CLEAR_BITS_PORT_RESET);
2937 
2938                 /*
2939                  * Arm the interrupts for: Cmd completion, Cmd error,
2940                  * Port Ready, PM Change, PhyRdyChange, Commwake,
2941                  * UnrecFIS, Devxchanged, SDBNotify.
2942                  */
2943                 ddi_put32(si_ctlp->sictl_port_acc_handle,
2944                     (uint32_t *)PORT_INTERRUPT_ENABLE_SET(si_ctlp, port),
2945                     (INTR_COMMAND_COMPLETE |
2946                     INTR_COMMAND_ERROR |
2947                     INTR_PORT_READY |
2948                     INTR_POWER_CHANGE |
2949                     INTR_PHYRDY_CHANGE |
2950                     INTR_COMWAKE_RECEIVED |
2951                     INTR_UNRECOG_FIS |
2952                     INTR_DEV_XCHANGED |
2953                     INTR_SETDEVBITS_NOTIFY));
2954 
2955                 /* Now enable the interrupts. */
2956                 si_enable_port_interrupts(si_ctlp, port);
2957 
2958                 /*
2959                  * The following PHY initialization is redundant in
2960                  * in x86 since the BIOS anyway does this as part of
2961                  * device enumeration during the power up. But this
2962                  * is a required step in sparc since there is no BIOS.
2963                  *
2964                  * The way to initialize the PHY is to write a 1 and then
2965                  * a 0 to DET field of SControl register.
2966                  */
2967 
2968                 /*
2969                  * Fetch the current SControl before writing the
2970                  * DET part with 1
2971                  */
2972                 SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
2973                     (uint32_t *)PORT_SCONTROL(si_ctlp, port));
2974                 SCONTROL_SET_DET(SControl, SCONTROL_DET_COMRESET);
2975                 ddi_put32(si_ctlp->sictl_port_acc_handle,
2976                     (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
2977                     SControl);
2978 #ifndef __lock_lint
2979                 delay(SI_10MS_TICKS); /* give time for COMRESET to percolate */
2980 #endif /* __lock_lint */
2981 
2982                 /*
2983                  * Now fetch the SControl again and rewrite the
2984                  * DET part with 0
2985                  */
2986                 SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
2987                     (uint32_t *)PORT_SCONTROL(si_ctlp, port));
2988                 SCONTROL_SET_DET(SControl, SCONTROL_DET_NOACTION);
2989                 ddi_put32(si_ctlp->sictl_port_acc_handle,
2990                     (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
2991                     SControl);
2992 
2993                 /*
2994                  * PHY may be initialized by now. Check the DET field of
2995                  * SStatus to determine if there is a device present.
2996                  *
2997                  * The DET field is valid only if IPM field indicates that
2998                  * the interface is in active state.
2999                  */
3000 
3001                 loop_count = 0;
3002                 do {
3003                         SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
3004                             (uint32_t *)PORT_SSTATUS(si_ctlp, port));
3005 
3006                         if (SSTATUS_GET_IPM(SStatus) !=
3007                             SSTATUS_IPM_INTERFACE_ACTIVE) {
3008                                 /*
3009                                  * If the interface is not active, the DET field
3010                                  * is considered not accurate. So we want to
3011                                  * continue looping.
3012                                  */
3013                                 SSTATUS_SET_DET(SStatus,
3014                                     SSTATUS_DET_NODEV_NOPHY);
3015                         }
3016 
3017                         if (loop_count++ > SI_POLLRATE_SSTATUS) {
3018                                 /*
3019                                  * We are effectively timing out after 0.1 sec.
3020                                  */
3021                                 break;
3022                         }
3023 
3024                         /* Wait for 10 millisec */
3025 #ifndef __lock_lint
3026                         delay(SI_10MS_TICKS);
3027 #endif /* __lock_lint */
3028 
3029                 } while (SSTATUS_GET_DET(SStatus) !=
3030                     SSTATUS_DET_DEVPRESENT_PHYONLINE);
3031 
3032                 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3033                     "si_initialize_controller: 1st loop count: %d, "
3034                     "SStatus: 0x%x",
3035                     loop_count,
3036                     SStatus);
3037 
3038                 if ((SSTATUS_GET_IPM(SStatus) !=
3039                     SSTATUS_IPM_INTERFACE_ACTIVE) ||
3040                     (SSTATUS_GET_DET(SStatus) !=
3041                     SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
3042                         /*
3043                          * Either the port is not active or there
3044                          * is no device present.
3045                          */
3046                         si_ctlp->sictl_ports[port]->siport_port_type =
3047                             PORT_TYPE_NODEV;
3048                         mutex_exit(&si_portp->siport_mutex);
3049                         continue;
3050                 }
3051 
3052                 /* Wait until Port Ready */
3053                 loop_count = 0;
3054                 do {
3055                         port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3056                             (uint32_t *)PORT_STATUS(si_ctlp, port));
3057 
3058                         if (loop_count++ > SI_POLLRATE_PORTREADY) {
3059                                 /*
3060                                  * We are effectively timing out after 0.5 sec.
3061                                  */
3062                                 break;
3063                         }
3064 
3065                         /* Wait for 10 millisec */
3066 #ifndef __lock_lint
3067                         delay(SI_10MS_TICKS);
3068 #endif /* __lock_lint */
3069 
3070                 } while (!(port_status & PORT_STATUS_BITS_PORT_READY));
3071 
3072                 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3073                     "si_initialize_controller: 2nd loop count: %d",
3074                     loop_count);
3075 
3076                 if (si_ctlp->sictl_flags & SI_ATTACH) {
3077                         /*
3078                          * We want to probe for dev signature only during attach
3079                          * case. Don't do it during suspend/resume sequence.
3080                          */
3081                         if (port_status & PORT_STATUS_BITS_PORT_READY) {
3082                                 mutex_exit(&si_portp->siport_mutex);
3083                                 si_find_dev_signature(si_ctlp, si_portp, port,
3084                                     PORTMULT_CONTROL_PORT);
3085                                 mutex_enter(&si_portp->siport_mutex);
3086                         } else {
3087                                 si_ctlp->sictl_ports[port]->siport_port_type =
3088                                     PORT_TYPE_NODEV;
3089                         }
3090                 }
3091 
3092                 if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
3093                     si_check_port_handles(si_portp) != DDI_SUCCESS) {
3094                         ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3095                             DDI_SERVICE_LOST);
3096                         mutex_exit(&si_portp->siport_mutex);
3097                         mutex_exit(&si_ctlp->sictl_mutex);
3098                         return (SI_FAILURE);
3099                 }
3100 
3101                 mutex_exit(&si_portp->siport_mutex);
3102         }
3103 
3104         mutex_exit(&si_ctlp->sictl_mutex);
3105         return (SI_SUCCESS);
3106 }
3107 
3108 /*
3109  * Reverse of si_initialize_controller().
3110  *
3111  * WARNING, WARNING: The caller is expected to obtain the sictl_mutex
3112  * before calling us.
3113  */
3114 static void
3115 si_deinitialize_controller(si_ctl_state_t *si_ctlp)
3116 {
3117         int port;
3118 
3119         _NOTE(ASSUMING_PROTECTED(si_ctlp))
3120 
3121         SIDBG_C(SIDBG_INIT, si_ctlp,
3122             "si3124: si_deinitialize_controller entered", NULL);
3123 
3124         /* disable all the interrupts. */
3125         si_disable_all_interrupts(si_ctlp);
3126 
3127         if (si_ctlp->sictl_flags & SI_DETACH) {
3128                 /*
3129                  * We want to dealloc all the memory in detach case.
3130                  */
3131                 for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
3132                         si_dealloc_port_state(si_ctlp, port);
3133                 }
3134         }
3135 
3136 }
3137 
3138 /*
3139  * Prepare the port ready for usage.
3140  *
3141  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
3142  * before calling us.
3143  */
3144 static void
3145 si_init_port(si_ctl_state_t *si_ctlp, int port)
3146 {
3147 
3148         SIDBG_C(SIDBG_INIT, si_ctlp,
3149             "si_init_port entered: port: 0x%x",
3150             port);
3151 
3152         /* Initialize the port. */
3153         ddi_put32(si_ctlp->sictl_port_acc_handle,
3154             (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
3155             PORT_CONTROL_SET_BITS_PORT_INITIALIZE);
3156 
3157         /*
3158          * Clear the InterruptNCOR (Interrupt No Clear on Read).
3159          * This step ensures that a mere reading of slot_status will clear
3160          * the interrupt; no explicit clearing of interrupt condition
3161          * will be needed for successful completion of commands.
3162          */
3163         ddi_put32(si_ctlp->sictl_port_acc_handle,
3164             (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
3165             PORT_CONTROL_CLEAR_BITS_INTR_NCoR);
3166 
3167         /* clear any pending interrupts at this point */
3168         ddi_put32(si_ctlp->sictl_port_acc_handle,
3169             (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp, port)),
3170             INTR_MASK);
3171 
3172 }
3173 
3174 
3175 /*
3176  * Enumerate the devices connected to the port multiplier.
3177  * Once a device is detected, we call si_find_dev_signature()
3178  * to find the type of device connected. Even though we are
3179  * called from within si_find_dev_signature(), there is no
3180  * recursion possible.
3181  */
3182 static int
3183 si_enumerate_port_multiplier(
3184         si_ctl_state_t *si_ctlp,
3185         si_port_state_t *si_portp,
3186         int port)
3187 {
3188         uint32_t num_dev_ports = 0;
3189         int pmport;
3190         uint32_t SControl = 0;
3191         uint32_t SStatus = 0;
3192         uint32_t SError = 0;
3193         int loop_count = 0;
3194 
3195         SIDBG_P(SIDBG_INIT, si_portp,
3196             "si_enumerate_port_multiplier entered: port: %d",
3197             port);
3198 
3199         mutex_enter(&si_portp->siport_mutex);
3200 
3201         /* Enable Port Multiplier context switching. */
3202         ddi_put32(si_ctlp->sictl_port_acc_handle,
3203             (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
3204             PORT_CONTROL_SET_BITS_PM_ENABLE);
3205 
3206         /*
3207          * Read the num dev ports connected.
3208          * GSCR[2] contains the number of device ports.
3209          */
3210         if (si_read_portmult_reg(si_ctlp, si_portp, port, PORTMULT_CONTROL_PORT,
3211             PSCR_REG2, &num_dev_ports)) {
3212                 mutex_exit(&si_portp->siport_mutex);
3213                 return (SI_FAILURE);
3214         }
3215         si_portp->siport_portmult_state.sipm_num_ports = num_dev_ports;
3216 
3217         SIDBG_P(SIDBG_INIT, si_portp,
3218             "si_enumerate_port_multiplier: ports found: %d",
3219             num_dev_ports);
3220 
3221         for (pmport = 0; pmport < num_dev_ports-1; pmport++) {
3222                 /*
3223                  * Enable PHY by writing a 1, then a 0 to SControl
3224                  * (i.e. PSCR[2]) DET field.
3225                  */
3226                 if (si_read_portmult_reg(si_ctlp, si_portp, port, pmport,
3227                     PSCR_REG2, &SControl)) {
3228                         continue;
3229                 }
3230 
3231                 /* First write a 1 to DET field of SControl. */
3232                 SCONTROL_SET_DET(SControl, SCONTROL_DET_COMRESET);
3233                 if (si_write_portmult_reg(si_ctlp, si_portp, port, pmport,
3234                     PSCR_REG2, SControl)) {
3235                         continue;
3236                 }
3237 #ifndef __lock_lint
3238                 delay(SI_10MS_TICKS); /* give time for COMRESET to percolate */
3239 #endif /* __lock_lint */
3240 
3241                 /* Then write a 0 to the DET field of SControl. */
3242                 SCONTROL_SET_DET(SControl, SCONTROL_DET_NOACTION);
3243                 if (si_write_portmult_reg(si_ctlp, si_portp, port, pmport,
3244                     PSCR_REG2, SControl)) {
3245                         continue;
3246                 }
3247 
3248                 /* Wait for PHYRDY by polling SStatus (i.e. PSCR[0]). */
3249                 loop_count = 0;
3250                 do {
3251                         if (si_read_portmult_reg(si_ctlp, si_portp, port,
3252                             pmport, PSCR_REG0, &SStatus)) {
3253                                 break;
3254                         }
3255                         SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3256                             "looping for PHYRDY: SStatus: %x",
3257                             SStatus);
3258 
3259                         if (SSTATUS_GET_IPM(SStatus) !=
3260                             SSTATUS_IPM_INTERFACE_ACTIVE) {
3261                                 /*
3262                                  * If the interface is not active, the DET field
3263                                  * is considered not accurate. So we want to
3264                                  * continue looping.
3265                                  */
3266                                 SSTATUS_SET_DET(SStatus,
3267                                     SSTATUS_DET_NODEV_NOPHY);
3268                         }
3269 
3270                         if (loop_count++ > SI_POLLRATE_SSTATUS) {
3271                                 /*
3272                                  * We are effectively timing out after 0.1 sec.
3273                                  */
3274                                 break;
3275                         }
3276 
3277                         /* Wait for 10 millisec */
3278 #ifndef __lock_lint
3279                         delay(SI_10MS_TICKS);
3280 #endif /* __lock_lint */
3281 
3282                 } while (SSTATUS_GET_DET(SStatus) !=
3283                     SSTATUS_DET_DEVPRESENT_PHYONLINE);
3284 
3285                 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3286                     "si_enumerate_port_multiplier: "
3287                     "loop count: %d, SStatus: 0x%x",
3288                     loop_count,
3289                     SStatus);
3290 
3291                 if ((SSTATUS_GET_IPM(SStatus) ==
3292                     SSTATUS_IPM_INTERFACE_ACTIVE) &&
3293                     (SSTATUS_GET_DET(SStatus) ==
3294                     SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
3295                         /* The interface is active and the device is present */
3296                         SIDBG_P(SIDBG_INIT, si_portp,
3297                             "Status: %x, device exists",
3298                             SStatus);
3299                         /*
3300                          * Clear error bits in SError register (i.e. PSCR[1]
3301                          * by writing back error bits.
3302                          */
3303                         if (si_read_portmult_reg(si_ctlp, si_portp, port,
3304                             pmport, PSCR_REG1, &SError)) {
3305                                 continue;
3306                         }
3307                         SIDBG_P(SIDBG_INIT, si_portp,
3308                             "SError bits are: %x", SError);
3309                         if (si_write_portmult_reg(si_ctlp, si_portp, port,
3310                             pmport, PSCR_REG1, SError)) {
3311                                 continue;
3312                         }
3313 
3314                         /* There exists a device. */
3315                         mutex_exit(&si_portp->siport_mutex);
3316                         si_find_dev_signature(si_ctlp, si_portp, port, pmport);
3317                         mutex_enter(&si_portp->siport_mutex);
3318                 }
3319         }
3320 
3321         mutex_exit(&si_portp->siport_mutex);
3322 
3323         return (SI_SUCCESS);
3324 }
3325 
3326 
3327 /*
3328  * Read a port multiplier register.
3329  *
3330  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
3331  * before calling us.
3332  */
3333 static int
3334 si_read_portmult_reg(
3335         si_ctl_state_t *si_ctlp,
3336         si_port_state_t *si_portp,
3337         int port,
3338         int pmport,
3339         int regnum,
3340         uint32_t *regval)
3341 {
3342         int slot;
3343         si_prb_t *prb;
3344         uint32_t *prb_word_ptr;
3345         int i;
3346         uint32_t slot_status;
3347         int loop_count = 0;
3348 
3349         _NOTE(ASSUMING_PROTECTED(si_portp))
3350 
3351         SIDBG_P(SIDBG_ENTRY, si_portp, "si_read_portmult_reg: port: %x,"
3352             "pmport: %x, regnum: %x",
3353             port, pmport, regnum);
3354 
3355         slot = si_claim_free_slot(si_ctlp, si_portp, port);
3356         if (slot == SI_FAILURE) {
3357                 return (SI_FAILURE);
3358         }
3359 
3360         prb =  &(si_portp->siport_prbpool[slot]);
3361         bzero((void *)prb, sizeof (si_prb_t));
3362 
3363         /* Now fill the prb. */
3364         SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
3365         SET_FIS_PMP(prb->prb_fis, PORTMULT_CONTROL_PORT);
3366         SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
3367         SET_FIS_COMMAND(prb->prb_fis, SATAC_READ_PM_REG);
3368 
3369         SET_FIS_DEV_HEAD(prb->prb_fis, pmport);
3370         SET_FIS_FEATURES(prb->prb_fis, regnum);
3371 
3372         /* no real data transfer is involved. */
3373         SET_SGE_TRM(prb->prb_sge0);
3374 
3375 #if SI_DEBUG
3376         if (si_debug_flags & SIDBG_DUMP_PRB) {
3377                 int *ptr;
3378                 int j;
3379 
3380                 ptr = (int *)(void *)prb;
3381                 cmn_err(CE_WARN, "read_port_mult_reg, prb: ");
3382                 for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
3383                         cmn_err(CE_WARN, "%x ", ptr[j]);
3384                 }
3385 
3386         }
3387 #endif /* SI_DEBUG */
3388 
3389         /* Deliver PRB */
3390         POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
3391 
3392         /* Loop till the command is finished. */
3393         do {
3394                 slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3395                     (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
3396 
3397                 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3398                     "looping read_pm slot_status: 0x%x",
3399                     slot_status);
3400 
3401                 if (loop_count++ > SI_POLLRATE_SLOTSTATUS) {
3402                         /* We are effectively timing out after 0.5 sec. */
3403                         break;
3404                 }
3405 
3406                 /* Wait for 10 millisec */
3407 #ifndef __lock_lint
3408                 delay(SI_10MS_TICKS);
3409 #endif /* __lock_lint */
3410 
3411         } while (slot_status & SI_SLOT_MASK & (0x1 << slot));
3412 
3413         SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3414             "read_portmult_reg: loop count: %d",
3415             loop_count);
3416 
3417         CLEAR_BIT(si_portp->siport_pending_tags, slot);
3418 
3419         /* Now inspect the port LRAM for the modified FIS. */
3420         prb_word_ptr = (uint32_t *)(void *)prb;
3421         for (i = 0; i < (sizeof (si_prb_t)/4); i++) {
3422                 prb_word_ptr[i] = ddi_get32(si_ctlp->sictl_port_acc_handle,
3423                     (uint32_t *)(PORT_LRAM(si_ctlp, port, slot)+i*4));
3424         }
3425 
3426         if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
3427             si_check_port_handles(si_portp) != DDI_SUCCESS) {
3428                 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3429                     DDI_SERVICE_UNAFFECTED);
3430                 return (SI_FAILURE);
3431         }
3432 
3433         if (((GET_FIS_COMMAND(prb->prb_fis) & 0x1) != 0) ||
3434             (GET_FIS_FEATURES(prb->prb_fis) != 0)) {
3435                 /* command failed. */
3436                 return (SI_FAILURE);
3437         }
3438 
3439         /* command succeeded. */
3440         *regval = (GET_FIS_SECTOR_COUNT(prb->prb_fis) & 0xff) |
3441             ((GET_FIS_SECTOR(prb->prb_fis) << 8)  & 0xff00) |
3442             ((GET_FIS_CYL_LOW(prb->prb_fis) << 16)  & 0xff0000) |
3443             ((GET_FIS_CYL_HI(prb->prb_fis) << 24)  & 0xff000000);
3444 
3445         return (SI_SUCCESS);
3446 }
3447 
3448 /*
3449  * Write a port multiplier register.
3450  *
3451  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
3452  * before calling us.
3453  */
3454 static int
3455 si_write_portmult_reg(
3456         si_ctl_state_t *si_ctlp,
3457         si_port_state_t *si_portp,
3458         int port,
3459         int pmport,
3460         int regnum,
3461         uint32_t regval)
3462 {
3463         int slot;
3464         si_prb_t *prb;
3465         uint32_t *prb_word_ptr;
3466         uint32_t slot_status;
3467         int i;
3468         int loop_count = 0;
3469 
3470         _NOTE(ASSUMING_PROTECTED(si_portp))
3471 
3472         SIDBG_P(SIDBG_ENTRY, si_portp,
3473             "si_write_portmult_reg: port: %x, pmport: %x,"
3474             "regnum: %x, regval: %x",
3475             port, pmport, regnum, regval);
3476 
3477         slot = si_claim_free_slot(si_ctlp, si_portp, port);
3478         if (slot == SI_FAILURE) {
3479                 return (SI_FAILURE);
3480         }
3481 
3482         prb =  &(si_portp->siport_prbpool[slot]);
3483         bzero((void *)prb, sizeof (si_prb_t));
3484 
3485         /* Now fill the prb. */
3486         SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
3487         SET_FIS_PMP(prb->prb_fis, PORTMULT_CONTROL_PORT);
3488         SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
3489 
3490         SET_FIS_COMMAND(prb->prb_fis, SATAC_WRITE_PM_REG);
3491         SET_FIS_DEV_HEAD(prb->prb_fis, pmport);
3492         SET_FIS_FEATURES(prb->prb_fis, regnum);
3493 
3494         SET_FIS_SECTOR_COUNT(prb->prb_fis, regval & 0xff);
3495         SET_FIS_SECTOR(prb->prb_fis, (regval >> 8) & 0xff);
3496         SET_FIS_CYL_LOW(prb->prb_fis, (regval >> 16) & 0xff);
3497         SET_FIS_CYL_HI(prb->prb_fis, (regval >> 24)  & 0xff);
3498 
3499         /* no real data transfer is involved. */
3500         SET_SGE_TRM(prb->prb_sge0);
3501 
3502 #if SI_DEBUG
3503         if (si_debug_flags & SIDBG_DUMP_PRB) {
3504                 int *ptr;
3505                 int j;
3506 
3507                 ptr = (int *)(void *)prb;
3508                 cmn_err(CE_WARN, "read_port_mult_reg, prb: ");
3509                 for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
3510                         cmn_err(CE_WARN, "%x ", ptr[j]);
3511                 }
3512 
3513         }
3514 #endif /* SI_DEBUG */
3515 
3516         /* Deliver PRB */
3517         POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
3518 
3519         /* Loop till the command is finished. */
3520         do {
3521                 slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3522                     (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
3523 
3524                 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3525                     "looping write_pmp slot_status: 0x%x",
3526                     slot_status);
3527 
3528                 if (loop_count++ > SI_POLLRATE_SLOTSTATUS) {
3529                         /* We are effectively timing out after 0.5 sec. */
3530                         break;
3531                 }
3532 
3533                 /* Wait for 10 millisec */
3534 #ifndef __lock_lint
3535                 delay(SI_10MS_TICKS);
3536 #endif /* __lock_lint */
3537 
3538         } while (slot_status & SI_SLOT_MASK & (0x1 << slot));
3539 
3540         SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3541             "write_portmult_reg: loop count: %d",
3542             loop_count);
3543 
3544         CLEAR_BIT(si_portp->siport_pending_tags, slot);
3545 
3546         /* Now inspect the port LRAM for the modified FIS. */
3547         prb_word_ptr = (uint32_t *)(void *)prb;
3548         for (i = 0; i < (sizeof (si_prb_t)/4); i++) {
3549                 prb_word_ptr[i] = ddi_get32(si_ctlp->sictl_port_acc_handle,
3550                     (uint32_t *)(PORT_LRAM(si_ctlp, port, slot)+i*4));
3551         }
3552 
3553         if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
3554             si_check_port_handles(si_portp) != DDI_SUCCESS) {
3555                 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3556                     DDI_SERVICE_UNAFFECTED);
3557                 return (SI_FAILURE);
3558         }
3559 
3560         if (((GET_FIS_COMMAND(prb->prb_fis) & 0x1) != 0) ||
3561             (GET_FIS_FEATURES(prb->prb_fis) != 0)) {
3562                 /* command failed */
3563                 return (SI_FAILURE);
3564         }
3565 
3566         /* command succeeded */
3567         return (SI_SUCCESS);
3568 }
3569 
3570 
3571 /*
3572  * Set the auto sense data for ATAPI devices.
3573  *
3574  * Note: Currently the sense data is simulated; this code will be enhanced
3575  * in second phase to fetch the real sense data from the atapi device.
3576  */
3577 static void
3578 si_set_sense_data(sata_pkt_t *satapkt, int reason)
3579 {
3580         struct scsi_extended_sense *sense;
3581 
3582         sense = (struct scsi_extended_sense *)
3583             satapkt->satapkt_cmd.satacmd_rqsense;
3584         bzero(sense, sizeof (struct scsi_extended_sense));
3585         sense->es_valid = 1;         /* Valid sense */
3586         sense->es_class = 7;         /* Response code 0x70 - current err */
3587         sense->es_key = 0;
3588         sense->es_info_1 = 0;
3589         sense->es_info_2 = 0;
3590         sense->es_info_3 = 0;
3591         sense->es_info_4 = 0;
3592         sense->es_add_len = 6;               /* Additional length */
3593         sense->es_cmd_info[0] = 0;
3594         sense->es_cmd_info[1] = 0;
3595         sense->es_cmd_info[2] = 0;
3596         sense->es_cmd_info[3] = 0;
3597         sense->es_add_code = 0;
3598         sense->es_qual_code = 0;
3599 
3600         if ((reason == SATA_PKT_DEV_ERROR) || (reason == SATA_PKT_TIMEOUT)) {
3601                 sense->es_key = KEY_HARDWARE_ERROR;
3602         }
3603 }
3604 
3605 
3606 /*
3607  * Interrupt service handler. We loop through each of the ports to find
3608  * if the interrupt belongs to any of them.
3609  *
3610  * Bulk of the interrupt handling is actually done out of subroutines
3611  * like si_intr_command_complete() etc.
3612  */
3613 /*ARGSUSED*/
3614 static uint_t
3615 si_intr(caddr_t arg1, caddr_t arg2)
3616 {
3617         si_ctl_state_t *si_ctlp = (si_ctl_state_t *)(void *)arg1;
3618         si_port_state_t *si_portp;
3619         uint32_t global_intr_status;
3620         uint32_t mask, port_intr_status;
3621         int port;
3622 
3623         global_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
3624             (uint32_t *)GLOBAL_INTERRUPT_STATUS(si_ctlp));
3625 
3626         SIDBG_C(SIDBG_INTR, si_ctlp,
3627             "si_intr: global_int_status: 0x%x",
3628             global_intr_status);
3629 
3630         if (si_check_acc_handle(si_ctlp->sictl_global_acc_handle) !=
3631             DDI_SUCCESS) {
3632                 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3633                     DDI_SERVICE_UNAFFECTED);
3634                 return (DDI_INTR_UNCLAIMED);
3635         }
3636 
3637         if (!(global_intr_status & SI31xx_INTR_PORT_MASK)) {
3638                 /* Sorry, the interrupt is not ours. */
3639                 return (DDI_INTR_UNCLAIMED);
3640         }
3641 
3642         /* Loop for all the ports. */
3643         for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
3644 
3645                 mask = 0x1 << port;
3646                 if (!(global_intr_status & mask)) {
3647                         continue;
3648                 }
3649 
3650                 mutex_enter(&si_ctlp->sictl_mutex);
3651                 si_portp = si_ctlp->sictl_ports[port];
3652                 mutex_exit(&si_ctlp->sictl_mutex);
3653 
3654                 port_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
3655                     (uint32_t *)PORT_INTERRUPT_STATUS(si_ctlp, port));
3656 
3657                 SIDBG_P(SIDBG_VERBOSE, si_portp,
3658                     "s_intr: port_intr_status: 0x%x, port: %x",
3659                     port_intr_status,
3660                     port);
3661 
3662                 if (port_intr_status & INTR_COMMAND_COMPLETE) {
3663                         (void) si_intr_command_complete(si_ctlp, si_portp,
3664                             port);
3665 
3666                         mutex_enter(&si_portp->siport_mutex);
3667                         if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
3668                             si_check_port_handles(si_portp) != DDI_SUCCESS) {
3669                                 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3670                                     DDI_SERVICE_UNAFFECTED);
3671                                 si_schedule_port_initialize(si_ctlp, si_portp,
3672                                     port);
3673                         }
3674                         mutex_exit(&si_portp->siport_mutex);
3675                 } else {
3676                         /* Clear the interrupts */
3677                         ddi_put32(si_ctlp->sictl_port_acc_handle,
3678                             (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp, port)),
3679                             port_intr_status & INTR_MASK);
3680                 }
3681 
3682                 /*
3683                  * Note that we did not clear the interrupt for command
3684                  * completion interrupt. Reading of slot_status takes care
3685                  * of clearing the interrupt for command completion case.
3686                  */
3687 
3688                 if (port_intr_status & INTR_COMMAND_ERROR) {
3689                         si_schedule_intr_command_error(si_ctlp, si_portp, port);
3690                 }
3691 
3692                 if (port_intr_status & INTR_PORT_READY) {
3693                         (void) si_intr_port_ready(si_ctlp, si_portp, port);
3694                 }
3695 
3696                 if (port_intr_status & INTR_POWER_CHANGE) {
3697                         (void) si_intr_pwr_change(si_ctlp, si_portp, port);
3698                 }
3699 
3700                 if (port_intr_status & INTR_PHYRDY_CHANGE) {
3701                         (void) si_intr_phy_ready_change(si_ctlp, si_portp,
3702                             port);
3703                 }
3704 
3705                 if (port_intr_status & INTR_COMWAKE_RECEIVED) {
3706                         (void) si_intr_comwake_rcvd(si_ctlp, si_portp,
3707                             port);
3708                 }
3709 
3710                 if (port_intr_status & INTR_UNRECOG_FIS) {
3711                         (void) si_intr_unrecognised_fis(si_ctlp, si_portp,
3712                             port);
3713                 }
3714 
3715                 if (port_intr_status & INTR_DEV_XCHANGED) {
3716                         (void) si_intr_dev_xchanged(si_ctlp, si_portp, port);
3717                 }
3718 
3719                 if (port_intr_status & INTR_8B10B_DECODE_ERROR) {
3720                         (void) si_intr_decode_err_threshold(si_ctlp, si_portp,
3721                             port);
3722                 }
3723 
3724                 if (port_intr_status & INTR_CRC_ERROR) {
3725                         (void) si_intr_crc_err_threshold(si_ctlp, si_portp,
3726                             port);
3727                 }
3728 
3729                 if (port_intr_status & INTR_HANDSHAKE_ERROR) {
3730                         (void) si_intr_handshake_err_threshold(si_ctlp,
3731                             si_portp, port);
3732                 }
3733 
3734                 if (port_intr_status & INTR_SETDEVBITS_NOTIFY) {
3735                         (void) si_intr_set_devbits_notify(si_ctlp, si_portp,
3736                             port);
3737                 }
3738         }
3739 
3740         return (DDI_INTR_CLAIMED);
3741 }
3742 
3743 /*
3744  * Interrupt which indicates that one or more commands have successfully
3745  * completed.
3746  *
3747  * Since we disabled W1C (write-one-to-clear) previously, mere reading
3748  * of slot_status register clears the interrupt. There is no need to
3749  * explicitly clear the interrupt.
3750  */
3751 static int
3752 si_intr_command_complete(
3753         si_ctl_state_t *si_ctlp,
3754         si_port_state_t *si_portp,
3755         int port)
3756 {
3757 
3758         uint32_t slot_status;
3759         uint32_t finished_tags;
3760         int finished_slot;
3761         sata_pkt_t *satapkt;
3762 
3763         SIDBG_P(SIDBG_INTR, si_portp,
3764             "si_intr_command_complete enter", NULL);
3765 
3766         mutex_enter(&si_portp->siport_mutex);
3767 
3768         slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3769             (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
3770 
3771         if (!si_portp->siport_pending_tags) {
3772                 /*
3773                  * Spurious interrupt. Nothing to be done.
3774                  * The interrupt was cleared when slot_status was read.
3775                  */
3776                 mutex_exit(&si_portp->siport_mutex);
3777                 return (SI_SUCCESS);
3778         }
3779 
3780         SIDBG_P(SIDBG_VERBOSE, si_portp, "si3124: si_intr_command_complete: "
3781             "pending_tags: %x, slot_status: %x",
3782             si_portp->siport_pending_tags,
3783             slot_status);
3784 
3785         finished_tags =  si_portp->siport_pending_tags &
3786             ~slot_status & SI_SLOT_MASK;
3787         while (finished_tags) {
3788 
3789                 finished_slot = ddi_ffs(finished_tags) - 1;
3790                 if (finished_slot == -1) {
3791                         break;
3792                 }
3793 
3794                 satapkt = si_portp->siport_slot_pkts[finished_slot];
3795 
3796                 if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
3797                         si_copy_out_regs(&satapkt->satapkt_cmd, si_ctlp, port,
3798                             finished_slot);
3799                 }
3800 
3801                 CLEAR_BIT(si_portp->siport_pending_tags, finished_slot);
3802                 CLEAR_BIT(finished_tags, finished_slot);
3803                 SENDUP_PACKET(si_portp, satapkt, SATA_PKT_COMPLETED);
3804         }
3805 
3806         SIDBG_P(SIDBG_PKTCOMP, si_portp,
3807             "command_complete done: pend_tags: 0x%x, slot_status: 0x%x",
3808             si_portp->siport_pending_tags,
3809             slot_status);
3810 
3811         /*
3812          * tidbit: no need to clear the interrupt since reading of
3813          * slot_status automatically clears the interrupt in the case
3814          * of a successful command completion.
3815          */
3816 
3817         mutex_exit(&si_portp->siport_mutex);
3818 
3819         return (SI_SUCCESS);
3820 }
3821 
3822 /*
3823  * Schedule a call to si_intr_command_error using a timeout to get it done
3824  * off the interrupt thread.
3825  */
3826 static void
3827 si_schedule_intr_command_error(
3828         si_ctl_state_t *si_ctlp,
3829         si_port_state_t *si_portp,
3830         int port)
3831 {
3832         si_event_arg_t *args;
3833 
3834         mutex_enter(&si_portp->siport_mutex);
3835 
3836         args = si_portp->siport_event_args;
3837         if (args->siea_ctlp != NULL) {
3838                 cmn_err(CE_WARN, "si_schedule_intr_command_error: "
3839                     "args->si_ctlp != NULL");
3840                 mutex_exit(&si_portp->siport_mutex);
3841                 return;
3842         }
3843 
3844         args->siea_ctlp = si_ctlp;
3845         args->siea_port = port;
3846 
3847         (void) timeout(si_do_intr_command_error, si_portp, 1);
3848 
3849         mutex_exit(&si_portp->siport_mutex);
3850 }
3851 
3852 /*
3853  * Called from timeout()
3854  * Unpack the arguments and call si_intr_command_error()
3855  */
3856 static void
3857 si_do_intr_command_error(void *arg)
3858 {
3859         si_event_arg_t *args;
3860         si_ctl_state_t *si_ctlp;
3861         si_port_state_t *si_portp;
3862         int port;
3863 
3864         si_portp = arg;
3865         mutex_enter(&si_portp->siport_mutex);
3866 
3867         args = si_portp->siport_event_args;
3868         si_ctlp = args->siea_ctlp;
3869         port = args->siea_port;
3870         args->siea_ctlp = NULL;      /* mark siport_event_args as free */
3871 
3872         mutex_exit(&si_portp->siport_mutex);
3873         (void) si_intr_command_error(si_ctlp, si_portp, port);
3874 }
3875 
3876 /*
3877  * Interrupt which indicates that a command did not complete successfully.
3878  *
3879  * The port halts whenever a command error interrupt is received.
3880  * The only way to restart it is to reset or reinitialize the port
3881  * but such an operation throws away all the pending commands on
3882  * the port.
3883  *
3884  * We reset the device and mop the commands on the port.
3885  */
3886 static int
3887 si_intr_command_error(
3888         si_ctl_state_t *si_ctlp,
3889         si_port_state_t *si_portp,
3890         int port)
3891 {
3892         uint32_t command_error, slot_status;
3893         uint32_t failed_tags;
3894 
3895         command_error = ddi_get32(si_ctlp->sictl_port_acc_handle,
3896             (uint32_t *)(PORT_COMMAND_ERROR(si_ctlp, port)));
3897 
3898         SIDBG_P(SIDBG_ERRS, si_portp,
3899             "si_intr_command_error: command_error: 0x%x",
3900             command_error);
3901 
3902         mutex_enter(&si_portp->siport_mutex);
3903 
3904         /*
3905          * Remember the slot_status since any of the recovery handler
3906          * can blow it away with reset operation.
3907          */
3908         slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3909             (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
3910 
3911         si_log_error_message(si_ctlp, port, command_error);
3912 
3913         switch (command_error) {
3914 
3915         case CMD_ERR_DEVICEERRROR:
3916                 si_error_recovery_DEVICEERROR(si_ctlp, si_portp, port);
3917                 break;
3918 
3919         case CMD_ERR_SDBERROR:
3920                 si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR, "SBD error");
3921                 si_error_recovery_SDBERROR(si_ctlp, si_portp, port);
3922                 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3923                     DDI_SERVICE_UNAFFECTED);
3924                 break;
3925 
3926         case CMD_ERR_DATAFISERROR:
3927                 si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR,
3928                     "Data FIS error");
3929                 si_error_recovery_DATAFISERROR(si_ctlp, si_portp, port);
3930                 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3931                     DDI_SERVICE_UNAFFECTED);
3932                 break;
3933 
3934         case CMD_ERR_SENDFISERROR:
3935                 si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR,
3936                     "Send FIS error");
3937                 si_error_recovery_SENDFISERROR(si_ctlp, si_portp, port);
3938                 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3939                     DDI_SERVICE_UNAFFECTED);
3940                 break;
3941 
3942         default:
3943                 si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR,
3944                     "Unknown error");
3945                 si_error_recovery_default(si_ctlp, si_portp, port);
3946                 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3947                     DDI_SERVICE_UNAFFECTED);
3948                 break;
3949 
3950         }
3951 
3952         /*
3953          * Compute the failed_tags by adding up the error tags.
3954          *
3955          * The siport_err_tags_SDBERROR and siport_err_tags_nonSDBERROR
3956          * were filled in by the si_error_recovery_* routines.
3957          */
3958         failed_tags = si_portp->siport_pending_tags &
3959             (si_portp->siport_err_tags_SDBERROR |
3960             si_portp->siport_err_tags_nonSDBERROR);
3961 
3962         SIDBG_P(SIDBG_ERRS, si_portp, "si_intr_command_error: "
3963             "err_tags_SDBERROR: 0x%x, "
3964             "err_tags_nonSDBERRROR: 0x%x, "
3965             "failed_tags: 0x%x",
3966             si_portp->siport_err_tags_SDBERROR,
3967             si_portp->siport_err_tags_nonSDBERROR,
3968             failed_tags);
3969 
3970         SIDBG_P(SIDBG_ERRS, si_portp,
3971             "si3124: si_intr_command_error: "
3972             "slot_status:0x%x, pending_tags: 0x%x",
3973             slot_status,
3974             si_portp->siport_pending_tags);
3975 
3976         si_portp->mopping_in_progress++;
3977 
3978         si_mop_commands(si_ctlp,
3979             si_portp,
3980             port,
3981             slot_status,
3982             failed_tags,
3983             0,  /* timedout_tags */
3984             0,  /* aborting_tags */
3985             0);         /* reset_tags */
3986 
3987         ASSERT(si_portp->siport_pending_tags == 0);
3988 
3989         si_portp->siport_err_tags_SDBERROR = 0;
3990         si_portp->siport_err_tags_nonSDBERROR = 0;
3991 
3992         mutex_exit(&si_portp->siport_mutex);
3993 
3994         return (SI_SUCCESS);
3995 }
3996 
3997 /*
3998  * There is a subtle difference between errors on a normal port and
3999  * a port-mult port. When an error happens on a normal port, the port
4000  * is halted effectively until the port is reset or initialized.
4001  * However, in port-mult port errors, port does not get halted since
4002  * other non-error devices behind the port multiplier can still
4003  * continue to operate. So we wait till all the commands are drained
4004  * instead of resetting it right away.
4005  *
4006  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4007  * before calling us.
4008  */
4009 static void
4010 si_recover_portmult_errors(
4011         si_ctl_state_t *si_ctlp,
4012         si_port_state_t *si_portp,
4013         int port)
4014 {
4015         uint32_t command_error, slot_status, port_status;
4016         int failed_slot;
4017         int loop_count = 0;
4018 
4019         _NOTE(ASSUMING_PROTECTED(si_portp))
4020 
4021         SIDBG_P(SIDBG_ERRS, si_portp,
4022             "si_recover_portmult_errors: port: 0x%x",
4023             port);
4024 
4025         /* Resume the port */
4026         ddi_put32(si_ctlp->sictl_port_acc_handle,
4027             (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
4028             PORT_CONTROL_SET_BITS_RESUME);
4029 
4030         port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4031             (uint32_t *)PORT_STATUS(si_ctlp, port));
4032 
4033         failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4034         command_error = ddi_get32(si_ctlp->sictl_port_acc_handle,
4035             (uint32_t *)(PORT_COMMAND_ERROR(si_ctlp, port)));
4036 
4037         if (command_error ==  CMD_ERR_SDBERROR) {
4038                 si_portp->siport_err_tags_SDBERROR |= (0x1 << failed_slot);
4039         } else {
4040                 si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4041         }
4042 
4043         /* Now we drain the pending commands. */
4044         do {
4045                 slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4046                     (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
4047 
4048                 /*
4049                  * Since we have not yet returned DDI_INTR_CLAIMED,
4050                  * our interrupt handler is guaranteed not to be called again.
4051                  * So we need to check IS_ATTENTION_RAISED() for further
4052                  * decisions.
4053                  *
4054                  * This is a too big a delay for an interrupt context.
4055                  * But this is supposed to be a rare condition.
4056                  */
4057 
4058                 if (IS_ATTENTION_RAISED(slot_status)) {
4059                         /* Resume again */
4060                         ddi_put32(si_ctlp->sictl_port_acc_handle,
4061                             (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
4062                             PORT_CONTROL_SET_BITS_RESUME);
4063 
4064                         port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4065                             (uint32_t *)PORT_STATUS(si_ctlp, port));
4066                         failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4067                         command_error = ddi_get32(
4068                             si_ctlp->sictl_port_acc_handle,
4069                             (uint32_t *)(PORT_COMMAND_ERROR(si_ctlp,
4070                             port)));
4071                         if (command_error ==  CMD_ERR_SDBERROR) {
4072                                 si_portp->siport_err_tags_SDBERROR |=
4073                                     (0x1 << failed_slot);
4074                         } else {
4075                                 si_portp->siport_err_tags_nonSDBERROR |=
4076                                     (0x1 << failed_slot);
4077                         }
4078                 }
4079 
4080                 if (loop_count++ > SI_POLLRATE_RECOVERPORTMULT) {
4081                         /* We are effectively timing out after 10 sec. */
4082                         break;
4083                 }
4084 
4085                 /* Wait for 10 millisec */
4086 #ifndef __lock_lint
4087                 delay(SI_10MS_TICKS);
4088 #endif /* __lock_lint */
4089 
4090         } while (slot_status & SI_SLOT_MASK);
4091 
4092         /*
4093          * The above loop can be improved for 3132 since we could obtain the
4094          * Port Multiplier Context of the device in error. Then we could
4095          * do a better job in filtering out commands for the device in error.
4096          * The loop could finish much earlier with such a logic.
4097          */
4098 
4099         /* Clear the RESUME bit. */
4100         ddi_put32(si_ctlp->sictl_port_acc_handle,
4101             (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
4102             PORT_CONTROL_CLEAR_BITS_RESUME);
4103 
4104 }
4105 
4106 /*
4107  * If we are connected to port multiplier, drain the non-failed devices.
4108  * Otherwise, we initialize the port (which effectively fails all the
4109  * pending commands in the hope that sd would retry them later).
4110  *
4111  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4112  * before calling us.
4113  */
4114 static void
4115 si_error_recovery_DEVICEERROR(
4116         si_ctl_state_t *si_ctlp,
4117         si_port_state_t *si_portp,
4118         int port)
4119 {
4120         uint32_t port_status;
4121         int failed_slot;
4122 
4123         _NOTE(ASSUMING_PROTECTED(si_portp))
4124 
4125         SIDBG_P(SIDBG_ERRS, si_portp,
4126             "si_error_recovery_DEVICEERROR: port: 0x%x",
4127             port);
4128 
4129         if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
4130                 si_recover_portmult_errors(si_ctlp, si_portp, port);
4131         } else {
4132                 port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4133                     (uint32_t *)PORT_STATUS(si_ctlp, port));
4134                 failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4135                 si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4136         }
4137 
4138         /* In either case (port-mult or not), we reinitialize the port. */
4139         (void) si_initialize_port_wait_till_ready(si_ctlp, port);
4140 }
4141 
4142 /*
4143  * Handle exactly like DEVICEERROR. Remember the tags with SDBERROR
4144  * to perform read_log_ext on them later. SDBERROR means that the
4145  * error was for an NCQ command.
4146  *
4147  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4148  * before calling us.
4149  */
4150 static void
4151 si_error_recovery_SDBERROR(
4152         si_ctl_state_t *si_ctlp,
4153         si_port_state_t *si_portp,
4154         int port)
4155 {
4156         uint32_t port_status;
4157         int failed_slot;
4158 
4159         _NOTE(ASSUMING_PROTECTED(si_portp))
4160 
4161         SIDBG_P(SIDBG_ERRS, si_portp,
4162             "si3124: si_error_recovery_SDBERROR: port: 0x%x",
4163             port);
4164 
4165         if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
4166                 si_recover_portmult_errors(si_ctlp, si_portp, port);
4167         } else {
4168                 port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4169                     (uint32_t *)PORT_STATUS(si_ctlp, port));
4170                 failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4171                 si_portp->siport_err_tags_SDBERROR |= (0x1 << failed_slot);
4172         }
4173 
4174         /* In either case (port-mult or not), we reinitialize the port. */
4175         (void) si_initialize_port_wait_till_ready(si_ctlp, port);
4176 }
4177 
4178 /*
4179  * Handle exactly like DEVICEERROR except resetting the port if there was
4180  * an NCQ command on the port.
4181  *
4182  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4183  * before calling us.
4184  */
4185 static void
4186 si_error_recovery_DATAFISERROR(
4187         si_ctl_state_t *si_ctlp,
4188         si_port_state_t *si_portp,
4189         int port)
4190 {
4191         uint32_t port_status;
4192         int failed_slot;
4193 
4194         _NOTE(ASSUMING_PROTECTED(si_portp))
4195 
4196         SIDBG_P(SIDBG_ERRS, si_portp,
4197             "si3124: si_error_recovery_DATAFISERROR: port: 0x%x",
4198             port);
4199 
4200         /* reset device if we were waiting for any ncq commands. */
4201         if (si_portp->siport_pending_ncq_count) {
4202                 port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4203                     (uint32_t *)PORT_STATUS(si_ctlp, port));
4204                 failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4205                 si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4206                 (void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
4207                     SI_DEVICE_RESET);
4208                 return;
4209         }
4210 
4211         /*
4212          * If we don't have any ncq commands pending, the rest of
4213          * the process is similar to the one for DEVICEERROR.
4214          */
4215         si_error_recovery_DEVICEERROR(si_ctlp, si_portp, port);
4216 }
4217 
4218 /*
4219  * We handle just like DEVICERROR except that we reset the device instead
4220  * of initializing the port.
4221  *
4222  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4223  * before calling us.
4224  */
4225 static void
4226 si_error_recovery_SENDFISERROR(
4227         si_ctl_state_t *si_ctlp,
4228         si_port_state_t *si_portp,
4229         int port)
4230 {
4231         uint32_t port_status;
4232         int failed_slot;
4233 
4234         _NOTE(ASSUMING_PROTECTED(si_portp))
4235 
4236         SIDBG_P(SIDBG_ERRS, si_portp,
4237             "si3124: si_error_recovery_SENDFISERROR: port: 0x%x",
4238             port);
4239 
4240         if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
4241                 si_recover_portmult_errors(si_ctlp, si_portp, port);
4242         } else {
4243                 port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4244                     (uint32_t *)PORT_STATUS(si_ctlp, port));
4245                 failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4246                 si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4247                 (void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
4248                     SI_DEVICE_RESET);
4249         }
4250 }
4251 
4252 /*
4253  * The default behavior for all other errors is to reset the device.
4254  *
4255  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4256  * before calling us.
4257  */
4258 static void
4259 si_error_recovery_default(
4260         si_ctl_state_t *si_ctlp,
4261         si_port_state_t *si_portp,
4262         int port)
4263 {
4264         uint32_t port_status;
4265         int failed_slot;
4266 
4267         _NOTE(ASSUMING_PROTECTED(si_portp))
4268 
4269         SIDBG_P(SIDBG_ERRS, si_portp,
4270             "si3124: si_error_recovery_default: port: 0x%x",
4271             port);
4272 
4273         port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4274             (uint32_t *)PORT_STATUS(si_ctlp, port));
4275         failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4276         si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4277 
4278         (void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
4279             SI_DEVICE_RESET);
4280 }
4281 
4282 /*
4283  * Read Log Ext with PAGE 10 to retrieve the error for an NCQ command.
4284  *
4285  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4286  * before calling us.
4287  */
4288 static uint8_t
4289 si_read_log_ext(si_ctl_state_t *si_ctlp, si_port_state_t *si_portp, int port)
4290 {
4291         int slot;
4292         si_prb_t *prb;
4293         int i;
4294         uint32_t slot_status;
4295         int loop_count = 0;
4296         uint32_t *prb_word_ptr;
4297         uint8_t error;
4298 
4299         _NOTE(ASSUMING_PROTECTED(si_portp))
4300 
4301         SIDBG_P(SIDBG_ERRS, si_portp,
4302             "si_read_log_ext: port: %x", port);
4303 
4304         slot = si_claim_free_slot(si_ctlp, si_portp, port);
4305         if (slot == SI_FAILURE) {
4306                 return (0);
4307         }
4308 
4309         prb =  &(si_portp->siport_prbpool[slot]);
4310         bzero((void *)prb, sizeof (si_prb_t));
4311 
4312         /* Now fill the prb */
4313         SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
4314         SET_FIS_PMP(prb->prb_fis, PORTMULT_CONTROL_PORT);
4315         SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
4316         SET_FIS_COMMAND(prb->prb_fis, SATAC_READ_LOG_EXT);
4317         SET_FIS_SECTOR(prb->prb_fis, SATA_LOG_PAGE_10);
4318 
4319         /* no real data transfer is involved */
4320         SET_SGE_TRM(prb->prb_sge0);
4321 
4322 #if SI_DEBUG
4323         if (si_debug_flags & SIDBG_DUMP_PRB) {
4324                 int *ptr;
4325                 int j;
4326 
4327                 ptr = (int *)(void *)prb;
4328                 cmn_err(CE_WARN, "read_port_mult_reg, prb: ");
4329                 for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
4330                         cmn_err(CE_WARN, "%x ", ptr[j]);
4331                 }
4332 
4333         }
4334 #endif /* SI_DEBUG */
4335 
4336         /* Deliver PRB */
4337         POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
4338 
4339         /* Loop till the command is finished. */
4340         do {
4341                 slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4342                     (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
4343 
4344                 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
4345                     "looping read_log_ext slot_status: 0x%x",
4346                     slot_status);
4347 
4348                 if (loop_count++ > SI_POLLRATE_SLOTSTATUS) {
4349                         /* We are effectively timing out after 0.5 sec. */
4350                         break;
4351                 }
4352 
4353                 /* Wait for 10 millisec */
4354 #ifndef __lock_lint
4355                 delay(SI_10MS_TICKS);
4356 #endif /* __lock_lint */
4357 
4358         } while (slot_status & SI_SLOT_MASK & (0x1 << slot));
4359 
4360         if (slot_status & SI_SLOT_MASK & (0x1 << slot)) {
4361                 /*
4362                  * If we fail with the READ LOG EXT command, we need to
4363                  * initialize the port to clear the slot_status register.
4364                  * We don't need to worry about any other valid commands
4365                  * being thrown away because we are already in recovery
4366                  * mode and READ LOG EXT is the only pending command.
4367                  */
4368                 (void) si_initialize_port_wait_till_ready(si_ctlp, port);
4369         }
4370 
4371         SIDBG_P(SIDBG_POLL_LOOP, si_portp,
4372             "read_portmult_reg: loop count: %d",
4373             loop_count);
4374 
4375         /*
4376          * The LRAM contains the the modified FIS.
4377          * Read the modified FIS to obtain the Error.
4378          */
4379         prb_word_ptr = (uint32_t *)(void *)prb;
4380         for (i = 0; i < (sizeof (si_prb_t)/4); i++) {
4381                 prb_word_ptr[i] = ddi_get32(si_ctlp->sictl_port_acc_handle,
4382                     (uint32_t *)(PORT_LRAM(si_ctlp, port, slot)+i*4));
4383         }
4384 
4385         if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
4386             si_check_port_handles(si_portp) != DDI_SUCCESS) {
4387                 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
4388                     DDI_SERVICE_UNAFFECTED);
4389         }
4390 
4391         error = GET_FIS_FEATURES(prb->prb_fis);
4392 
4393         CLEAR_BIT(si_portp->siport_pending_tags, slot);
4394 
4395         return (error);
4396 
4397 }
4398 
4399 /*
4400  * Dump the error message to the log.
4401  */
4402 static void
4403 si_log_error_message(si_ctl_state_t *si_ctlp, int port, uint32_t command_error)
4404 {
4405 #if SI_DEBUG
4406 #ifndef __lock_lint
4407         _NOTE(ARGUNUSED(si_ctlp))
4408         _NOTE(ARGUNUSED(port))
4409 #endif  /* __lock_lint */
4410 
4411         char *errstr;
4412         si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
4413 
4414         switch (command_error) {
4415 
4416         case CMD_ERR_DEVICEERRROR:
4417                 errstr = "Standard Error: Error bit set in register - device"
4418                     " to host FIS";
4419                 break;
4420 
4421         case CMD_ERR_SDBERROR:
4422                 errstr = "NCQ Error: Error bit set in register - device"
4423                     " to host FIS";
4424                 break;
4425 
4426         case CMD_ERR_DATAFISERROR:
4427                 errstr = "Error in data FIS not detected by device";
4428                 break;
4429 
4430         case CMD_ERR_SENDFISERROR:
4431                 errstr = "Initial command FIS transmission failed";
4432                 break;
4433 
4434         case CMD_ERR_INCONSISTENTSTATE:
4435                 errstr = "Inconsistency in protocol";
4436                 break;
4437 
4438         case CMD_ERR_DIRECTIONERROR:
4439                 errstr = "DMA direction flag does not match the command";
4440                 break;
4441 
4442         case CMD_ERR_UNDERRUNERROR:
4443                 errstr = "Run out of scatter gather entries while writing data";
4444                 break;
4445 
4446         case CMD_ERR_OVERRUNERROR:
4447                 errstr = "Run out of scatter gather entries while reading data";
4448                 break;
4449 
4450         case CMD_ERR_PACKETPROTOCOLERROR:
4451                 errstr = "Packet protocol error";
4452                 break;
4453 
4454         case CMD_ERR_PLDSGTERRORBOUNDARY:
4455                 errstr = "Scatter/gather table not on quadword boundary";
4456                 break;
4457 
4458         case CMD_ERR_PLDSGTERRORTARETABORT:
4459                 errstr = "PCI(X) Target abort while fetching scatter/gather"
4460                     " table";
4461                 break;
4462 
4463         case CMD_ERR_PLDSGTERRORMASTERABORT:
4464                 errstr = "PCI(X) Master abort while fetching scatter/gather"
4465                     " table";
4466                 break;
4467 
4468         case CMD_ERR_PLDSGTERRORPCIERR:
4469                 errstr = "PCI(X) parity error while fetching scatter/gather"
4470                     " table";
4471                 break;
4472 
4473         case CMD_ERR_PLDCMDERRORBOUNDARY:
4474                 errstr = "PRB not on quadword boundary";
4475                 break;
4476 
4477         case CMD_ERR_PLDCMDERRORTARGETABORT:
4478                 errstr = "PCI(X) Target abort while fetching PRB";
4479                 break;
4480 
4481         case CMD_ERR_PLDCMDERRORMASTERABORT:
4482                 errstr = "PCI(X) Master abort while fetching PRB";
4483                 break;
4484 
4485         case CMD_ERR_PLDCMDERORPCIERR:
4486                 errstr = "PCI(X) parity error while fetching PRB";
4487                 break;
4488 
4489         case CMD_ERR_PSDERRORTARGETABORT:
4490                 errstr = "PCI(X) Target abort during data transfer";
4491                 break;
4492 
4493         case CMD_ERR_PSDERRORMASTERABORT:
4494                 errstr = "PCI(X) Master abort during data transfer";
4495                 break;
4496 
4497         case CMD_ERR_PSDERRORPCIERR:
4498                 errstr = "PCI(X) parity error during data transfer";
4499                 break;
4500 
4501         case CMD_ERR_SENDSERVICEERROR:
4502                 errstr = "FIS received while sending service FIS in"
4503                     " legacy queuing operation";
4504                 break;
4505 
4506         default:
4507                 errstr = "Unknown Error";
4508                 break;
4509 
4510         }
4511 
4512         SIDBG_P(SIDBG_ERRS, si_portp,
4513             "command error: error: %s",
4514             errstr);
4515 #else
4516 #ifndef __lock_lint
4517         _NOTE(ARGUNUSED(si_ctlp))
4518         _NOTE(ARGUNUSED(port))
4519         _NOTE(ARGUNUSED(command_error))
4520 #endif  /* __lock_lint */
4521 
4522 #endif  /* SI_DEBUG */
4523 }
4524 
4525 
4526 /*
4527  * Interrupt which indicates that the Port Ready state has changed
4528  * from zero to one.
4529  *
4530  * We are not interested in this interrupt; we just log a debug message.
4531  */
4532 /*ARGSUSED*/
4533 static int
4534 si_intr_port_ready(
4535         si_ctl_state_t *si_ctlp,
4536         si_port_state_t *si_portp,
4537         int port)
4538 {
4539         SIDBG_P(SIDBG_INTR, si_portp, "si_intr_ready", NULL);
4540         return (SI_SUCCESS);
4541 }
4542 
4543 /*
4544  * Interrupt which indicates that the port power management state
4545  * has been modified.
4546  *
4547  * We are not interested in this interrupt; we just log a debug message.
4548  */
4549 /*ARGSUSED*/
4550 static int
4551 si_intr_pwr_change(
4552         si_ctl_state_t *si_ctlp,
4553         si_port_state_t *si_portp,
4554         int port)
4555 {
4556         SIDBG_P(SIDBG_INTR, si_portp, "si_intr_pwr_change", NULL);
4557         return (SI_SUCCESS);
4558 }
4559 
4560 /*
4561  * Interrupt which indicates that the PHY state has changed either from
4562  * Not-Ready to Ready or from Ready to Not-Ready.
4563  */
4564 static int
4565 si_intr_phy_ready_change(
4566         si_ctl_state_t *si_ctlp,
4567         si_port_state_t *si_portp,
4568         int port)
4569 {
4570         sata_device_t sdevice;
4571         uint32_t SStatus = 0; /* No dev present & PHY not established. */
4572         int dev_exists_now = 0;
4573         int dev_existed_previously = 0;
4574 
4575         SIDBG_P(SIDBG_INTR, si_portp,
4576             "si_intr_phy_rdy_change", NULL);
4577 
4578         mutex_enter(&si_ctlp->sictl_mutex);
4579         if ((si_ctlp->sictl_sata_hba_tran == NULL) || (si_portp == NULL)) {
4580                 /* the whole controller setup is not yet done. */
4581                 mutex_exit(&si_ctlp->sictl_mutex);
4582                 return (SI_SUCCESS);
4583         }
4584 
4585         mutex_exit(&si_ctlp->sictl_mutex);
4586 
4587         mutex_enter(&si_portp->siport_mutex);
4588 
4589         /* SStatus tells the presence of device. */
4590         SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
4591             (uint32_t *)PORT_SSTATUS(si_ctlp, port));
4592         dev_exists_now =
4593             (SSTATUS_GET_DET(SStatus) == SSTATUS_DET_DEVPRESENT_PHYONLINE);
4594 
4595         if (si_portp->siport_port_type != PORT_TYPE_NODEV) {
4596                 dev_existed_previously = 1;
4597         }
4598 
4599         bzero((void *)&sdevice, sizeof (sata_device_t));
4600 
4601         sdevice.satadev_addr.cport = (uint8_t)port;
4602         sdevice.satadev_addr.pmport = PORTMULT_CONTROL_PORT;
4603 
4604         /* we don't have a way of determining the exact port-mult port. */
4605         if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
4606                 sdevice.satadev_addr.qual = SATA_ADDR_PMPORT;
4607         } else {
4608                 sdevice.satadev_addr.qual = SATA_ADDR_CPORT;
4609         }
4610 
4611         sdevice.satadev_state = SATA_STATE_READY; /* port state */
4612 
4613         if (dev_exists_now) {
4614                 if (dev_existed_previously) {
4615 
4616                         /* Things are fine now. The loss was temporary. */
4617                         SIDBG_P(SIDBG_INTR, si_portp,
4618                             "phyrdy: doing BOTH EVENTS TOGETHER", NULL);
4619                         if (si_portp->siport_active) {
4620                                 SIDBG_P(SIDBG_EVENT, si_portp,
4621                                     "sending event: LINK_LOST & "
4622                                     "LINK_ESTABLISHED", NULL);
4623 
4624                                 sata_hba_event_notify(
4625                                     si_ctlp->sictl_sata_hba_tran->\
4626                                     sata_tran_hba_dip,
4627                                     &sdevice,
4628                                     SATA_EVNT_LINK_LOST|
4629                                     SATA_EVNT_LINK_ESTABLISHED);
4630                         }
4631 
4632                 } else {
4633 
4634                         /* A new device has been detected. */
4635                         mutex_exit(&si_portp->siport_mutex);
4636                         si_find_dev_signature(si_ctlp, si_portp, port,
4637                             PORTMULT_CONTROL_PORT);
4638                         mutex_enter(&si_portp->siport_mutex);
4639                         SIDBG_P(SIDBG_INTR, si_portp,
4640                             "phyrdy: doing ATTACH event", NULL);
4641                         if (si_portp->siport_active) {
4642                                 SIDBG_P(SIDBG_EVENT, si_portp,
4643                                     "sending event up: LINK_ESTABLISHED", NULL);
4644 
4645                                 sata_hba_event_notify(
4646                                     si_ctlp->sictl_sata_hba_tran->\
4647                                     sata_tran_hba_dip,
4648                                     &sdevice,
4649                                     SATA_EVNT_LINK_ESTABLISHED);
4650                         }
4651 
4652                 }
4653         } else { /* No device exists now */
4654 
4655                 if (dev_existed_previously) {
4656 
4657                         /* An existing device is lost. */
4658                         if (si_portp->siport_active) {
4659                                 SIDBG_P(SIDBG_EVENT, si_portp,
4660                                     "sending event up: LINK_LOST", NULL);
4661 
4662                                 sata_hba_event_notify(
4663                                     si_ctlp->sictl_sata_hba_tran->
4664                                     sata_tran_hba_dip,
4665                                     &sdevice,
4666                                     SATA_EVNT_LINK_LOST);
4667                         }
4668                         si_portp->siport_port_type = PORT_TYPE_NODEV;
4669 
4670                 } else {
4671 
4672                         /* spurious interrupt */
4673                         SIDBG_P(SIDBG_INTR, si_portp,
4674                             "spurious phy ready interrupt", NULL);
4675                 }
4676         }
4677 
4678         mutex_exit(&si_portp->siport_mutex);
4679         return (SI_SUCCESS);
4680 }
4681 
4682 
4683 /*
4684  * Interrupt which indicates that a COMWAKE OOB signal has been decoded
4685  * on the receiver.
4686  *
4687  * We are not interested in this interrupt; we just log a debug message.
4688  */
4689 /*ARGSUSED*/
4690 static int
4691 si_intr_comwake_rcvd(
4692         si_ctl_state_t *si_ctlp,
4693         si_port_state_t *si_portp,
4694         int port)
4695 {
4696         SIDBG_P(SIDBG_INTR, si_portp,
4697             "si_intr_commwake_rcvd", NULL);
4698         return (SI_SUCCESS);
4699 }
4700 
4701 /*
4702  * Interrupt which indicates that the F-bit has been set in SError
4703  * Diag field.
4704  *
4705  * We are not interested in this interrupt; we just log a debug message.
4706  */
4707 /*ARGSUSED*/
4708 static int
4709 si_intr_unrecognised_fis(
4710         si_ctl_state_t *si_ctlp,
4711         si_port_state_t *si_portp,
4712         int port)
4713 {
4714         SIDBG_P(SIDBG_INTR, si_portp,
4715             "si_intr_unrecognised_fis", NULL);
4716         return (SI_SUCCESS);
4717 }
4718 
4719 /*
4720  * Interrupt which indicates that the X-bit has been set in SError
4721  * Diag field.
4722  *
4723  * We are not interested in this interrupt; we just log a debug message.
4724  */
4725 /*ARGSUSED*/
4726 static int
4727 si_intr_dev_xchanged(
4728         si_ctl_state_t *si_ctlp,
4729         si_port_state_t *si_portp,
4730         int port)
4731 {
4732 
4733         SIDBG_P(SIDBG_INTR, si_portp,
4734             "si_intr_dev_xchanged", NULL);
4735         return (SI_SUCCESS);
4736 }
4737 
4738 /*
4739  * Interrupt which indicates that the 8b/10b Decode Error counter has
4740  * exceeded the programmed non-zero threshold value.
4741  *
4742  * We are not interested in this interrupt; we just log a debug message.
4743  */
4744 /*ARGSUSED*/
4745 static int
4746 si_intr_decode_err_threshold(
4747         si_ctl_state_t *si_ctlp,
4748         si_port_state_t *si_portp,
4749         int port)
4750 {
4751         SIDBG_P(SIDBG_INTR, si_portp,
4752             "si_intr_err_threshold", NULL);
4753         return (SI_SUCCESS);
4754 }
4755 
4756 /*
4757  * Interrupt which indicates that the CRC Error counter has exceeded the
4758  * programmed non-zero threshold value.
4759  *
4760  * We are not interested in this interrupt; we just log a debug message.
4761  */
4762 /*ARGSUSED*/
4763 static int
4764 si_intr_crc_err_threshold(
4765         si_ctl_state_t *si_ctlp,
4766         si_port_state_t *si_portp,
4767         int port)
4768 {
4769         SIDBG_P(SIDBG_INTR, si_portp,
4770             "si_intr_crc_threshold", NULL);
4771         return (SI_SUCCESS);
4772 }
4773 
4774 /*
4775  * Interrupt which indicates that the Handshake Error counter has
4776  * exceeded the programmed non-zero threshold value.
4777  *
4778  * We are not interested in this interrupt; we just log a debug message.
4779  */
4780 /*ARGSUSED*/
4781 static int
4782 si_intr_handshake_err_threshold(
4783         si_ctl_state_t *si_ctlp,
4784         si_port_state_t *si_portp,
4785         int port)
4786 {
4787         SIDBG_P(SIDBG_INTR, si_portp,
4788             "si_intr_handshake_err_threshold", NULL);
4789         return (SI_SUCCESS);
4790 }
4791 
4792 /*
4793  * Interrupt which indicates that a "Set Device Bits" FIS has been
4794  * received with N-bit set in the control field.
4795  *
4796  * We are not interested in this interrupt; we just log a debug message.
4797  */
4798 /*ARGSUSED*/
4799 static int
4800 si_intr_set_devbits_notify(
4801         si_ctl_state_t *si_ctlp,
4802         si_port_state_t *si_portp,
4803         int port)
4804 {
4805         SIDBG_P(SIDBG_INTR, si_portp,
4806             "si_intr_set_devbits_notify", NULL);
4807         return (SI_SUCCESS);
4808 }
4809 
4810 
4811 /*
4812  * Enable the interrupts for a particular port.
4813  *
4814  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4815  * before calling us.
4816  */
4817 static void
4818 si_enable_port_interrupts(si_ctl_state_t *si_ctlp, int port)
4819 {
4820         uint32_t mask;
4821         si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
4822 
4823         /* get the current settings first. */
4824         mask = ddi_get32(si_ctlp->sictl_global_acc_handle,
4825             (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp));
4826 
4827         SIDBG_P(SIDBG_INIT, si_portp,
4828             "si_enable_port_interrupts: current mask: 0x%x",
4829             mask);
4830 
4831         /* enable the bit for current port. */
4832         SET_BIT(mask, port);
4833 
4834         /* now use this mask to enable the interrupt. */
4835         ddi_put32(si_ctlp->sictl_global_acc_handle,
4836             (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp),
4837             mask);
4838 }
4839 
4840 /*
4841  * Enable interrupts for all the ports.
4842  */
4843 static void
4844 si_enable_all_interrupts(si_ctl_state_t *si_ctlp)
4845 {
4846         int port;
4847 
4848         for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
4849                 si_enable_port_interrupts(si_ctlp, port);
4850         }
4851 }
4852 
4853 /*
4854  * Disable interrupts for a particular port.
4855  *
4856  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4857  * before calling us.
4858  */
4859 static void
4860 si_disable_port_interrupts(si_ctl_state_t *si_ctlp, int port)
4861 {
4862         uint32_t mask;
4863 
4864         /* get the current settings first. */
4865         mask = ddi_get32(si_ctlp->sictl_global_acc_handle,
4866             (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp));
4867 
4868         /* clear the bit for current port. */
4869         CLEAR_BIT(mask, port);
4870 
4871         /* now use this mask to disable the interrupt. */
4872         ddi_put32(si_ctlp->sictl_global_acc_handle,
4873             (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp),
4874             mask);
4875 
4876 }
4877 
4878 /*
4879  * Disable interrupts for all the ports.
4880  */
4881 static void
4882 si_disable_all_interrupts(si_ctl_state_t *si_ctlp)
4883 {
4884         int port;
4885 
4886         for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
4887                 si_disable_port_interrupts(si_ctlp, port);
4888         }
4889 }
4890 
4891 /*
4892  * Fetches the latest sstatus, scontrol, serror, sactive registers
4893  * and stuffs them into sata_device_t structure.
4894  */
4895 static void
4896 fill_dev_sregisters(si_ctl_state_t *si_ctlp, int port, sata_device_t *satadev)
4897 {
4898         satadev->satadev_scr.sstatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
4899             (uint32_t *)(PORT_SSTATUS(si_ctlp, port)));
4900         satadev->satadev_scr.serror = ddi_get32(si_ctlp->sictl_port_acc_handle,
4901             (uint32_t *)(PORT_SERROR(si_ctlp, port)));
4902         satadev->satadev_scr.sactive = ddi_get32(si_ctlp->sictl_port_acc_handle,
4903             (uint32_t *)(PORT_SACTIVE(si_ctlp, port)));
4904         satadev->satadev_scr.scontrol =
4905             ddi_get32(si_ctlp->sictl_port_acc_handle,
4906             (uint32_t *)(PORT_SCONTROL(si_ctlp, port)));
4907 
4908 }
4909 
4910 /*
4911  * si_add_legacy_intrs() handles INTx and legacy interrupts.
4912  */
4913 static int
4914 si_add_legacy_intrs(si_ctl_state_t *si_ctlp)
4915 {
4916         dev_info_t      *devinfo = si_ctlp->sictl_devinfop;
4917         int             actual, count = 0;
4918         int             x, y, rc, inum = 0;
4919 
4920         SIDBG_C(SIDBG_INIT, si_ctlp, "si_add_legacy_intrs", NULL);
4921 
4922         /* get number of interrupts. */
4923         rc = ddi_intr_get_nintrs(devinfo, DDI_INTR_TYPE_FIXED, &count);
4924         if ((rc != DDI_SUCCESS) || (count == 0)) {
4925                 SIDBG_C(SIDBG_ERRS, si_ctlp,
4926                     "ddi_intr_get_nintrs() failed, "
4927                     "rc %d count %d\n", rc, count);
4928                 return (DDI_FAILURE);
4929         }
4930 
4931         /* Allocate an array of interrupt handles. */
4932         si_ctlp->sictl_intr_size = count * sizeof (ddi_intr_handle_t);
4933         si_ctlp->sictl_htable = kmem_zalloc(si_ctlp->sictl_intr_size, KM_SLEEP);
4934 
4935         /* call ddi_intr_alloc(). */
4936         rc = ddi_intr_alloc(devinfo, si_ctlp->sictl_htable, DDI_INTR_TYPE_FIXED,
4937             inum, count, &actual, DDI_INTR_ALLOC_STRICT);
4938 
4939         if ((rc != DDI_SUCCESS) || (actual == 0)) {
4940                 SIDBG_C(SIDBG_ERRS, si_ctlp,
4941                     "ddi_intr_alloc() failed, rc %d\n", rc);
4942                 kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
4943                 return (DDI_FAILURE);
4944         }
4945 
4946         if (actual < count) {
4947                 SIDBG_C(SIDBG_ERRS, si_ctlp,
4948                     "Requested: %d, Received: %d", count, actual);
4949 
4950                 for (x = 0; x < actual; x++) {
4951                         (void) ddi_intr_free(si_ctlp->sictl_htable[x]);
4952                 }
4953 
4954                 kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
4955                 return (DDI_FAILURE);
4956         }
4957 
4958         si_ctlp->sictl_intr_cnt = actual;
4959 
4960         /* Get intr priority. */
4961         if (ddi_intr_get_pri(si_ctlp->sictl_htable[0],
4962             &si_ctlp->sictl_intr_pri) != DDI_SUCCESS) {
4963                 SIDBG_C(SIDBG_ERRS, si_ctlp,
4964                     "ddi_intr_get_pri() failed", NULL);
4965 
4966                 for (x = 0; x < actual; x++) {
4967                         (void) ddi_intr_free(si_ctlp->sictl_htable[x]);
4968                 }
4969 
4970                 kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
4971                 return (DDI_FAILURE);
4972         }
4973 
4974         /* Test for high level mutex. */
4975         if (si_ctlp->sictl_intr_pri >= ddi_intr_get_hilevel_pri()) {
4976                 SIDBG_C(SIDBG_ERRS, si_ctlp,
4977                     "si_add_legacy_intrs: Hi level intr not supported", NULL);
4978 
4979                 for (x = 0; x < actual; x++) {
4980                         (void) ddi_intr_free(si_ctlp->sictl_htable[x]);
4981                 }
4982 
4983                 kmem_free(si_ctlp->sictl_htable, sizeof (ddi_intr_handle_t));
4984 
4985                 return (DDI_FAILURE);
4986         }
4987 
4988         /* Call ddi_intr_add_handler(). */
4989         for (x = 0; x < actual; x++) {
4990                 if (ddi_intr_add_handler(si_ctlp->sictl_htable[x], si_intr,
4991                     (caddr_t)si_ctlp, NULL) != DDI_SUCCESS) {
4992                         SIDBG_C(SIDBG_ERRS, si_ctlp,
4993                             "ddi_intr_add_handler() failed", NULL);
4994 
4995                         for (y = 0; y < actual; y++) {
4996                                 (void) ddi_intr_free(si_ctlp->sictl_htable[y]);
4997                         }
4998 
4999                         kmem_free(si_ctlp->sictl_htable,
5000                             si_ctlp->sictl_intr_size);
5001                         return (DDI_FAILURE);
5002                 }
5003         }
5004 
5005         /* Call ddi_intr_enable() for legacy interrupts. */
5006         for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
5007                 (void) ddi_intr_enable(si_ctlp->sictl_htable[x]);
5008         }
5009 
5010         return (DDI_SUCCESS);
5011 }
5012 
5013 /*
5014  * si_add_msictl_intrs() handles MSI interrupts.
5015  */
5016 static int
5017 si_add_msi_intrs(si_ctl_state_t *si_ctlp)
5018 {
5019         dev_info_t      *devinfo = si_ctlp->sictl_devinfop;
5020         int             count, avail, actual;
5021         int             x, y, rc, inum = 0;
5022 
5023         SIDBG_C(SIDBG_INIT, si_ctlp, "si_add_msi_intrs", NULL);
5024 
5025         /* get number of interrupts. */
5026         rc = ddi_intr_get_nintrs(devinfo, DDI_INTR_TYPE_MSI, &count);
5027         if ((rc != DDI_SUCCESS) || (count == 0)) {
5028                 SIDBG_C(SIDBG_ERRS, si_ctlp,
5029                     "ddi_intr_get_nintrs() failed, "
5030                     "rc %d count %d\n", rc, count);
5031                 return (DDI_FAILURE);
5032         }
5033 
5034         /* get number of available interrupts. */
5035         rc = ddi_intr_get_navail(devinfo, DDI_INTR_TYPE_MSI, &avail);
5036         if ((rc != DDI_SUCCESS) || (avail == 0)) {
5037                 SIDBG_C(SIDBG_ERRS, si_ctlp,
5038                     "ddi_intr_get_navail() failed, "
5039                     "rc %d avail %d\n", rc, avail);
5040                 return (DDI_FAILURE);
5041         }
5042 
5043         if (avail < count) {
5044                 SIDBG_C(SIDBG_INIT, si_ctlp,
5045                     "ddi_intr_get_nvail returned %d, navail() returned %d",
5046                     count, avail);
5047         }
5048 
5049         /* Allocate an array of interrupt handles. */
5050         si_ctlp->sictl_intr_size = count * sizeof (ddi_intr_handle_t);
5051         si_ctlp->sictl_htable = kmem_alloc(si_ctlp->sictl_intr_size, KM_SLEEP);
5052 
5053         /* call ddi_intr_alloc(). */
5054         rc = ddi_intr_alloc(devinfo, si_ctlp->sictl_htable, DDI_INTR_TYPE_MSI,
5055             inum, count, &actual, DDI_INTR_ALLOC_NORMAL);
5056 
5057         if ((rc != DDI_SUCCESS) || (actual == 0)) {
5058                 SIDBG_C(SIDBG_ERRS, si_ctlp,
5059                     "ddi_intr_alloc() failed, rc %d\n", rc);
5060                 kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
5061                 return (DDI_FAILURE);
5062         }
5063 
5064         /* use interrupt count returned */
5065         if (actual < count) {
5066                 SIDBG_C(SIDBG_INIT, si_ctlp,
5067                     "Requested: %d, Received: %d", count, actual);
5068         }
5069 
5070         si_ctlp->sictl_intr_cnt = actual;
5071 
5072         /*
5073          * Get priority for first msi, assume remaining are all the same.
5074          */
5075         if (ddi_intr_get_pri(si_ctlp->sictl_htable[0],
5076             &si_ctlp->sictl_intr_pri) != DDI_SUCCESS) {
5077                 SIDBG_C(SIDBG_ERRS, si_ctlp, "ddi_intr_get_pri() failed", NULL);
5078 
5079                 /* Free already allocated intr. */
5080                 for (y = 0; y < actual; y++) {
5081                         (void) ddi_intr_free(si_ctlp->sictl_htable[y]);
5082                 }
5083 
5084                 kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
5085                 return (DDI_FAILURE);
5086         }
5087 
5088         /* Test for high level mutex. */
5089         if (si_ctlp->sictl_intr_pri >= ddi_intr_get_hilevel_pri()) {
5090                 SIDBG_C(SIDBG_ERRS, si_ctlp,
5091                     "si_add_msi_intrs: Hi level intr not supported", NULL);
5092 
5093                 /* Free already allocated intr. */
5094                 for (y = 0; y < actual; y++) {
5095                         (void) ddi_intr_free(si_ctlp->sictl_htable[y]);
5096                 }
5097 
5098                 kmem_free(si_ctlp->sictl_htable, sizeof (ddi_intr_handle_t));
5099 
5100                 return (DDI_FAILURE);
5101         }
5102 
5103         /* Call ddi_intr_add_handler(). */
5104         for (x = 0; x < actual; x++) {
5105                 if (ddi_intr_add_handler(si_ctlp->sictl_htable[x], si_intr,
5106                     (caddr_t)si_ctlp, NULL) != DDI_SUCCESS) {
5107                         SIDBG_C(SIDBG_ERRS, si_ctlp,
5108                             "ddi_intr_add_handler() failed", NULL);
5109 
5110                         /* Free already allocated intr. */
5111                         for (y = 0; y < actual; y++) {
5112                                 (void) ddi_intr_free(si_ctlp->sictl_htable[y]);
5113                         }
5114 
5115                         kmem_free(si_ctlp->sictl_htable,
5116                             si_ctlp->sictl_intr_size);
5117                         return (DDI_FAILURE);
5118                 }
5119         }
5120 
5121         (void) ddi_intr_get_cap(si_ctlp->sictl_htable[0],
5122             &si_ctlp->sictl_intr_cap);
5123 
5124         if (si_ctlp->sictl_intr_cap & DDI_INTR_FLAG_BLOCK) {
5125                 /* Call ddi_intr_block_enable() for MSI. */
5126                 (void) ddi_intr_block_enable(si_ctlp->sictl_htable,
5127                     si_ctlp->sictl_intr_cnt);
5128         } else {
5129                 /* Call ddi_intr_enable() for MSI non block enable. */
5130                 for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
5131                         (void) ddi_intr_enable(si_ctlp->sictl_htable[x]);
5132                 }
5133         }
5134 
5135         return (DDI_SUCCESS);
5136 }
5137 
5138 /*
5139  * Removes the registered interrupts irrespective of whether they
5140  * were legacy or MSI.
5141  */
5142 static void
5143 si_rem_intrs(si_ctl_state_t *si_ctlp)
5144 {
5145         int x;
5146 
5147         SIDBG_C(SIDBG_INIT, si_ctlp, "si_rem_intrs entered", NULL);
5148 
5149         /* Disable all interrupts. */
5150         if ((si_ctlp->sictl_intr_type == DDI_INTR_TYPE_MSI) &&
5151             (si_ctlp->sictl_intr_cap & DDI_INTR_FLAG_BLOCK)) {
5152                 /* Call ddi_intr_block_disable(). */
5153                 (void) ddi_intr_block_disable(si_ctlp->sictl_htable,
5154                     si_ctlp->sictl_intr_cnt);
5155         } else {
5156                 for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
5157                         (void) ddi_intr_disable(si_ctlp->sictl_htable[x]);
5158                 }
5159         }
5160 
5161         /* Call ddi_intr_remove_handler(). */
5162         for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
5163                 (void) ddi_intr_remove_handler(si_ctlp->sictl_htable[x]);
5164                 (void) ddi_intr_free(si_ctlp->sictl_htable[x]);
5165         }
5166 
5167         kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
5168 }
5169 
5170 /*
5171  * Resets either the port or the device connected to the port based on
5172  * the flag variable.
5173  *
5174  * The reset effectively throws away all the pending commands. So, the caller
5175  * has to make provision to handle the pending commands.
5176  *
5177  * After the reset, we wait till the port is ready again.
5178  *
5179  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
5180  * before calling us.
5181  *
5182  * Note: Not port-mult aware.
5183  */
5184 static int
5185 si_reset_dport_wait_till_ready(
5186         si_ctl_state_t *si_ctlp,
5187         si_port_state_t *si_portp,
5188         int port,
5189         int flag)
5190 {
5191         uint32_t port_status;
5192         int loop_count = 0;
5193         sata_device_t sdevice;
5194         uint32_t SStatus;
5195         uint32_t SControl;
5196         uint32_t port_intr_status;
5197 
5198         _NOTE(ASSUMING_PROTECTED(si_portp))
5199 
5200         if (flag == SI_PORT_RESET) {
5201                 ddi_put32(si_ctlp->sictl_port_acc_handle,
5202                     (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
5203                     PORT_CONTROL_SET_BITS_PORT_RESET);
5204 
5205                 /* Port reset is not self clearing. So clear it now. */
5206                 ddi_put32(si_ctlp->sictl_port_acc_handle,
5207                     (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
5208                     PORT_CONTROL_CLEAR_BITS_PORT_RESET);
5209         } else {
5210                 /* Reset the device. */
5211                 ddi_put32(si_ctlp->sictl_port_acc_handle,
5212                     (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
5213                     PORT_CONTROL_SET_BITS_DEV_RESET);
5214 
5215                 /*
5216                  * tidbit: this bit is self clearing; so there is no need
5217                  * for manual clear as we did for port reset.
5218                  */
5219         }
5220 
5221         /* Set the reset in progress flag */
5222         if (!(flag & SI_RESET_NO_EVENTS_UP)) {
5223                 si_portp->siport_reset_in_progress = 1;
5224         }
5225 
5226 
5227         /*
5228          * Every reset needs a PHY initialization.
5229          *
5230          * The way to initialize the PHY is to write a 1 and then
5231          * a 0 to DET field of SControl register.
5232          */
5233 
5234         /* Fetch the current SControl before writing the DET part with 1. */
5235         SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
5236             (uint32_t *)PORT_SCONTROL(si_ctlp, port));
5237         SCONTROL_SET_DET(SControl, SCONTROL_DET_COMRESET);
5238         ddi_put32(si_ctlp->sictl_port_acc_handle,
5239             (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
5240             SControl);
5241 #ifndef __lock_lint
5242         delay(SI_10MS_TICKS); /* give time for COMRESET to percolate */
5243 #endif /* __lock_lint */
5244 
5245         /* Now fetch the SControl again and rewrite the DET part with 0 */
5246         SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
5247             (uint32_t *)PORT_SCONTROL(si_ctlp, port));
5248         SCONTROL_SET_DET(SControl, SCONTROL_DET_NOACTION);
5249         ddi_put32(si_ctlp->sictl_port_acc_handle,
5250             (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
5251             SControl);
5252 
5253         /*
5254          * PHY may be initialized by now. Check the DET field of SStatus
5255          * to determine if there is a device present.
5256          *
5257          * The DET field is valid only if IPM field indicates that
5258          * the interface is in active state.
5259          */
5260 
5261         loop_count = 0;
5262         do {
5263                 SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
5264                     (uint32_t *)PORT_SSTATUS(si_ctlp, port));
5265 
5266                 if (SSTATUS_GET_IPM(SStatus) !=
5267                     SSTATUS_IPM_INTERFACE_ACTIVE) {
5268                         /*
5269                          * If the interface is not active, the DET field
5270                          * is considered not accurate. So we want to
5271                          * continue looping.
5272                          */
5273                         SSTATUS_SET_DET(SStatus, SSTATUS_DET_NODEV_NOPHY);
5274                 }
5275 
5276                 if (loop_count++ > SI_POLLRATE_SSTATUS) {
5277                         /* We are effectively timing out after 0.1 sec. */
5278                         break;
5279                 }
5280 
5281                 /* Wait for 10 millisec */
5282 #ifndef __lock_lint
5283                 delay(SI_10MS_TICKS);
5284 #endif /* __lock_lint */
5285 
5286         } while (SSTATUS_GET_DET(SStatus) != SSTATUS_DET_DEVPRESENT_PHYONLINE);
5287 
5288         SIDBG_P(SIDBG_POLL_LOOP, si_portp,
5289             "si_reset_dport_wait_till_ready: loop count: %d, \
5290                 SStatus: 0x%x",
5291             loop_count,
5292             SStatus);
5293 
5294         /* Now check for port readiness. */
5295         loop_count = 0;
5296         do {
5297                 port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
5298                     (uint32_t *)PORT_STATUS(si_ctlp, port));
5299 
5300                 if (loop_count++ > SI_POLLRATE_PORTREADY) {
5301                         /* We are effectively timing out after 0.5 sec. */
5302                         break;
5303                 }
5304 
5305                 /* Wait for 10 millisec */
5306 #ifndef __lock_lint
5307                 delay(SI_10MS_TICKS);
5308 #endif /* __lock_lint */
5309 
5310         } while (!(port_status & PORT_STATUS_BITS_PORT_READY));
5311 
5312         SIDBG_P(SIDBG_POLL_LOOP, si_portp,
5313             "si_reset_dport_wait_till_ready: loop count: %d, \
5314                 port_status: 0x%x, SStatus: 0x%x",
5315             loop_count,
5316             port_status,
5317             SStatus);
5318 
5319         /* Indicate to the framework that a reset has happened. */
5320         if (!(flag & SI_RESET_NO_EVENTS_UP)) {
5321 
5322                 bzero((void *)&sdevice, sizeof (sata_device_t));
5323 
5324                 sdevice.satadev_addr.cport = (uint8_t)port;
5325                 sdevice.satadev_addr.pmport = PORTMULT_CONTROL_PORT;
5326 
5327                 if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
5328                         sdevice.satadev_addr.qual = SATA_ADDR_DPMPORT;
5329                 } else {
5330                         sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
5331                 }
5332                 sdevice.satadev_state = SATA_DSTATE_RESET |
5333                     SATA_DSTATE_PWR_ACTIVE;
5334                 if (si_ctlp->sictl_sata_hba_tran) {
5335                         sata_hba_event_notify(
5336                             si_ctlp->sictl_sata_hba_tran->sata_tran_hba_dip,
5337                             &sdevice,
5338                             SATA_EVNT_DEVICE_RESET);
5339                 }
5340 
5341                 SIDBG_P(SIDBG_EVENT, si_portp,
5342                     "sending event up: SATA_EVNT_RESET", NULL);
5343         }
5344 
5345         if ((SSTATUS_GET_IPM(SStatus) == SSTATUS_IPM_INTERFACE_ACTIVE) &&
5346             (SSTATUS_GET_DET(SStatus) ==
5347             SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
5348                 /* The interface is active and the device is present */
5349                 if (!(port_status & PORT_STATUS_BITS_PORT_READY)) {
5350                         /* But the port is is not ready for some reason */
5351                         SIDBG_P(SIDBG_POLL_LOOP, si_portp,
5352                             "si_reset_dport_wait_till_ready failed", NULL);
5353                         return (SI_FAILURE);
5354                 }
5355         }
5356 
5357 
5358         /*
5359          * For some reason, we are losing the interrupt enablement after
5360          * any reset condition. So restore them back now.
5361          */
5362 
5363         SIDBG_P(SIDBG_INIT, si_portp,
5364             "current interrupt enable set: 0x%x",
5365             ddi_get32(si_ctlp->sictl_port_acc_handle,
5366             (uint32_t *)PORT_INTERRUPT_ENABLE_SET(si_ctlp, port)));
5367 
5368         ddi_put32(si_ctlp->sictl_port_acc_handle,
5369             (uint32_t *)PORT_INTERRUPT_ENABLE_SET(si_ctlp, port),
5370             (INTR_COMMAND_COMPLETE |
5371             INTR_COMMAND_ERROR |
5372             INTR_PORT_READY |
5373             INTR_POWER_CHANGE |
5374             INTR_PHYRDY_CHANGE |
5375             INTR_COMWAKE_RECEIVED |
5376             INTR_UNRECOG_FIS |
5377             INTR_DEV_XCHANGED |
5378             INTR_SETDEVBITS_NOTIFY));
5379 
5380         si_enable_port_interrupts(si_ctlp, port);
5381 
5382         /*
5383          * make sure interrupts are cleared
5384          */
5385         port_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
5386             (uint32_t *)PORT_INTERRUPT_STATUS(si_ctlp, port));
5387 
5388         ddi_put32(si_ctlp->sictl_port_acc_handle,
5389             (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp,
5390             port)),
5391             port_intr_status & INTR_MASK);
5392 
5393 
5394         SIDBG_P(SIDBG_POLL_LOOP, si_portp,
5395             "si_reset_dport_wait_till_ready returning success", NULL);
5396 
5397         return (SI_SUCCESS);
5398 }
5399 
5400 /*
5401  * Schedule an initialization of the port using a timeout to get it done
5402  * off an interrupt thread.
5403  *
5404  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
5405  * before calling us.
5406  */
5407 static void
5408 si_schedule_port_initialize(
5409         si_ctl_state_t *si_ctlp,
5410         si_port_state_t *si_portp,
5411         int port)
5412 {
5413         si_event_arg_t *args;
5414 
5415         ASSERT(mutex_owned(&si_portp->siport_mutex));
5416 
5417         args = si_portp->siport_event_args;
5418         if (args->siea_ctlp != NULL) {
5419                 cmn_err(CE_WARN, "si_schedule_port_initialize: "
5420                     "args->si_ctlp != NULL");
5421                 return;
5422         }
5423 
5424         args->siea_ctlp = si_ctlp;
5425         args->siea_port = port;
5426 
5427         (void) timeout(si_do_initialize_port, si_portp, 1);
5428 }
5429 
5430 /*
5431  * Called from timeout()
5432  * Unpack the arguments and call si_initialize_port_wait_till_ready()
5433  */
5434 static void
5435 si_do_initialize_port(void *arg)
5436 {
5437         si_event_arg_t *args;
5438         si_ctl_state_t *si_ctlp;
5439         si_port_state_t *si_portp;
5440         int port;
5441 
5442         si_portp = arg;
5443         mutex_enter(&si_portp->siport_mutex);
5444 
5445         args = si_portp->siport_event_args;
5446         si_ctlp = args->siea_ctlp;
5447         port = args->siea_port;
5448         args->siea_ctlp = NULL;      /* mark siport_event_args as free */
5449         (void) si_initialize_port_wait_till_ready(si_ctlp, port);
5450 
5451         mutex_exit(&si_portp->siport_mutex);
5452 }
5453 
5454 
5455 /*
5456  * Initializes the port.
5457  *
5458  * Initialization effectively throws away all the pending commands on
5459  * the port. So, the caller  has to make provision to handle the pending
5460  * commands.
5461  *
5462  * After the port initialization, we wait till the port is ready again.
5463  *
5464  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
5465  * before calling us.
5466  */
5467 static int
5468 si_initialize_port_wait_till_ready(si_ctl_state_t *si_ctlp, int port)
5469 {
5470         uint32_t port_status;
5471         int loop_count = 0;
5472         uint32_t SStatus;
5473         si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
5474 
5475         /* Initialize the port. */
5476         ddi_put32(si_ctlp->sictl_port_acc_handle,
5477             (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
5478             PORT_CONTROL_SET_BITS_PORT_INITIALIZE);
5479 
5480         /* Wait until Port Ready */
5481         loop_count = 0;
5482         do {
5483                 port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
5484                     (uint32_t *)PORT_STATUS(si_ctlp, port));
5485 
5486                 if (loop_count++ > SI_POLLRATE_PORTREADY) {
5487                         SIDBG_P(SIDBG_INTR, si_portp,
5488                             "si_initialize_port_wait is timing out: "
5489                             "port_status: %x",
5490                             port_status);
5491                         /* We are effectively timing out after 0.5 sec. */
5492                         break;
5493                 }
5494 
5495                 /* Wait for 10 millisec */
5496 #ifndef __lock_lint
5497                 delay(SI_10MS_TICKS);
5498 #endif /* __lock_lint */
5499 
5500         } while (!(port_status & PORT_STATUS_BITS_PORT_READY));
5501 
5502         SIDBG_P(SIDBG_POLL_LOOP, si_portp,
5503             "si_initialize_port_wait_till_ready: loop count: %d",
5504             loop_count);
5505 
5506         SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
5507             (uint32_t *)PORT_SSTATUS(si_ctlp, port));
5508 
5509         if ((SSTATUS_GET_IPM(SStatus) == SSTATUS_IPM_INTERFACE_ACTIVE) &&
5510             (SSTATUS_GET_DET(SStatus) ==
5511             SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
5512                 /* The interface is active and the device is present */
5513                 if (!(port_status & PORT_STATUS_BITS_PORT_READY)) {
5514                         /* But the port is is not ready for some reason */
5515                         return (SI_FAILURE);
5516                 }
5517         }
5518 
5519         return (SI_SUCCESS);
5520 }
5521 
5522 
5523 /*
5524  * si_watchdog_handler() calls us if it detects that there are some
5525  * commands which timed out. We recalculate the timed out commands once
5526  * again since some of them may have finished recently.
5527  */
5528 static void
5529 si_timeout_pkts(
5530         si_ctl_state_t *si_ctlp,
5531         si_port_state_t *si_portp,
5532         int port,
5533         uint32_t timedout_tags)
5534 {
5535         uint32_t slot_status;
5536         uint32_t finished_tags;
5537 
5538         SIDBG_P(SIDBG_TIMEOUT, si_portp,
5539             "si_timeout_pkts entry", NULL);
5540 
5541         mutex_enter(&si_portp->siport_mutex);
5542         slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
5543             (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
5544 
5545         si_portp->mopping_in_progress++;
5546 
5547         /*
5548          * Initialize the controller. The only way to timeout the commands
5549          * is to reset or initialize the controller. We mop commands after
5550          * the initialization.
5551          */
5552         (void) si_initialize_port_wait_till_ready(si_ctlp, port);
5553 
5554         /*
5555          * Recompute the timedout tags since some of them may have finished
5556          * meanwhile.
5557          */
5558         finished_tags =  si_portp->siport_pending_tags &
5559             ~slot_status & SI_SLOT_MASK;
5560         timedout_tags &= ~finished_tags;
5561 
5562         SIDBG_P(SIDBG_TIMEOUT, si_portp,
5563             "si_timeout_pkts: finished: %x, timeout: %x",
5564             finished_tags,
5565             timedout_tags);
5566 
5567         si_mop_commands(si_ctlp,
5568             si_portp,
5569             port,
5570             slot_status,
5571             0, /* failed_tags */
5572             timedout_tags,
5573             0, /* aborting_tags */
5574             0);  /* reset_tags */
5575 
5576         mutex_exit(&si_portp->siport_mutex);
5577 }
5578 
5579 
5580 
5581 /*
5582  * Watchdog handler kicks in every 5 seconds to timeout any commands pending
5583  * for long time.
5584  */
5585 static void
5586 si_watchdog_handler(si_ctl_state_t *si_ctlp)
5587 {
5588         uint32_t pending_tags = 0;
5589         uint32_t timedout_tags = 0;
5590         si_port_state_t *si_portp;
5591         int port;
5592         int tmpslot;
5593         sata_pkt_t *satapkt;
5594 
5595         /* max number of cycles this packet should survive */
5596         int max_life_cycles;
5597 
5598         /* how many cycles this packet survived so far */
5599         int watched_cycles;
5600 
5601         mutex_enter(&si_ctlp->sictl_mutex);
5602         SIDBG_C(SIDBG_ENTRY, si_ctlp,
5603             "si_watchdog_handler entered", NULL);
5604 
5605         for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
5606 
5607                 si_portp = si_ctlp->sictl_ports[port];
5608                 if (si_portp == NULL) {
5609                         continue;
5610                 }
5611 
5612                 mutex_enter(&si_portp->siport_mutex);
5613 
5614                 if (si_portp->siport_port_type == PORT_TYPE_NODEV) {
5615                         mutex_exit(&si_portp->siport_mutex);
5616                         continue;
5617                 }
5618 
5619                 /* Skip the check for those ports in error recovery */
5620                 if (si_portp->mopping_in_progress > 0) {
5621                         SIDBG_P(SIDBG_INFO, si_portp,
5622                             "si_watchdog_handler: port %d mopping "
5623                             "in progress, so just return", port);
5624                         mutex_exit(&si_portp->siport_mutex);
5625                         continue;
5626                 }
5627 
5628                 pending_tags =  si_portp->siport_pending_tags;
5629                 timedout_tags = 0;
5630                 while (pending_tags) {
5631                         tmpslot = ddi_ffs(pending_tags) - 1;
5632                         if (tmpslot == -1) {
5633                                 break;
5634                         }
5635                         satapkt = si_portp->siport_slot_pkts[tmpslot];
5636 
5637                         if ((satapkt != NULL) && satapkt->satapkt_time) {
5638 
5639                                 /*
5640                                  * We are overloading satapkt_hba_driver_private
5641                                  * with watched_cycle count.
5642                                  *
5643                                  * If a packet has survived for more than it's
5644                                  * max life cycles, it is a candidate for time
5645                                  * out.
5646                                  */
5647                                 watched_cycles = (int)(intptr_t)
5648                                     satapkt->satapkt_hba_driver_private;
5649                                 watched_cycles++;
5650                                 max_life_cycles = (satapkt->satapkt_time +
5651                                     si_watchdog_timeout - 1) /
5652                                     si_watchdog_timeout;
5653                                 if (watched_cycles > max_life_cycles) {
5654                                         timedout_tags |= (0x1 << tmpslot);
5655                                         SIDBG_P(SIDBG_TIMEOUT,
5656                                             si_portp,
5657                                             "watchdog: timedout_tags: 0x%x",
5658                                             timedout_tags);
5659                                 }
5660                                 satapkt->satapkt_hba_driver_private =
5661                                     (void *)(intptr_t)watched_cycles;
5662                         }
5663 
5664                         CLEAR_BIT(pending_tags, tmpslot);
5665                 }
5666 
5667                 if (timedout_tags) {
5668                         mutex_exit(&si_portp->siport_mutex);
5669                         mutex_exit(&si_ctlp->sictl_mutex);
5670                         si_timeout_pkts(si_ctlp, si_portp, port, timedout_tags);
5671                         mutex_enter(&si_ctlp->sictl_mutex);
5672                         mutex_enter(&si_portp->siport_mutex);
5673                 }
5674 
5675                 mutex_exit(&si_portp->siport_mutex);
5676         }
5677 
5678         /* Reinstall the watchdog timeout handler. */
5679         if (!(si_ctlp->sictl_flags & SI_NO_TIMEOUTS)) {
5680                 si_ctlp->sictl_timeout_id =
5681                     timeout((void (*)(void *))si_watchdog_handler,
5682                     (caddr_t)si_ctlp, si_watchdog_tick);
5683         }
5684         mutex_exit(&si_ctlp->sictl_mutex);
5685 }
5686 
5687 /*
5688  * FMA Functions
5689  */
5690 
5691 /*
5692  * The IO fault service error handling callback function
5693  */
5694 /*ARGSUSED*/
5695 static int
5696 si_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
5697 {
5698         /*
5699          * as the driver can always deal with an error in any dma or
5700          * access handle, we can just return the fme_status value.
5701          */
5702         pci_ereport_post(dip, err, NULL);
5703         return (err->fme_status);
5704 }
5705 
5706 /*
5707  * si_fm_init - initialize fma capabilities and register with IO
5708  *              fault services.
5709  */
5710 static void
5711 si_fm_init(si_ctl_state_t *si_ctlp)
5712 {
5713         /*
5714          * Need to change iblock to priority for new MSI intr
5715          */
5716         ddi_iblock_cookie_t fm_ibc;
5717 
5718         /* Only register with IO Fault Services if we have some capability */
5719         if (si_ctlp->fm_capabilities) {
5720                 /* Adjust access and dma attributes for FMA */
5721                 accattr.devacc_attr_access = DDI_FLAGERR_ACC;
5722                 prb_sgt_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
5723                 buffer_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
5724 
5725                 /*
5726                  * Register capabilities with IO Fault Services.
5727                  * fm_capabilities will be updated to indicate
5728                  * capabilities actually supported (not requested.)
5729                  */
5730                 ddi_fm_init(si_ctlp->sictl_devinfop, &si_ctlp->fm_capabilities,
5731                     &fm_ibc);
5732 
5733                 if (si_ctlp->fm_capabilities == DDI_FM_NOT_CAPABLE)
5734                         cmn_err(CE_WARN, "si_fm_init: ddi_fm_init fail");
5735 
5736                 /*
5737                  * Initialize pci ereport capabilities if ereport
5738                  * capable (should always be.)
5739                  */
5740                 if (DDI_FM_EREPORT_CAP(si_ctlp->fm_capabilities) ||
5741                     DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
5742                         pci_ereport_setup(si_ctlp->sictl_devinfop);
5743                 }
5744 
5745                 /*
5746                  * Register error callback if error callback capable.
5747                  */
5748                 if (DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
5749                         ddi_fm_handler_register(si_ctlp->sictl_devinfop,
5750                             si_fm_error_cb, (void *) si_ctlp);
5751                 }
5752         }
5753 }
5754 
5755 /*
5756  * si_fm_fini - Releases fma capabilities and un-registers with IO
5757  *              fault services.
5758  */
5759 static void
5760 si_fm_fini(si_ctl_state_t *si_ctlp)
5761 {
5762         /* Only unregister FMA capabilities if registered */
5763         if (si_ctlp->fm_capabilities) {
5764                 /*
5765                  * Un-register error callback if error callback capable.
5766                  */
5767                 if (DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
5768                         ddi_fm_handler_unregister(si_ctlp->sictl_devinfop);
5769                 }
5770 
5771                 /*
5772                  * Release any resources allocated by pci_ereport_setup()
5773                  */
5774                 if (DDI_FM_EREPORT_CAP(si_ctlp->fm_capabilities) ||
5775                     DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
5776                         pci_ereport_teardown(si_ctlp->sictl_devinfop);
5777                 }
5778 
5779                 /* Unregister from IO Fault Services */
5780                 ddi_fm_fini(si_ctlp->sictl_devinfop);
5781 
5782                 /* Adjust access and dma attributes for FMA */
5783                 accattr.devacc_attr_access = DDI_DEFAULT_ACC;
5784                 prb_sgt_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
5785                 buffer_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
5786         }
5787 }
5788 
5789 static int
5790 si_check_acc_handle(ddi_acc_handle_t handle)
5791 {
5792         ddi_fm_error_t de;
5793 
5794         ASSERT(handle != NULL);
5795         ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION);
5796         return (de.fme_status);
5797 }
5798 
5799 static int
5800 si_check_dma_handle(ddi_dma_handle_t handle)
5801 {
5802         ddi_fm_error_t de;
5803 
5804         ASSERT(handle != NULL);
5805         ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION);
5806         return (de.fme_status);
5807 }
5808 
5809 static int
5810 si_check_ctl_handles(si_ctl_state_t *si_ctlp)
5811 {
5812         if ((si_check_acc_handle(si_ctlp->sictl_pci_conf_handle)
5813             != DDI_SUCCESS) ||
5814             (si_check_acc_handle(si_ctlp->sictl_global_acc_handle)
5815             != DDI_SUCCESS) ||
5816             (si_check_acc_handle(si_ctlp->sictl_port_acc_handle)
5817             != DDI_SUCCESS)) {
5818                 return (DDI_FAILURE);
5819         }
5820 
5821         return (DDI_SUCCESS);
5822 }
5823 
5824 /*
5825  * WARNING: The caller is expected to obtain the siport_mutex
5826  * before calling us.
5827  */
5828 static int
5829 si_check_port_handles(si_port_state_t *si_portp)
5830 {
5831         if ((si_check_dma_handle(si_portp->siport_prbpool_dma_handle)
5832             != DDI_SUCCESS) ||
5833             (si_check_acc_handle(si_portp->siport_prbpool_acc_handle)
5834             != DDI_SUCCESS) ||
5835             (si_check_dma_handle(si_portp->siport_sgbpool_dma_handle)
5836             != DDI_SUCCESS) ||
5837             (si_check_acc_handle(si_portp->siport_sgbpool_acc_handle)
5838             != DDI_SUCCESS)) {
5839                 return (DDI_FAILURE);
5840         }
5841 
5842         return (DDI_SUCCESS);
5843 }
5844 
5845 static void
5846 si_fm_ereport(si_ctl_state_t *si_ctlp, char *detail, char *payload)
5847 {
5848         uint64_t ena;
5849         char buf[FM_MAX_CLASS];
5850 
5851         (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
5852         ena = fm_ena_generate(0, FM_ENA_FMT1);
5853 
5854         if (DDI_FM_EREPORT_CAP(si_ctlp->fm_capabilities)) {
5855                 ddi_fm_ereport_post(si_ctlp->sictl_devinfop, buf, ena,
5856                     DDI_NOSLEEP,
5857                     FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERSION,
5858                     "detailed_err_type", DATA_TYPE_STRING, payload,
5859                     NULL);
5860         }
5861 }
5862 
5863 /*
5864  * Logs the message.
5865  */
5866 static void
5867 si_log(si_ctl_state_t *si_ctlp, si_port_state_t *si_portp, char *fmt, ...)
5868 {
5869         va_list ap;
5870 
5871         mutex_enter(&si_log_mutex);
5872 
5873         va_start(ap, fmt);
5874 
5875         if (si_portp == NULL && si_ctlp == NULL) {
5876                 sata_vtrace_debug(NULL, fmt, ap);
5877                 va_end(ap);
5878                 mutex_exit(&si_log_mutex);
5879                 return;
5880         }
5881 
5882         if (si_portp == NULL && si_ctlp != NULL) {
5883                 sata_vtrace_debug(si_ctlp->sictl_devinfop, fmt, ap);
5884                 va_end(ap);
5885                 mutex_exit(&si_log_mutex);
5886                 return;
5887         }
5888 
5889         /*
5890          * si_portp is not NULL, but si_ctlp might be.
5891          * Reference si_portp for both port and dip.
5892          */
5893         (void) snprintf(si_log_buf, SI_LOGBUF_LEN, "port%d: %s",
5894             si_portp->siport_port_num, fmt);
5895 
5896         if (si_portp->siport_ctlp == NULL) {
5897                 sata_vtrace_debug(NULL, si_log_buf, ap);
5898                 va_end(ap);
5899                 mutex_exit(&si_log_mutex);
5900                 return;
5901         }
5902 
5903         sata_vtrace_debug(si_portp->siport_ctlp->sictl_devinfop,
5904             si_log_buf, ap);
5905 
5906         va_end(ap);
5907 
5908         mutex_exit(&si_log_mutex);
5909 
5910 }
5911 
5912 static void
5913 si_copy_out_regs(sata_cmd_t *scmd, si_ctl_state_t *si_ctlp, uint8_t port,
5914         uint8_t slot)
5915 {
5916         uint32_t *fis_word_ptr;
5917         si_prb_t *prb;
5918         int i;
5919         si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
5920 
5921         /*
5922          * The LRAM contains the the modified FIS after command completion, so
5923          * first copy it back to the in-core PRB pool.  To save read cycles,
5924          * just copy over the FIS portion of the PRB pool.
5925          */
5926         prb =  &si_ctlp->sictl_ports[port]->siport_prbpool[slot];
5927 
5928         fis_word_ptr = (uint32_t *)(void *)(&prb->prb_fis);
5929 
5930         for (i = 0; i < (sizeof (fis_reg_h2d_t)/4); i++) {
5931                 fis_word_ptr[i] = ddi_get32(
5932                     si_ctlp->sictl_port_acc_handle,
5933                     (uint32_t *)(PORT_LRAM(si_ctlp, port,
5934                     slot) + i * 4 + 0x08));
5935         }
5936 
5937         /*
5938          * always get the status register
5939          */
5940         scmd->satacmd_status_reg = GET_FIS_COMMAND(prb->prb_fis);
5941 
5942         DTRACE_PROBE1(satacmd_status_reg, int, scmd->satacmd_status_reg);
5943 
5944         if (scmd->satacmd_flags.sata_copy_out_sec_count_msb) {
5945                 scmd->satacmd_sec_count_msb =
5946                     GET_FIS_SECTOR_COUNT_EXP(prb->prb_fis);
5947                 SIDBG_P(SIDBG_VERBOSE, si_portp,
5948                     "copyout satacmd_sec_count_msb %x\n",
5949                     scmd->satacmd_sec_count_msb);
5950         }
5951 
5952         if (scmd->satacmd_flags.sata_copy_out_lba_low_msb) {
5953                 scmd->satacmd_lba_low_msb = GET_FIS_SECTOR_EXP(prb->prb_fis);
5954                 SIDBG_P(SIDBG_VERBOSE, si_portp,
5955                     "copyout satacmd_lba_low_msb %x\n",
5956                     scmd->satacmd_lba_low_msb);
5957         }
5958 
5959         if (scmd->satacmd_flags.sata_copy_out_lba_mid_msb) {
5960                 scmd->satacmd_lba_mid_msb = GET_FIS_CYL_LOW_EXP(prb->prb_fis);
5961                 SIDBG_P(SIDBG_VERBOSE, si_portp,
5962                     "copyout satacmd_lba_mid_msb %x\n",
5963                     scmd->satacmd_lba_mid_msb);
5964         }
5965 
5966         if (scmd->satacmd_flags.sata_copy_out_lba_high_msb) {
5967                 scmd->satacmd_lba_high_msb = GET_FIS_CYL_HI_EXP(prb->prb_fis);
5968                 SIDBG_P(SIDBG_VERBOSE, si_portp,
5969                     "copyout satacmd_lba_high_msb %x\n",
5970                     scmd->satacmd_lba_high_msb);
5971         }
5972 
5973         if (scmd->satacmd_flags.sata_copy_out_sec_count_lsb) {
5974                 scmd->satacmd_sec_count_lsb =
5975                     GET_FIS_SECTOR_COUNT(prb->prb_fis);
5976                 SIDBG_P(SIDBG_VERBOSE, si_portp,
5977                     "copyout satacmd_sec_count_lsb %x\n",
5978                     scmd->satacmd_sec_count_lsb);
5979         }
5980 
5981         if (scmd->satacmd_flags.sata_copy_out_lba_low_lsb) {
5982                 scmd->satacmd_lba_low_lsb = GET_FIS_SECTOR(prb->prb_fis);
5983                 SIDBG_P(SIDBG_VERBOSE, si_portp,
5984                     "copyout satacmd_lba_low_lsb %x\n",
5985                     scmd->satacmd_lba_low_lsb);
5986         }
5987 
5988         if (scmd->satacmd_flags.sata_copy_out_lba_mid_lsb) {
5989                 scmd->satacmd_lba_mid_lsb = GET_FIS_CYL_LOW(prb->prb_fis);
5990                 SIDBG_P(SIDBG_VERBOSE, si_portp,
5991                     "copyout satacmd_lba_mid_lsb %x\n",
5992                     scmd->satacmd_lba_mid_lsb);
5993         }
5994 
5995         if (scmd->satacmd_flags.sata_copy_out_lba_high_lsb) {
5996                 scmd->satacmd_lba_high_lsb = GET_FIS_CYL_HI(prb->prb_fis);
5997                 SIDBG_P(SIDBG_VERBOSE, si_portp,
5998                     "copyout satacmd_lba_high_lsb %x\n",
5999                     scmd->satacmd_lba_high_lsb);
6000         }
6001 
6002         if (scmd->satacmd_flags.sata_copy_out_device_reg) {
6003                 scmd->satacmd_device_reg = GET_FIS_DEV_HEAD(prb->prb_fis);
6004                 SIDBG_P(SIDBG_VERBOSE, si_portp,
6005                     "copyout satacmd_device_reg %x\n",
6006                     scmd->satacmd_device_reg);
6007         }
6008 
6009         if (scmd->satacmd_flags.sata_copy_out_error_reg) {
6010                 scmd->satacmd_error_reg = GET_FIS_FEATURES(prb->prb_fis);
6011                 SIDBG_P(SIDBG_VERBOSE, si_portp,
6012                     "copyout satacmd_error_reg %x\n",
6013                     scmd->satacmd_error_reg);
6014         }
6015 }
6016 
6017 /*
6018  * This function clear the special port by send the PORT RESET
6019  * After reset was sent, all commands running on the port
6020  * is aborted
6021  */
6022 static int
6023 si_clear_port(si_ctl_state_t *si_ctlp, int port)
6024 {
6025 
6026         if (si_ctlp == NULL)
6027                 return (SI_FAILURE);
6028         /*
6029          * reset this port so that all existing command
6030          * is clear
6031          */
6032         ddi_put32(si_ctlp->sictl_port_acc_handle,
6033             (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
6034             PORT_CONTROL_SET_BITS_PORT_RESET);
6035 
6036         /* Port reset is not self clearing. So clear it now. */
6037         ddi_put32(si_ctlp->sictl_port_acc_handle,
6038             (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
6039             PORT_CONTROL_CLEAR_BITS_PORT_RESET);
6040         return (SI_SUCCESS);
6041 }
6042 
6043 /*
6044  * quiesce(9E) entry point.
6045  * This function is called when the system is single-threaded at high
6046  * PIL with preemption disabled. Therefore, this function must not be
6047  * blocked.
6048  *
6049  * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
6050  * DDI_FAILURE indicates an error condition and should almost never happen.
6051  */
6052 static int
6053 si_quiesce(dev_info_t *dip)
6054 {
6055         si_ctl_state_t *si_ctlp;
6056         int instance;
6057         int port;
6058 
6059         instance = ddi_get_instance(dip);
6060         si_ctlp = ddi_get_soft_state(si_statep, instance);
6061         if (si_ctlp == NULL)
6062                 return (DDI_FAILURE);
6063 
6064         SIDBG_C(SIDBG_ENTRY, si_ctlp, "si_quiesce enter", NULL);
6065         /*
6066          * Disable all the interrupts before quiesce
6067          */
6068 
6069         for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
6070                 si_disable_port_interrupts(si_ctlp, port);
6071                 (void) si_clear_port(si_ctlp, port);
6072         }
6073 
6074         return (DDI_SUCCESS);
6075 }