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