9241 si3124: this statement may fall through
[unleashed.git] / usr / src / uts / common / io / sata / adapters / si3124 / si3124.c
blob32df68974996a48c3215d91343c0b1ff40127bbe
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
28 * SiliconImage 3124/3132/3531 sata controller driver
34 * Few Design notes
37 * I. General notes
39 * Even though the driver is named as si3124, it is actually meant to
40 * work with SiI3124, SiI3132 and SiI3531 controllers.
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.
48 * II. Data structures
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.
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.
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.
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.
87 * III. Driver operation
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.
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.
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.
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.
124 * Here is the implementation strategy based on SiliconImage email
125 * regarding how they handle the errors for their Windows driver:
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
133 * If the port is not connected to port multiplier, issue
134 * a Port Initialize.
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.
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
146 * If the port is not connected to port multiplier, issue
147 * a Device Reset.
149 * d) for DATAFISERROR:
150 * If the port was executing an NCQ command, issue a Device
151 * Reset.
153 * Otherwise, follow the same error recovery as DEVICEERROR.
155 * e) for any other error, simply issue a Device Reset.
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.
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)
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.
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.
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.
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].
188 * IV. Known Issues
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.
196 * 2) Do real REQUEST SENSE command instead of faking for ATAPI case.
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>
210 * FMA header files
212 #include <sys/ddifm.h>
213 #include <sys/fm/protocol.h>
214 #include <sys/fm/util.h>
215 #include <sys/fm/io/ddi.h>
218 * Function prototypes for driver entry points
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 *);
226 * Function prototypes for SATA Framework interfaces
228 static int si_register_sata_hba_tran(si_ctl_state_t *);
229 static int si_unregister_sata_hba_tran(si_ctl_state_t *);
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 *);
239 * Local function prototypes
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);
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 *);
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);
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);
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 *);
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);
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 *);
323 * FMA Prototypes
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 *);
334 static void si_log(si_ctl_state_t *, si_port_state_t *, char *, ...);
336 static void si_copy_out_regs(sata_cmd_t *, si_ctl_state_t *, uint8_t, uint8_t);
339 * DMA attributes for the data buffer
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 */
358 * DMA attributes for incore RPB and SGT pool
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 */
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
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 */
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
406 static int si_watchdog_timeout = 5; /* 5 seconds */
407 static int si_watchdog_tick;
409 extern struct mod_ops mod_driverops;
411 static struct modldrv modldrv = {
412 &mod_driverops, /* driverops */
413 "si3124 driver",
414 &sictl_dev_ops, /* driver ops */
417 static struct modlinkage modlinkage = {
418 MODREV_1,
419 &modldrv,
420 NULL
424 /* The following are needed for si_log() */
425 static kmutex_t si_log_mutex;
426 static char si_log_buf[SI_LOGBUF_LEN];
427 uint32_t si_debug_flags =
428 SIDBG_ERRS|SIDBG_INIT|SIDBG_EVENT|SIDBG_TIMEOUT|SIDBG_RESET;
430 static int is_msi_supported = 0;
433 * The below global variables are tunable via /etc/system
435 * si_dma_sg_number
438 int si_dma_sg_number = SI_DEFAULT_SGT_TABLES_PER_PRB;
440 /* Opaque state pointer to be initialized by ddi_soft_state_init() */
441 static void *si_statep = NULL;
444 * si3124 module initialization.
448 _init(void)
450 int error;
452 error = ddi_soft_state_init(&si_statep, sizeof (si_ctl_state_t), 0);
453 if (error != 0) {
454 return (error);
457 mutex_init(&si_log_mutex, NULL, MUTEX_DRIVER, NULL);
459 if ((error = sata_hba_init(&modlinkage)) != 0) {
460 mutex_destroy(&si_log_mutex);
461 ddi_soft_state_fini(&si_statep);
462 return (error);
465 error = mod_install(&modlinkage);
466 if (error != 0) {
467 sata_hba_fini(&modlinkage);
468 mutex_destroy(&si_log_mutex);
469 ddi_soft_state_fini(&si_statep);
470 return (error);
473 si_watchdog_tick = drv_usectohz((clock_t)si_watchdog_timeout * 1000000);
475 return (error);
479 * si3124 module uninitialize.
483 _fini(void)
485 int error;
487 error = mod_remove(&modlinkage);
488 if (error != 0) {
489 return (error);
492 /* Remove the resources allocated in _init(). */
493 sata_hba_fini(&modlinkage);
494 mutex_destroy(&si_log_mutex);
495 ddi_soft_state_fini(&si_statep);
497 return (error);
501 * _info entry point
505 _info(struct modinfo *modinfop)
507 return (mod_info(&modlinkage, modinfop));
512 * The attach entry point for dev_ops.
514 * We initialize the controller, initialize the soft state, register
515 * the interrupt handlers and then register ourselves with sata framework.
517 static int
518 si_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
520 si_ctl_state_t *si_ctlp;
521 int instance;
522 int status;
523 int attach_state;
524 int intr_types;
525 sata_device_t sdevice;
527 SIDBG(SIDBG_ENTRY, "si_attach enter", NULL);
528 instance = ddi_get_instance(dip);
529 attach_state = ATTACH_PROGRESS_NONE;
531 switch (cmd) {
533 case DDI_ATTACH:
535 /* Allocate si_softc. */
536 status = ddi_soft_state_zalloc(si_statep, instance);
537 if (status != DDI_SUCCESS) {
538 goto err_out;
541 si_ctlp = ddi_get_soft_state(si_statep, instance);
542 si_ctlp->sictl_devinfop = dip;
544 attach_state |= ATTACH_PROGRESS_STATEP_ALLOC;
546 /* Initialize FMA */
547 si_ctlp->fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, dip,
548 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable",
549 DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
550 DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
552 si_fm_init(si_ctlp);
554 attach_state |= ATTACH_PROGRESS_INIT_FMA;
556 /* Configure pci config space handle. */
557 status = pci_config_setup(dip, &si_ctlp->sictl_pci_conf_handle);
558 if (status != DDI_SUCCESS) {
559 goto err_out;
562 si_ctlp->sictl_devid =
563 pci_config_get16(si_ctlp->sictl_pci_conf_handle,
564 PCI_CONF_DEVID);
565 switch (si_ctlp->sictl_devid) {
566 case SI3124_DEV_ID:
567 si_ctlp->sictl_num_ports = SI3124_MAX_PORTS;
568 break;
570 case SI3132_DEV_ID:
571 si_ctlp->sictl_num_ports = SI3132_MAX_PORTS;
572 break;
574 case SI3531_DEV_ID:
575 si_ctlp->sictl_num_ports = SI3531_MAX_PORTS;
576 break;
578 default:
580 * Driver should not have attatched if device
581 * ID is not already known and is supported.
583 goto err_out;
586 attach_state |= ATTACH_PROGRESS_CONF_HANDLE;
588 /* Now map the bar0; the bar0 contains the global registers. */
589 status = ddi_regs_map_setup(dip,
590 PCI_BAR0,
591 (caddr_t *)&si_ctlp->sictl_global_addr,
594 &accattr,
595 &si_ctlp->sictl_global_acc_handle);
596 if (status != DDI_SUCCESS) {
597 goto err_out;
600 attach_state |= ATTACH_PROGRESS_BAR0_MAP;
602 /* Now map bar1; the bar1 contains the port registers. */
603 status = ddi_regs_map_setup(dip,
604 PCI_BAR1,
605 (caddr_t *)&si_ctlp->sictl_port_addr,
608 &accattr,
609 &si_ctlp->sictl_port_acc_handle);
610 if (status != DDI_SUCCESS) {
611 goto err_out;
614 attach_state |= ATTACH_PROGRESS_BAR1_MAP;
617 * Disable all the interrupts before adding interrupt
618 * handler(s). The interrupts shall be re-enabled selectively
619 * out of si_init_port().
621 si_disable_all_interrupts(si_ctlp);
623 /* Get supported interrupt types. */
624 if (ddi_intr_get_supported_types(dip, &intr_types)
625 != DDI_SUCCESS) {
626 SIDBG_C(SIDBG_INIT, si_ctlp,
627 "ddi_intr_get_supported_types failed", NULL);
628 goto err_out;
631 SIDBG_C(SIDBG_INIT, si_ctlp,
632 "ddi_intr_get_supported_types() returned: 0x%x",
633 intr_types);
635 if (is_msi_supported && (intr_types & DDI_INTR_TYPE_MSI)) {
636 SIDBG_C(SIDBG_INIT, si_ctlp,
637 "Using MSI interrupt type", NULL);
640 * Try MSI first, but fall back to legacy if MSI
641 * attach fails.
643 if (si_add_msi_intrs(si_ctlp) == DDI_SUCCESS) {
644 si_ctlp->sictl_intr_type = DDI_INTR_TYPE_MSI;
645 attach_state |= ATTACH_PROGRESS_INTR_ADDED;
646 SIDBG_C(SIDBG_INIT, si_ctlp,
647 "MSI interrupt setup done", NULL);
648 } else {
649 SIDBG_C(SIDBG_INIT, si_ctlp,
650 "MSI registration failed "
651 "will try Legacy interrupts", NULL);
655 if (!(attach_state & ATTACH_PROGRESS_INTR_ADDED) &&
656 (intr_types & DDI_INTR_TYPE_FIXED)) {
658 * Either the MSI interrupt setup has failed or only
659 * fixed interrupts are available on the system.
661 SIDBG_C(SIDBG_INIT, si_ctlp,
662 "Using Legacy interrupt type", NULL);
664 if (si_add_legacy_intrs(si_ctlp) == DDI_SUCCESS) {
665 si_ctlp->sictl_intr_type = DDI_INTR_TYPE_FIXED;
666 attach_state |= ATTACH_PROGRESS_INTR_ADDED;
667 SIDBG_C(SIDBG_INIT, si_ctlp,
668 "Legacy interrupt setup done", NULL);
669 } else {
670 SIDBG_C(SIDBG_INIT, si_ctlp,
671 "legacy interrupt setup failed", NULL);
672 goto err_out;
676 if (!(attach_state & ATTACH_PROGRESS_INTR_ADDED)) {
677 SIDBG_C(SIDBG_INIT, si_ctlp,
678 "si3124: No interrupts registered", NULL);
679 goto err_out;
683 /* Initialize the mutex. */
684 mutex_init(&si_ctlp->sictl_mutex, NULL, MUTEX_DRIVER,
685 (void *)(uintptr_t)si_ctlp->sictl_intr_pri);
687 attach_state |= ATTACH_PROGRESS_MUTEX_INIT;
690 * Initialize the controller and driver core.
692 si_ctlp->sictl_flags |= SI_ATTACH;
693 status = si_initialize_controller(si_ctlp);
694 si_ctlp->sictl_flags &= ~SI_ATTACH;
695 if (status) {
696 goto err_out;
699 attach_state |= ATTACH_PROGRESS_HW_INIT;
701 if (si_register_sata_hba_tran(si_ctlp)) {
702 SIDBG_C(SIDBG_INIT, si_ctlp,
703 "si3124: setting sata hba tran failed", NULL);
704 goto err_out;
707 si_ctlp->sictl_timeout_id = timeout(
708 (void (*)(void *))si_watchdog_handler,
709 (caddr_t)si_ctlp, si_watchdog_tick);
711 si_ctlp->sictl_power_level = PM_LEVEL_D0;
713 return (DDI_SUCCESS);
715 case DDI_RESUME:
716 si_ctlp = ddi_get_soft_state(si_statep, instance);
718 status = si_initialize_controller(si_ctlp);
719 if (status) {
720 return (DDI_FAILURE);
723 si_ctlp->sictl_timeout_id = timeout(
724 (void (*)(void *))si_watchdog_handler,
725 (caddr_t)si_ctlp, si_watchdog_tick);
727 (void) pm_power_has_changed(dip, 0, PM_LEVEL_D0);
729 /* Notify SATA framework about RESUME. */
730 if (sata_hba_attach(si_ctlp->sictl_devinfop,
731 si_ctlp->sictl_sata_hba_tran,
732 DDI_RESUME) != DDI_SUCCESS) {
733 return (DDI_FAILURE);
737 * Notify the "framework" that it should reprobe ports to see
738 * if any device got changed while suspended.
740 bzero((void *)&sdevice, sizeof (sata_device_t));
741 sata_hba_event_notify(dip, &sdevice,
742 SATA_EVNT_PWR_LEVEL_CHANGED);
743 SIDBG_C(SIDBG_INIT|SIDBG_EVENT, si_ctlp,
744 "sending event up: SATA_EVNT_PWR_LEVEL_CHANGED", NULL);
746 (void) pm_idle_component(si_ctlp->sictl_devinfop, 0);
748 si_ctlp->sictl_power_level = PM_LEVEL_D0;
750 return (DDI_SUCCESS);
752 default:
753 return (DDI_FAILURE);
757 err_out:
758 if (attach_state & ATTACH_PROGRESS_HW_INIT) {
759 si_ctlp->sictl_flags |= SI_DETACH;
760 /* We want to set SI_DETACH to deallocate all memory */
761 si_deinitialize_controller(si_ctlp);
762 si_ctlp->sictl_flags &= ~SI_DETACH;
765 if (attach_state & ATTACH_PROGRESS_MUTEX_INIT) {
766 mutex_destroy(&si_ctlp->sictl_mutex);
769 if (attach_state & ATTACH_PROGRESS_INTR_ADDED) {
770 si_rem_intrs(si_ctlp);
773 if (attach_state & ATTACH_PROGRESS_BAR1_MAP) {
774 ddi_regs_map_free(&si_ctlp->sictl_port_acc_handle);
777 if (attach_state & ATTACH_PROGRESS_BAR0_MAP) {
778 ddi_regs_map_free(&si_ctlp->sictl_global_acc_handle);
781 if (attach_state & ATTACH_PROGRESS_CONF_HANDLE) {
782 pci_config_teardown(&si_ctlp->sictl_pci_conf_handle);
785 if (attach_state & ATTACH_PROGRESS_INIT_FMA) {
786 si_fm_fini(si_ctlp);
789 if (attach_state & ATTACH_PROGRESS_STATEP_ALLOC) {
790 ddi_soft_state_free(si_statep, instance);
793 return (DDI_FAILURE);
798 * The detach entry point for dev_ops.
800 * We undo the things we did in si_attach().
802 static int
803 si_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
805 si_ctl_state_t *si_ctlp;
806 int instance;
808 SIDBG(SIDBG_ENTRY, "si_detach enter", NULL);
809 instance = ddi_get_instance(dip);
810 si_ctlp = ddi_get_soft_state(si_statep, instance);
812 switch (cmd) {
814 case DDI_DETACH:
816 mutex_enter(&si_ctlp->sictl_mutex);
818 /* disable the interrupts for an uninterrupted detach */
819 si_disable_all_interrupts(si_ctlp);
821 mutex_exit(&si_ctlp->sictl_mutex);
822 /* unregister from the sata framework. */
823 if (si_unregister_sata_hba_tran(si_ctlp) != SI_SUCCESS) {
824 si_enable_all_interrupts(si_ctlp);
825 return (DDI_FAILURE);
827 mutex_enter(&si_ctlp->sictl_mutex);
829 /* now cancel the timeout handler. */
830 si_ctlp->sictl_flags |= SI_NO_TIMEOUTS;
831 (void) untimeout(si_ctlp->sictl_timeout_id);
832 si_ctlp->sictl_flags &= ~SI_NO_TIMEOUTS;
834 /* de-initialize the controller. */
835 si_ctlp->sictl_flags |= SI_DETACH;
836 si_deinitialize_controller(si_ctlp);
837 si_ctlp->sictl_flags &= ~SI_DETACH;
839 /* destroy any mutexes */
840 mutex_exit(&si_ctlp->sictl_mutex);
841 mutex_destroy(&si_ctlp->sictl_mutex);
843 /* remove the interrupts */
844 si_rem_intrs(si_ctlp);
846 /* remove the reg maps. */
847 ddi_regs_map_free(&si_ctlp->sictl_port_acc_handle);
848 ddi_regs_map_free(&si_ctlp->sictl_global_acc_handle);
849 pci_config_teardown(&si_ctlp->sictl_pci_conf_handle);
851 /* deinit FMA */
852 si_fm_fini(si_ctlp);
854 /* free the soft state. */
855 ddi_soft_state_free(si_statep, instance);
857 return (DDI_SUCCESS);
859 case DDI_SUSPEND:
860 /* Inform SATA framework */
861 if (sata_hba_detach(dip, cmd) != DDI_SUCCESS) {
862 return (DDI_FAILURE);
865 mutex_enter(&si_ctlp->sictl_mutex);
868 * Device needs to be at full power in case it is needed to
869 * handle dump(9e) to save CPR state after DDI_SUSPEND
870 * completes. This is OK since presumably power will be
871 * removed anyways. No outstanding transactions should be
872 * on the controller since the children are already quiesced.
874 * If any ioctls/cfgadm support is added that touches
875 * hardware, those entry points will need to check for
876 * suspend and then block or return errors until resume.
879 if (pm_busy_component(si_ctlp->sictl_devinfop, 0) ==
880 DDI_SUCCESS) {
881 mutex_exit(&si_ctlp->sictl_mutex);
882 (void) pm_raise_power(si_ctlp->sictl_devinfop, 0,
883 PM_LEVEL_D0);
884 mutex_enter(&si_ctlp->sictl_mutex);
887 si_deinitialize_controller(si_ctlp);
889 si_ctlp->sictl_flags |= SI_NO_TIMEOUTS;
890 (void) untimeout(si_ctlp->sictl_timeout_id);
891 si_ctlp->sictl_flags &= ~SI_NO_TIMEOUTS;
893 SIDBG_C(SIDBG_POWER, si_ctlp, "si3124%d: DDI_SUSPEND",
894 instance);
896 mutex_exit(&si_ctlp->sictl_mutex);
898 return (DDI_SUCCESS);
900 default:
901 return (DDI_FAILURE);
907 static int
908 si_power(dev_info_t *dip, int component, int level)
910 #ifndef __lock_lint
911 _NOTE(ARGUNUSED(component))
912 #endif /* __lock_lint */
914 si_ctl_state_t *si_ctlp;
915 int instance = ddi_get_instance(dip);
916 int rval = DDI_SUCCESS;
917 int old_level;
918 sata_device_t sdevice;
920 si_ctlp = ddi_get_soft_state(si_statep, instance);
922 if (si_ctlp == NULL) {
923 return (DDI_FAILURE);
926 SIDBG_C(SIDBG_ENTRY, si_ctlp, "si_power enter", NULL);
928 mutex_enter(&si_ctlp->sictl_mutex);
929 old_level = si_ctlp->sictl_power_level;
931 switch (level) {
932 case PM_LEVEL_D0: /* fully on */
933 pci_config_put16(si_ctlp->sictl_pci_conf_handle,
934 PM_CSR(si_ctlp->sictl_devid), PCI_PMCSR_D0);
935 #ifndef __lock_lint
936 delay(drv_usectohz(10000));
937 #endif /* __lock_lint */
938 si_ctlp->sictl_power_level = PM_LEVEL_D0;
939 (void) pci_restore_config_regs(si_ctlp->sictl_devinfop);
941 SIDBG_C(SIDBG_POWER, si_ctlp,
942 "si3124%d: turning power ON. old level %d",
943 instance, old_level);
945 * If called from attach, just raise device power,
946 * restore config registers (if they were saved
947 * from a previous detach that lowered power),
948 * and exit.
950 if (si_ctlp->sictl_flags & SI_ATTACH)
951 break;
953 mutex_exit(&si_ctlp->sictl_mutex);
954 (void) si_initialize_controller(si_ctlp);
955 mutex_enter(&si_ctlp->sictl_mutex);
957 si_ctlp->sictl_timeout_id = timeout(
958 (void (*)(void *))si_watchdog_handler,
959 (caddr_t)si_ctlp, si_watchdog_tick);
961 bzero((void *)&sdevice, sizeof (sata_device_t));
962 sata_hba_event_notify(
963 si_ctlp->sictl_sata_hba_tran->sata_tran_hba_dip,
964 &sdevice, SATA_EVNT_PWR_LEVEL_CHANGED);
965 SIDBG_C(SIDBG_EVENT|SIDBG_POWER, si_ctlp,
966 "sending event up: PWR_LEVEL_CHANGED", NULL);
968 break;
970 case PM_LEVEL_D3: /* fully off */
971 if (!(si_ctlp->sictl_flags & SI_DETACH)) {
972 si_ctlp->sictl_flags |= SI_NO_TIMEOUTS;
973 (void) untimeout(si_ctlp->sictl_timeout_id);
974 si_ctlp->sictl_flags &= ~SI_NO_TIMEOUTS;
976 si_deinitialize_controller(si_ctlp);
978 si_ctlp->sictl_power_level = PM_LEVEL_D3;
981 (void) pci_save_config_regs(si_ctlp->sictl_devinfop);
983 pci_config_put16(si_ctlp->sictl_pci_conf_handle,
984 PM_CSR(si_ctlp->sictl_devid), PCI_PMCSR_D3HOT);
986 SIDBG_C(SIDBG_POWER, si_ctlp, "si3124%d: turning power OFF. "
987 "old level %d", instance, old_level);
989 break;
991 default:
992 SIDBG_C(SIDBG_POWER, si_ctlp, "si3124%d: turning power OFF. "
993 "old level %d", instance, old_level);
994 rval = DDI_FAILURE;
995 break;
998 mutex_exit(&si_ctlp->sictl_mutex);
1000 return (rval);
1005 * The info entry point for dev_ops.
1008 static int
1009 si_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd,
1010 void *arg,
1011 void **result)
1013 #ifndef __lock_lint
1014 _NOTE(ARGUNUSED(dip))
1015 #endif /* __lock_lint */
1016 si_ctl_state_t *si_ctlp;
1017 int instance;
1018 dev_t dev;
1020 dev = (dev_t)arg;
1021 instance = getminor(dev);
1023 switch (infocmd) {
1024 case DDI_INFO_DEVT2DEVINFO:
1025 si_ctlp = ddi_get_soft_state(si_statep, instance);
1026 if (si_ctlp != NULL) {
1027 *result = si_ctlp->sictl_devinfop;
1028 return (DDI_SUCCESS);
1029 } else {
1030 *result = NULL;
1031 return (DDI_FAILURE);
1033 case DDI_INFO_DEVT2INSTANCE:
1034 *(int *)result = instance;
1035 break;
1036 default:
1037 break;
1039 return (DDI_SUCCESS);
1045 * Registers the si3124 with sata framework.
1047 static int
1048 si_register_sata_hba_tran(si_ctl_state_t *si_ctlp)
1050 struct sata_hba_tran *sata_hba_tran;
1052 SIDBG_C(SIDBG_ENTRY, si_ctlp,
1053 "si_register_sata_hba_tran entry", NULL);
1055 mutex_enter(&si_ctlp->sictl_mutex);
1057 /* Allocate memory for the sata_hba_tran */
1058 sata_hba_tran = kmem_zalloc(sizeof (sata_hba_tran_t), KM_SLEEP);
1060 sata_hba_tran->sata_tran_hba_rev = SATA_TRAN_HBA_REV;
1061 sata_hba_tran->sata_tran_hba_dip = si_ctlp->sictl_devinfop;
1063 if (si_dma_sg_number > SI_MAX_SGT_TABLES_PER_PRB) {
1064 si_dma_sg_number = SI_MAX_SGT_TABLES_PER_PRB;
1065 } else if (si_dma_sg_number < SI_MIN_SGT_TABLES_PER_PRB) {
1066 si_dma_sg_number = SI_MIN_SGT_TABLES_PER_PRB;
1069 if (si_dma_sg_number != SI_DEFAULT_SGT_TABLES_PER_PRB) {
1070 buffer_dma_attr.dma_attr_sgllen = SGE_LENGTH(si_dma_sg_number);
1072 sata_hba_tran->sata_tran_hba_dma_attr = &buffer_dma_attr;
1074 sata_hba_tran->sata_tran_hba_num_cports = si_ctlp->sictl_num_ports;
1075 sata_hba_tran->sata_tran_hba_features_support = 0;
1076 sata_hba_tran->sata_tran_hba_qdepth = SI_NUM_SLOTS;
1078 sata_hba_tran->sata_tran_probe_port = si_tran_probe_port;
1079 sata_hba_tran->sata_tran_start = si_tran_start;
1080 sata_hba_tran->sata_tran_abort = si_tran_abort;
1081 sata_hba_tran->sata_tran_reset_dport = si_tran_reset_dport;
1082 sata_hba_tran->sata_tran_selftest = NULL;
1083 sata_hba_tran->sata_tran_hotplug_ops = &si_tran_hotplug_ops;
1084 sata_hba_tran->sata_tran_pwrmgt_ops = NULL;
1085 sata_hba_tran->sata_tran_ioctl = NULL;
1086 mutex_exit(&si_ctlp->sictl_mutex);
1088 /* Attach it to SATA framework */
1089 if (sata_hba_attach(si_ctlp->sictl_devinfop, sata_hba_tran, DDI_ATTACH)
1090 != DDI_SUCCESS) {
1091 kmem_free((void *)sata_hba_tran, sizeof (sata_hba_tran_t));
1092 return (SI_FAILURE);
1095 mutex_enter(&si_ctlp->sictl_mutex);
1096 si_ctlp->sictl_sata_hba_tran = sata_hba_tran;
1097 mutex_exit(&si_ctlp->sictl_mutex);
1099 return (SI_SUCCESS);
1104 * Unregisters the si3124 with sata framework.
1106 static int
1107 si_unregister_sata_hba_tran(si_ctl_state_t *si_ctlp)
1110 /* Detach from the SATA framework. */
1111 if (sata_hba_detach(si_ctlp->sictl_devinfop, DDI_DETACH) !=
1112 DDI_SUCCESS) {
1113 return (SI_FAILURE);
1116 /* Deallocate sata_hba_tran. */
1117 kmem_free((void *)si_ctlp->sictl_sata_hba_tran,
1118 sizeof (sata_hba_tran_t));
1120 si_ctlp->sictl_sata_hba_tran = NULL;
1122 return (SI_SUCCESS);
1126 * Called by sata framework to probe a port. We return the
1127 * cached information from a previous hardware probe.
1129 * The actual hardware probing itself was done either from within
1130 * si_initialize_controller() during the driver attach or
1131 * from a phy ready change interrupt handler.
1133 static int
1134 si_tran_probe_port(dev_info_t *dip, sata_device_t *sd)
1137 si_ctl_state_t *si_ctlp;
1138 uint8_t cport = sd->satadev_addr.cport;
1139 uint8_t pmport = sd->satadev_addr.pmport;
1140 uint8_t qual = sd->satadev_addr.qual;
1141 uint8_t port_type;
1142 si_port_state_t *si_portp;
1143 si_portmult_state_t *si_portmultp;
1145 si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
1147 SIDBG_C(SIDBG_ENTRY, si_ctlp,
1148 "si_tran_probe_port: cport: 0x%x, pmport: 0x%x, qual: 0x%x",
1149 cport, pmport, qual);
1151 if (cport >= SI_MAX_PORTS) {
1152 sd->satadev_type = SATA_DTYPE_NONE;
1153 sd->satadev_state = SATA_STATE_UNKNOWN; /* invalid port */
1154 return (SATA_FAILURE);
1157 mutex_enter(&si_ctlp->sictl_mutex);
1158 si_portp = si_ctlp->sictl_ports[cport];
1159 mutex_exit(&si_ctlp->sictl_mutex);
1160 if (si_portp == NULL) {
1161 sd->satadev_type = SATA_DTYPE_NONE;
1162 sd->satadev_state = SATA_STATE_UNKNOWN;
1163 return (SATA_FAILURE);
1166 mutex_enter(&si_portp->siport_mutex);
1168 if (qual == SATA_ADDR_PMPORT) {
1169 if (pmport >= si_portp->siport_portmult_state.sipm_num_ports) {
1170 sd->satadev_type = SATA_DTYPE_NONE;
1171 sd->satadev_state = SATA_STATE_UNKNOWN;
1172 mutex_exit(&si_portp->siport_mutex);
1173 return (SATA_FAILURE);
1174 } else {
1175 si_portmultp = &si_portp->siport_portmult_state;
1176 port_type = si_portmultp->sipm_port_type[pmport];
1178 } else {
1179 port_type = si_portp->siport_port_type;
1182 switch (port_type) {
1184 case PORT_TYPE_DISK:
1185 sd->satadev_type = SATA_DTYPE_ATADISK;
1186 break;
1188 case PORT_TYPE_ATAPI:
1189 sd->satadev_type = SATA_DTYPE_ATAPICD;
1190 break;
1192 case PORT_TYPE_MULTIPLIER:
1193 sd->satadev_type = SATA_DTYPE_PMULT;
1194 sd->satadev_add_info =
1195 si_portp->siport_portmult_state.sipm_num_ports;
1196 break;
1198 case PORT_TYPE_UNKNOWN:
1199 sd->satadev_type = SATA_DTYPE_UNKNOWN;
1200 break;
1202 default:
1203 /* we don't support any other device types. */
1204 sd->satadev_type = SATA_DTYPE_NONE;
1205 break;
1207 sd->satadev_state = SATA_STATE_READY;
1209 if (qual == SATA_ADDR_PMPORT) {
1210 (void) si_read_portmult_reg(si_ctlp, si_portp, cport,
1211 pmport, PSCR_REG0, &sd->satadev_scr.sstatus);
1212 (void) si_read_portmult_reg(si_ctlp, si_portp, cport,
1213 pmport, PSCR_REG1, &sd->satadev_scr.serror);
1214 (void) si_read_portmult_reg(si_ctlp, si_portp, cport,
1215 pmport, PSCR_REG2, &sd->satadev_scr.scontrol);
1216 (void) si_read_portmult_reg(si_ctlp, si_portp, cport,
1217 pmport, PSCR_REG3, &sd->satadev_scr.sactive);
1218 } else {
1219 fill_dev_sregisters(si_ctlp, cport, sd);
1220 if (!(si_portp->siport_active)) {
1222 * Since we are implementing the port deactivation
1223 * in software only, we need to fake a valid value
1224 * for sstatus when the device is in deactivated state.
1226 SSTATUS_SET_DET(sd->satadev_scr.sstatus,
1227 SSTATUS_DET_PHYOFFLINE);
1228 SSTATUS_SET_IPM(sd->satadev_scr.sstatus,
1229 SSTATUS_IPM_NODEV_NOPHY);
1230 sd->satadev_state = SATA_PSTATE_SHUTDOWN;
1234 mutex_exit(&si_portp->siport_mutex);
1235 return (SATA_SUCCESS);
1239 * Called by sata framework to transport a sata packet down stream.
1241 * The actual work of building the FIS & transporting it to the hardware
1242 * is done out of the subroutine si_deliver_satapkt().
1244 static int
1245 si_tran_start(dev_info_t *dip, sata_pkt_t *spkt)
1247 si_ctl_state_t *si_ctlp;
1248 uint8_t cport;
1249 si_port_state_t *si_portp;
1250 int slot;
1252 cport = spkt->satapkt_device.satadev_addr.cport;
1253 si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
1254 mutex_enter(&si_ctlp->sictl_mutex);
1255 si_portp = si_ctlp->sictl_ports[cport];
1256 mutex_exit(&si_ctlp->sictl_mutex);
1258 SIDBG_P(SIDBG_ENTRY, si_portp,
1259 "si_tran_start entry", NULL);
1261 mutex_enter(&si_portp->siport_mutex);
1263 if ((si_portp->siport_port_type == PORT_TYPE_NODEV) ||
1264 !si_portp->siport_active) {
1266 * si_intr_phy_ready_change() may have rendered it to
1267 * PORT_TYPE_NODEV. cfgadm operation may have rendered
1268 * it inactive.
1270 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1271 fill_dev_sregisters(si_ctlp, cport, &spkt->satapkt_device);
1272 mutex_exit(&si_portp->siport_mutex);
1273 return (SATA_TRAN_PORT_ERROR);
1276 if (spkt->satapkt_cmd.satacmd_flags.sata_clear_dev_reset) {
1277 si_portp->siport_reset_in_progress = 0;
1278 SIDBG_P(SIDBG_RESET, si_portp,
1279 "si_tran_start clearing the "
1280 "reset_in_progress for port", NULL);
1283 if (si_portp->siport_reset_in_progress &&
1284 ! spkt->satapkt_cmd.satacmd_flags.sata_ignore_dev_reset &&
1285 ! ddi_in_panic()) {
1287 spkt->satapkt_reason = SATA_PKT_BUSY;
1288 SIDBG_P(SIDBG_RESET, si_portp,
1289 "si_tran_start returning BUSY while "
1290 "reset in progress for port", NULL);
1291 mutex_exit(&si_portp->siport_mutex);
1292 return (SATA_TRAN_BUSY);
1295 if (si_portp->mopping_in_progress > 0) {
1296 spkt->satapkt_reason = SATA_PKT_BUSY;
1297 SIDBG_P(SIDBG_RESET, si_portp,
1298 "si_tran_start returning BUSY while "
1299 "mopping in progress for port", NULL);
1300 mutex_exit(&si_portp->siport_mutex);
1301 return (SATA_TRAN_BUSY);
1304 if ((slot = si_deliver_satapkt(si_ctlp, si_portp, cport, spkt))
1305 == SI_FAILURE) {
1306 spkt->satapkt_reason = SATA_PKT_QUEUE_FULL;
1307 SIDBG_P(SIDBG_ERRS, si_portp,
1308 "si_tran_start returning QUEUE_FULL",
1309 NULL);
1310 mutex_exit(&si_portp->siport_mutex);
1311 return (SATA_TRAN_QUEUE_FULL);
1314 if (spkt->satapkt_op_mode & (SATA_OPMODE_POLLING|SATA_OPMODE_SYNCH)) {
1315 /* we need to poll now */
1316 si_poll_cmd(si_ctlp, si_portp, cport, slot, spkt);
1318 * The command has completed, and spkt will be freed by the
1319 * sata module, so don't keep a pointer to it lying around.
1321 si_portp->siport_slot_pkts[slot] = NULL;
1324 mutex_exit(&si_portp->siport_mutex);
1325 return (SATA_TRAN_ACCEPTED);
1328 #define SENDUP_PACKET(si_portp, satapkt, reason) \
1329 if (satapkt) { \
1330 if ((satapkt->satapkt_cmd.satacmd_cmd_reg == \
1331 SATAC_WRITE_FPDMA_QUEUED) || \
1332 (satapkt->satapkt_cmd.satacmd_cmd_reg == \
1333 SATAC_READ_FPDMA_QUEUED)) { \
1334 si_portp->siport_pending_ncq_count--; \
1336 satapkt->satapkt_reason = reason; \
1337 /* \
1338 * We set the satapkt_reason in both synch and \
1339 * non-synch cases. \
1340 */ \
1341 if (!(satapkt->satapkt_op_mode & SATA_OPMODE_SYNCH) && \
1342 satapkt->satapkt_comp) { \
1343 mutex_exit(&si_portp->siport_mutex); \
1344 (*satapkt->satapkt_comp)(satapkt); \
1345 mutex_enter(&si_portp->siport_mutex); \
1350 * Mopping is necessitated because of the si3124 hardware limitation.
1351 * The only way to recover from errors or to abort a command is to
1352 * reset the port/device but such a reset also results in throwing
1353 * away all the unfinished pending commands.
1355 * A port or device is reset in four scenarios:
1356 * a) some commands failed with errors
1357 * b) or we need to timeout some commands
1358 * c) or we need to abort some commands
1359 * d) or we need reset the port at the request of sata framework
1361 * In all these scenarios, we need to send any pending unfinished
1362 * commands up to sata framework.
1364 * WARNING!!! siport_mutex should be acquired before the function is called.
1366 static void
1367 si_mop_commands(si_ctl_state_t *si_ctlp,
1368 si_port_state_t *si_portp,
1369 uint8_t port,
1371 uint32_t slot_status,
1372 uint32_t failed_tags,
1373 uint32_t timedout_tags,
1374 uint32_t aborting_tags,
1375 uint32_t reset_tags)
1377 uint32_t finished_tags, unfinished_tags;
1378 int tmpslot;
1379 sata_pkt_t *satapkt;
1380 struct sata_cmd_flags *flagsp;
1382 SIDBG_P(SIDBG_ERRS, si_portp,
1383 "si_mop_commands entered: slot_status: 0x%x",
1384 slot_status);
1386 SIDBG_P(SIDBG_ERRS, si_portp,
1387 "si_mop_commands: failed_tags: 0x%x, timedout_tags: 0x%x"
1388 "aborting_tags: 0x%x, reset_tags: 0x%x",
1389 failed_tags,
1390 timedout_tags,
1391 aborting_tags,
1392 reset_tags);
1395 * We could be here for four reasons: abort, reset,
1396 * timeout or error handling. Only one such mopping
1397 * is allowed at a time.
1400 finished_tags = si_portp->siport_pending_tags &
1401 ~slot_status & SI_SLOT_MASK;
1403 unfinished_tags = slot_status & SI_SLOT_MASK &
1404 ~failed_tags &
1405 ~aborting_tags &
1406 ~reset_tags &
1407 ~timedout_tags;
1409 /* Send up the finished_tags with SATA_PKT_COMPLETED. */
1410 while (finished_tags) {
1411 tmpslot = ddi_ffs(finished_tags) - 1;
1412 if (tmpslot == -1) {
1413 break;
1416 satapkt = si_portp->siport_slot_pkts[tmpslot];
1418 if (satapkt != NULL &&
1419 satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
1420 si_copy_out_regs(&satapkt->satapkt_cmd, si_ctlp,
1421 port, tmpslot);
1424 SIDBG_P(SIDBG_ERRS, si_portp,
1425 "si_mop_commands sending up completed satapkt: %x",
1426 satapkt);
1428 CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
1429 CLEAR_BIT(finished_tags, tmpslot);
1430 SENDUP_PACKET(si_portp, satapkt, SATA_PKT_COMPLETED);
1433 ASSERT(finished_tags == 0);
1435 /* Send up failed_tags with SATA_PKT_DEV_ERROR. */
1436 while (failed_tags) {
1437 tmpslot = ddi_ffs(failed_tags) - 1;
1438 if (tmpslot == -1) {
1439 break;
1441 SIDBG_P(SIDBG_ERRS, si_portp, "si3124: si_mop_commands: "
1442 "handling failed slot: 0x%x", tmpslot);
1444 satapkt = si_portp->siport_slot_pkts[tmpslot];
1446 if (satapkt != NULL) {
1448 if (satapkt->satapkt_device.satadev_type ==
1449 SATA_DTYPE_ATAPICD) {
1450 si_set_sense_data(satapkt, SATA_PKT_DEV_ERROR);
1454 flagsp = &satapkt->satapkt_cmd.satacmd_flags;
1456 flagsp->sata_copy_out_lba_low_msb = B_TRUE;
1457 flagsp->sata_copy_out_lba_mid_msb = B_TRUE;
1458 flagsp->sata_copy_out_lba_high_msb = B_TRUE;
1459 flagsp->sata_copy_out_lba_low_lsb = B_TRUE;
1460 flagsp->sata_copy_out_lba_mid_lsb = B_TRUE;
1461 flagsp->sata_copy_out_lba_high_lsb = B_TRUE;
1462 flagsp->sata_copy_out_error_reg = B_TRUE;
1463 flagsp->sata_copy_out_sec_count_msb = B_TRUE;
1464 flagsp->sata_copy_out_sec_count_lsb = B_TRUE;
1465 flagsp->sata_copy_out_device_reg = B_TRUE;
1467 si_copy_out_regs(&satapkt->satapkt_cmd, si_ctlp,
1468 port, tmpslot);
1471 * In the case of NCQ command failures, the error is
1472 * overwritten by the one obtained from issuing of a
1473 * READ LOG EXTENDED command.
1475 if (si_portp->siport_err_tags_SDBERROR &
1476 (1 << tmpslot)) {
1477 satapkt->satapkt_cmd.satacmd_error_reg =
1478 si_read_log_ext(si_ctlp, si_portp, port);
1482 CLEAR_BIT(failed_tags, tmpslot);
1483 CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
1484 SENDUP_PACKET(si_portp, satapkt, SATA_PKT_DEV_ERROR);
1487 ASSERT(failed_tags == 0);
1489 /* Send up timedout_tags with SATA_PKT_TIMEOUT. */
1490 while (timedout_tags) {
1491 tmpslot = ddi_ffs(timedout_tags) - 1;
1492 if (tmpslot == -1) {
1493 break;
1496 satapkt = si_portp->siport_slot_pkts[tmpslot];
1497 SIDBG_P(SIDBG_ERRS, si_portp,
1498 "si_mop_commands sending "
1499 "spkt up with PKT_TIMEOUT: %x",
1500 satapkt);
1502 CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
1503 CLEAR_BIT(timedout_tags, tmpslot);
1504 SENDUP_PACKET(si_portp, satapkt, SATA_PKT_TIMEOUT);
1507 ASSERT(timedout_tags == 0);
1509 /* Send up aborting packets with SATA_PKT_ABORTED. */
1510 while (aborting_tags) {
1511 tmpslot = ddi_ffs(aborting_tags) - 1;
1512 if (tmpslot == -1) {
1513 break;
1516 satapkt = si_portp->siport_slot_pkts[tmpslot];
1517 SIDBG_P(SIDBG_ERRS, si_portp,
1518 "si_mop_commands aborting spkt: %x",
1519 satapkt);
1520 if (satapkt != NULL && satapkt->satapkt_device.satadev_type ==
1521 SATA_DTYPE_ATAPICD) {
1522 si_set_sense_data(satapkt, SATA_PKT_ABORTED);
1525 CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
1526 CLEAR_BIT(aborting_tags, tmpslot);
1527 SENDUP_PACKET(si_portp, satapkt, SATA_PKT_ABORTED);
1531 ASSERT(aborting_tags == 0);
1533 /* Reset tags are sent up to framework with SATA_PKT_RESET. */
1534 while (reset_tags) {
1535 tmpslot = ddi_ffs(reset_tags) - 1;
1536 if (tmpslot == -1) {
1537 break;
1539 satapkt = si_portp->siport_slot_pkts[tmpslot];
1540 SIDBG_P(SIDBG_ERRS, si_portp,
1541 "si_mop_commands sending PKT_RESET for "
1542 "reset spkt: %x",
1543 satapkt);
1545 CLEAR_BIT(reset_tags, tmpslot);
1546 CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
1547 SENDUP_PACKET(si_portp, satapkt, SATA_PKT_RESET);
1550 ASSERT(reset_tags == 0);
1552 /* Send up the unfinished_tags with SATA_PKT_RESET. */
1553 while (unfinished_tags) {
1554 tmpslot = ddi_ffs(unfinished_tags) - 1;
1555 if (tmpslot == -1) {
1556 break;
1558 satapkt = si_portp->siport_slot_pkts[tmpslot];
1559 SIDBG_P(SIDBG_ERRS, si_portp,
1560 "si_mop_commands sending SATA_PKT_RESET for "
1561 "retry spkt: %x",
1562 satapkt);
1564 CLEAR_BIT(unfinished_tags, tmpslot);
1565 CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
1566 SENDUP_PACKET(si_portp, satapkt, SATA_PKT_RESET);
1569 ASSERT(unfinished_tags == 0);
1571 si_portp->mopping_in_progress--;
1572 ASSERT(si_portp->mopping_in_progress >= 0);
1576 * Called by the sata framework to abort the previously sent packet(s).
1578 * We reset the device and mop the commands on the port.
1580 static int
1581 si_tran_abort(dev_info_t *dip, sata_pkt_t *spkt, int flag)
1583 uint32_t slot_status;
1584 uint8_t port;
1585 int tmpslot;
1586 uint32_t aborting_tags;
1587 uint32_t finished_tags;
1588 si_port_state_t *si_portp;
1589 si_ctl_state_t *si_ctlp;
1591 port = spkt->satapkt_device.satadev_addr.cport;
1592 si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
1593 mutex_enter(&si_ctlp->sictl_mutex);
1594 si_portp = si_ctlp->sictl_ports[port];
1595 mutex_exit(&si_ctlp->sictl_mutex);
1597 SIDBG_P(SIDBG_ERRS, si_portp, "si_tran_abort on port: %x", port);
1599 mutex_enter(&si_portp->siport_mutex);
1602 * If already mopping, then no need to abort anything.
1604 if (si_portp->mopping_in_progress > 0) {
1605 SIDBG_P(SIDBG_ERRS, si_portp,
1606 "si_tran_abort: port %d mopping "
1607 "in progress, so just return", port);
1608 mutex_exit(&si_portp->siport_mutex);
1609 return (SATA_SUCCESS);
1612 if ((si_portp->siport_port_type == PORT_TYPE_NODEV) ||
1613 !si_portp->siport_active) {
1615 * si_intr_phy_ready_change() may have rendered it to
1616 * PORT_TYPE_NODEV. cfgadm operation may have rendered
1617 * it inactive.
1619 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1620 fill_dev_sregisters(si_ctlp, port, &spkt->satapkt_device);
1621 mutex_exit(&si_portp->siport_mutex);
1622 return (SATA_FAILURE);
1625 if (flag == SATA_ABORT_ALL_PACKETS) {
1626 aborting_tags = si_portp->siport_pending_tags;
1627 } else {
1629 * Need to abort a single packet.
1630 * Search our siport_slot_pkts[] list for matching spkt.
1632 aborting_tags = 0xffffffff; /* 0xffffffff is impossible tag */
1633 for (tmpslot = 0; tmpslot < SI_NUM_SLOTS; tmpslot++) {
1634 if (si_portp->siport_slot_pkts[tmpslot] == spkt) {
1635 aborting_tags = (0x1 << tmpslot);
1636 break;
1640 if (aborting_tags == 0xffffffff) {
1641 /* requested packet is not on pending list. */
1642 fill_dev_sregisters(si_ctlp, port,
1643 &spkt->satapkt_device);
1644 mutex_exit(&si_portp->siport_mutex);
1645 return (SATA_FAILURE);
1649 si_portp->mopping_in_progress++;
1651 slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
1652 (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
1653 (void) si_reset_dport_wait_till_ready(si_ctlp, si_portp,
1654 port, SI_DEVICE_RESET);
1657 * Compute which have finished and which need to be retried.
1659 * The finished tags are siport_pending_tags minus the slot_status.
1660 * The aborting_tags have to be reduced by finished_tags since we
1661 * can't possibly abort a tag which had finished already.
1663 finished_tags = si_portp->siport_pending_tags &
1664 ~slot_status & SI_SLOT_MASK;
1665 aborting_tags &= ~finished_tags;
1667 si_mop_commands(si_ctlp,
1668 si_portp,
1669 port,
1670 slot_status,
1671 0, /* failed_tags */
1672 0, /* timedout_tags */
1673 aborting_tags,
1674 0); /* reset_tags */
1676 fill_dev_sregisters(si_ctlp, port, &spkt->satapkt_device);
1677 mutex_exit(&si_portp->siport_mutex);
1678 return (SATA_SUCCESS);
1683 * Used to reject all the pending packets on a port during a reset
1684 * operation.
1686 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
1687 * before calling us.
1689 static void
1690 si_reject_all_reset_pkts(
1691 si_ctl_state_t *si_ctlp,
1692 si_port_state_t *si_portp,
1693 int port)
1695 uint32_t slot_status;
1696 uint32_t reset_tags;
1698 _NOTE(ASSUMING_PROTECTED(si_portp))
1700 SIDBG_P(SIDBG_RESET, si_portp,
1701 "si_reject_all_reset_pkts on port: %x",
1702 port);
1704 slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
1705 (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
1707 /* Compute which tags need to be sent up. */
1708 reset_tags = slot_status & SI_SLOT_MASK;
1710 si_portp->mopping_in_progress++;
1712 si_mop_commands(si_ctlp,
1713 si_portp,
1714 port,
1715 slot_status,
1716 0, /* failed_tags */
1717 0, /* timedout_tags */
1718 0, /* aborting_tags */
1719 reset_tags);
1724 * Called by sata framework to reset a port(s) or device.
1727 static int
1728 si_tran_reset_dport(dev_info_t *dip, sata_device_t *sd)
1730 si_ctl_state_t *si_ctlp;
1731 uint8_t port = sd->satadev_addr.cport;
1732 int i;
1733 si_port_state_t *si_portp;
1734 int retval = SI_SUCCESS;
1736 si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
1737 SIDBG_C(SIDBG_RESET, si_ctlp,
1738 "si_tran_reset_port entry: port: 0x%x",
1739 port);
1741 switch (sd->satadev_addr.qual) {
1742 case SATA_ADDR_CPORT:
1743 mutex_enter(&si_ctlp->sictl_mutex);
1744 si_portp = si_ctlp->sictl_ports[port];
1745 mutex_exit(&si_ctlp->sictl_mutex);
1747 mutex_enter(&si_portp->siport_mutex);
1750 * If already mopping, then no need to reset or mop again.
1752 if (si_portp->mopping_in_progress > 0) {
1753 SIDBG_P(SIDBG_RESET, si_portp,
1754 "si_tran_reset_dport: CPORT port %d mopping "
1755 "in progress, so just return", port);
1756 mutex_exit(&si_portp->siport_mutex);
1757 retval = SI_SUCCESS;
1758 break;
1761 retval = si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
1762 SI_PORT_RESET);
1763 si_reject_all_reset_pkts(si_ctlp, si_portp, port);
1764 mutex_exit(&si_portp->siport_mutex);
1766 break;
1768 case SATA_ADDR_DCPORT:
1769 mutex_enter(&si_ctlp->sictl_mutex);
1770 si_portp = si_ctlp->sictl_ports[port];
1771 mutex_exit(&si_ctlp->sictl_mutex);
1773 mutex_enter(&si_portp->siport_mutex);
1775 if ((si_portp->siport_port_type == PORT_TYPE_NODEV) ||
1776 !si_portp->siport_active) {
1777 mutex_exit(&si_portp->siport_mutex);
1778 retval = SI_FAILURE;
1779 break;
1783 * If already mopping, then no need to reset or mop again.
1785 if (si_portp->mopping_in_progress > 0) {
1786 SIDBG_P(SIDBG_RESET, si_portp,
1787 "si_tran_reset_dport: DCPORT port %d mopping "
1788 "in progress, so just return", port);
1789 mutex_exit(&si_portp->siport_mutex);
1790 retval = SI_SUCCESS;
1791 break;
1794 retval = si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
1795 SI_DEVICE_RESET);
1796 si_reject_all_reset_pkts(si_ctlp, si_portp, port);
1797 mutex_exit(&si_portp->siport_mutex);
1799 break;
1801 case SATA_ADDR_CNTRL:
1802 for (i = 0; i < si_ctlp->sictl_num_ports; i++) {
1803 mutex_enter(&si_ctlp->sictl_mutex);
1804 si_portp = si_ctlp->sictl_ports[i];
1805 mutex_exit(&si_ctlp->sictl_mutex);
1807 mutex_enter(&si_portp->siport_mutex);
1810 * If mopping, then all the pending commands are being
1811 * mopped, therefore there is nothing else to do.
1813 if (si_portp->mopping_in_progress > 0) {
1814 SIDBG_P(SIDBG_RESET, si_portp,
1815 "si_tran_reset_dport: CNTRL port %d mopping"
1816 " in progress, so just return", i);
1817 mutex_exit(&si_portp->siport_mutex);
1818 retval = SI_SUCCESS;
1819 break;
1822 retval = si_reset_dport_wait_till_ready(si_ctlp,
1823 si_portp, i, SI_PORT_RESET);
1824 if (retval) {
1825 mutex_exit(&si_portp->siport_mutex);
1826 break;
1828 si_reject_all_reset_pkts(si_ctlp, si_portp, i);
1829 mutex_exit(&si_portp->siport_mutex);
1831 break;
1833 case SATA_ADDR_PMPORT:
1834 case SATA_ADDR_DPMPORT:
1835 SIDBG_P(SIDBG_RESET, si_portp,
1836 "port mult reset not implemented yet", NULL);
1837 /* FALLTHROUGH */
1839 default:
1840 retval = SI_FAILURE;
1844 return (retval);
1849 * Called by sata framework to activate a port as part of hotplug.
1851 * Note: Not port-mult aware.
1853 static int
1854 si_tran_hotplug_port_activate(dev_info_t *dip, sata_device_t *satadev)
1856 si_ctl_state_t *si_ctlp;
1857 si_port_state_t *si_portp;
1858 uint8_t port;
1860 si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
1861 port = satadev->satadev_addr.cport;
1862 mutex_enter(&si_ctlp->sictl_mutex);
1863 si_portp = si_ctlp->sictl_ports[port];
1864 mutex_exit(&si_ctlp->sictl_mutex);
1866 SIDBG_P(SIDBG_EVENT, si_portp, "si_tran_hotplug_port_activate entry",
1867 NULL);
1869 mutex_enter(&si_portp->siport_mutex);
1870 si_enable_port_interrupts(si_ctlp, port);
1873 * Reset the device so that a si_find_dev_signature() would trigger.
1874 * But this reset is an internal operation; the sata framework does
1875 * not need to know about it.
1877 (void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
1878 SI_DEVICE_RESET|SI_RESET_NO_EVENTS_UP);
1880 satadev->satadev_state = SATA_STATE_READY;
1882 si_portp->siport_active = PORT_ACTIVE;
1884 fill_dev_sregisters(si_ctlp, port, satadev);
1886 mutex_exit(&si_portp->siport_mutex);
1887 return (SATA_SUCCESS);
1891 * Called by sata framework to deactivate a port as part of hotplug.
1893 * Note: Not port-mult aware.
1895 static int
1896 si_tran_hotplug_port_deactivate(dev_info_t *dip, sata_device_t *satadev)
1898 si_ctl_state_t *si_ctlp;
1899 si_port_state_t *si_portp;
1900 uint8_t port;
1902 si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
1903 port = satadev->satadev_addr.cport;
1904 mutex_enter(&si_ctlp->sictl_mutex);
1905 si_portp = si_ctlp->sictl_ports[port];
1906 mutex_exit(&si_ctlp->sictl_mutex);
1908 SIDBG(SIDBG_EVENT, "si_tran_hotplug_port_deactivate entry", NULL);
1910 mutex_enter(&si_portp->siport_mutex);
1911 if (si_portp->siport_pending_tags & SI_SLOT_MASK) {
1913 * There are pending commands on this port.
1914 * Fail the deactivate request.
1916 satadev->satadev_state = SATA_STATE_READY;
1917 mutex_exit(&si_portp->siport_mutex);
1918 return (SATA_FAILURE);
1921 /* mark the device as not accessible any more. */
1922 si_portp->siport_active = PORT_INACTIVE;
1924 /* disable the interrupts on the port. */
1925 si_disable_port_interrupts(si_ctlp, port);
1927 satadev->satadev_state = SATA_PSTATE_SHUTDOWN;
1929 fill_dev_sregisters(si_ctlp, port, satadev);
1931 * Since we are implementing the port deactivation in software only,
1932 * we need to fake a valid value for sstatus.
1934 SSTATUS_SET_DET(satadev->satadev_scr.sstatus, SSTATUS_DET_PHYOFFLINE);
1935 SSTATUS_SET_IPM(satadev->satadev_scr.sstatus, SSTATUS_IPM_NODEV_NOPHY);
1937 mutex_exit(&si_portp->siport_mutex);
1938 return (SATA_SUCCESS);
1943 * Allocates the si_port_state_t.
1945 static int
1946 si_alloc_port_state(si_ctl_state_t *si_ctlp, int port)
1948 si_port_state_t *si_portp;
1950 si_ctlp->sictl_ports[port] = (si_port_state_t *)kmem_zalloc(
1951 sizeof (si_port_state_t), KM_SLEEP);
1953 si_portp = si_ctlp->sictl_ports[port];
1954 mutex_init(&si_portp->siport_mutex, NULL, MUTEX_DRIVER,
1955 (void *)(uintptr_t)si_ctlp->sictl_intr_pri);
1956 mutex_enter(&si_portp->siport_mutex);
1958 /* allocate prb & sgt pkts for this port. */
1959 if (si_alloc_prbpool(si_ctlp, port)) {
1960 mutex_exit(&si_portp->siport_mutex);
1961 kmem_free(si_ctlp->sictl_ports[port], sizeof (si_port_state_t));
1962 return (SI_FAILURE);
1964 if (si_alloc_sgbpool(si_ctlp, port)) {
1965 si_dealloc_prbpool(si_ctlp, port);
1966 mutex_exit(&si_portp->siport_mutex);
1967 kmem_free(si_ctlp->sictl_ports[port], sizeof (si_port_state_t));
1968 return (SI_FAILURE);
1971 /* Allocate the argument for the timeout */
1972 si_portp->siport_event_args =
1973 kmem_zalloc(sizeof (si_event_arg_t), KM_SLEEP);
1975 si_portp->siport_active = PORT_ACTIVE;
1976 mutex_exit(&si_portp->siport_mutex);
1978 return (SI_SUCCESS);
1983 * Deallocates the si_port_state_t.
1985 static void
1986 si_dealloc_port_state(si_ctl_state_t *si_ctlp, int port)
1988 si_port_state_t *si_portp;
1989 si_portp = si_ctlp->sictl_ports[port];
1991 mutex_enter(&si_portp->siport_mutex);
1992 kmem_free(si_portp->siport_event_args, sizeof (si_event_arg_t));
1993 si_dealloc_sgbpool(si_ctlp, port);
1994 si_dealloc_prbpool(si_ctlp, port);
1995 mutex_exit(&si_portp->siport_mutex);
1997 mutex_destroy(&si_portp->siport_mutex);
1999 kmem_free(si_ctlp->sictl_ports[port], sizeof (si_port_state_t));
2004 * Allocates the SGB (Scatter Gather Block) incore buffer.
2006 static int
2007 si_alloc_sgbpool(si_ctl_state_t *si_ctlp, int port)
2009 si_port_state_t *si_portp;
2010 uint_t cookie_count;
2011 size_t incore_sgbpool_size = SI_NUM_SLOTS * sizeof (si_sgblock_t)
2012 * si_dma_sg_number;
2013 size_t ret_len;
2014 ddi_dma_cookie_t sgbpool_dma_cookie;
2016 si_portp = si_ctlp->sictl_ports[port];
2018 /* allocate sgbpool dma handle. */
2019 if (ddi_dma_alloc_handle(si_ctlp->sictl_devinfop,
2020 &prb_sgt_dma_attr,
2021 DDI_DMA_SLEEP,
2022 NULL,
2023 &si_portp->siport_sgbpool_dma_handle) !=
2024 DDI_SUCCESS) {
2026 return (SI_FAILURE);
2029 /* allocate the memory for sgbpool. */
2030 if (ddi_dma_mem_alloc(si_portp->siport_sgbpool_dma_handle,
2031 incore_sgbpool_size,
2032 &accattr,
2033 DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2034 DDI_DMA_SLEEP,
2035 NULL,
2036 (caddr_t *)&si_portp->siport_sgbpool,
2037 &ret_len,
2038 &si_portp->siport_sgbpool_acc_handle) != NULL) {
2040 /* error.. free the dma handle. */
2041 ddi_dma_free_handle(&si_portp->siport_sgbpool_dma_handle);
2042 return (SI_FAILURE);
2045 /* now bind it */
2046 if (ddi_dma_addr_bind_handle(si_portp->siport_sgbpool_dma_handle,
2047 NULL,
2048 (caddr_t)si_portp->siport_sgbpool,
2049 incore_sgbpool_size,
2050 DDI_DMA_CONSISTENT,
2051 DDI_DMA_SLEEP,
2052 NULL,
2053 &sgbpool_dma_cookie,
2054 &cookie_count) != DDI_DMA_MAPPED) {
2055 /* error.. free the dma handle & free the memory. */
2056 ddi_dma_mem_free(&si_portp->siport_sgbpool_acc_handle);
2057 ddi_dma_free_handle(&si_portp->siport_sgbpool_dma_handle);
2058 return (SI_FAILURE);
2061 si_portp->siport_sgbpool_physaddr = sgbpool_dma_cookie.dmac_laddress;
2062 return (SI_SUCCESS);
2066 * Deallocates the SGB (Scatter Gather Block) incore buffer.
2068 static void
2069 si_dealloc_sgbpool(si_ctl_state_t *si_ctlp, int port)
2071 si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
2073 /* Unbind the dma handle first. */
2074 (void) ddi_dma_unbind_handle(si_portp->siport_sgbpool_dma_handle);
2076 /* Then free the underlying memory. */
2077 ddi_dma_mem_free(&si_portp->siport_sgbpool_acc_handle);
2079 /* Now free the handle itself. */
2080 ddi_dma_free_handle(&si_portp->siport_sgbpool_dma_handle);
2085 * Allocates the PRB (Port Request Block) incore packets.
2087 static int
2088 si_alloc_prbpool(si_ctl_state_t *si_ctlp, int port)
2090 si_port_state_t *si_portp;
2091 uint_t cookie_count;
2092 size_t incore_pkt_size = SI_NUM_SLOTS * sizeof (si_prb_t);
2093 size_t ret_len;
2094 ddi_dma_cookie_t prbpool_dma_cookie;
2096 si_portp = si_ctlp->sictl_ports[port];
2098 /* allocate prb pkts. */
2099 if (ddi_dma_alloc_handle(si_ctlp->sictl_devinfop,
2100 &prb_sgt_dma_attr,
2101 DDI_DMA_SLEEP,
2102 NULL,
2103 &si_portp->siport_prbpool_dma_handle) !=
2104 DDI_SUCCESS) {
2106 return (SI_FAILURE);
2109 if (ddi_dma_mem_alloc(si_portp->siport_prbpool_dma_handle,
2110 incore_pkt_size,
2111 &accattr,
2112 DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2113 DDI_DMA_SLEEP,
2114 NULL,
2115 (caddr_t *)&si_portp->siport_prbpool,
2116 &ret_len,
2117 &si_portp->siport_prbpool_acc_handle) != NULL) {
2119 /* error.. free the dma handle. */
2120 ddi_dma_free_handle(&si_portp->siport_prbpool_dma_handle);
2121 return (SI_FAILURE);
2124 if (ddi_dma_addr_bind_handle(si_portp->siport_prbpool_dma_handle,
2125 NULL,
2126 (caddr_t)si_portp->siport_prbpool,
2127 incore_pkt_size,
2128 DDI_DMA_CONSISTENT,
2129 DDI_DMA_SLEEP,
2130 NULL,
2131 &prbpool_dma_cookie,
2132 &cookie_count) != DDI_DMA_MAPPED) {
2133 /* error.. free the dma handle & free the memory. */
2134 ddi_dma_mem_free(&si_portp->siport_prbpool_acc_handle);
2135 ddi_dma_free_handle(&si_portp->siport_prbpool_dma_handle);
2136 return (SI_FAILURE);
2139 si_portp->siport_prbpool_physaddr =
2140 prbpool_dma_cookie.dmac_laddress;
2141 return (SI_SUCCESS);
2145 * Deallocates the PRB (Port Request Block) incore packets.
2147 static void
2148 si_dealloc_prbpool(si_ctl_state_t *si_ctlp, int port)
2150 si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
2152 /* Unbind the prb dma handle first. */
2153 (void) ddi_dma_unbind_handle(si_portp->siport_prbpool_dma_handle);
2155 /* Then free the underlying memory. */
2156 ddi_dma_mem_free(&si_portp->siport_prbpool_acc_handle);
2158 /* Now free the handle itself. */
2159 ddi_dma_free_handle(&si_portp->siport_prbpool_dma_handle);
2166 * Soft-reset the port to find the signature of the device connected to
2167 * the port.
2169 static void
2170 si_find_dev_signature(
2171 si_ctl_state_t *si_ctlp,
2172 si_port_state_t *si_portp,
2173 int port,
2174 int pmp)
2176 si_prb_t *prb;
2177 uint32_t slot_status, signature;
2178 int slot, loop_count;
2180 SIDBG_P(SIDBG_INIT, si_portp,
2181 "si_find_dev_signature enter: port: %x, pmp: %x",
2182 port, pmp);
2184 /* Build a Soft Reset PRB in host memory. */
2185 mutex_enter(&si_portp->siport_mutex);
2187 slot = si_claim_free_slot(si_ctlp, si_portp, port);
2188 if (slot == SI_FAILURE) {
2189 /* Empty slot could not be found. */
2190 if (pmp != PORTMULT_CONTROL_PORT) {
2191 /* We are behind port multiplier. */
2192 si_portp->siport_portmult_state.sipm_port_type[pmp] =
2193 PORT_TYPE_NODEV;
2194 } else {
2195 si_portp->siport_port_type = PORT_TYPE_NODEV;
2198 mutex_exit(&si_portp->siport_mutex);
2199 return;
2201 prb = &si_portp->siport_prbpool[slot];
2202 bzero((void *)prb, sizeof (si_prb_t));
2204 SET_FIS_PMP(prb->prb_fis, pmp);
2205 SET_PRB_CONTROL_SOFT_RESET(prb);
2207 #if SI_DEBUG
2208 if (si_debug_flags & SIDBG_DUMP_PRB) {
2209 char *ptr;
2210 int j;
2212 ptr = (char *)prb;
2213 cmn_err(CE_WARN, "si_find_dev_signature, prb: ");
2214 for (j = 0; j < (sizeof (si_prb_t)); j++) {
2215 if (j%4 == 0) {
2216 cmn_err(CE_WARN, "----");
2218 cmn_err(CE_WARN, "%x ", ptr[j]);
2222 #endif /* SI_DEBUG */
2224 /* deliver soft reset prb to empty slot. */
2225 POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
2227 loop_count = 0;
2228 /* Loop till the soft reset is finished. */
2229 do {
2230 slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
2231 (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
2233 if (loop_count++ > SI_POLLRATE_SOFT_RESET) {
2234 /* We are effectively timing out after 10 sec. */
2235 break;
2238 /* Wait for 10 millisec */
2239 #ifndef __lock_lint
2240 delay(SI_10MS_TICKS);
2241 #endif /* __lock_lint */
2243 } while (slot_status & SI_SLOT_MASK & (0x1 << slot));
2245 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
2246 "si_find_dev_signature: loop count: %d, slot_status: 0x%x",
2247 loop_count, slot_status);
2249 CLEAR_BIT(si_portp->siport_pending_tags, slot);
2251 /* Read device signature from command slot. */
2252 signature = ddi_get32(si_ctlp->sictl_port_acc_handle,
2253 (uint32_t *)(PORT_SIGNATURE_MSB(si_ctlp, port, slot)));
2254 signature <<= 8;
2255 signature |= (0xff & ddi_get32(si_ctlp->sictl_port_acc_handle,
2256 (uint32_t *)(PORT_SIGNATURE_LSB(si_ctlp,
2257 port, slot))));
2259 SIDBG_P(SIDBG_INIT, si_portp, "Device signature: 0x%x", signature);
2261 if (signature == SI_SIGNATURE_PORT_MULTIPLIER) {
2263 SIDBG_P(SIDBG_INIT, si_portp,
2264 "Found multiplier at cport: 0x%d, pmport: 0x%x",
2265 port, pmp);
2267 if (pmp != PORTMULT_CONTROL_PORT) {
2269 * It is wrong to chain a port multiplier behind
2270 * another port multiplier.
2272 si_portp->siport_portmult_state.sipm_port_type[pmp] =
2273 PORT_TYPE_NODEV;
2274 } else {
2275 si_portp->siport_port_type = PORT_TYPE_MULTIPLIER;
2276 mutex_exit(&si_portp->siport_mutex);
2277 (void) si_enumerate_port_multiplier(si_ctlp,
2278 si_portp, port);
2279 mutex_enter(&si_portp->siport_mutex);
2281 si_init_port(si_ctlp, port);
2283 } else if (signature == SI_SIGNATURE_ATAPI) {
2284 if (pmp != PORTMULT_CONTROL_PORT) {
2285 /* We are behind port multiplier. */
2286 si_portp->siport_portmult_state.sipm_port_type[pmp] =
2287 PORT_TYPE_ATAPI;
2288 } else {
2289 si_portp->siport_port_type = PORT_TYPE_ATAPI;
2290 si_init_port(si_ctlp, port);
2292 SIDBG_P(SIDBG_INIT, si_portp,
2293 "Found atapi at : cport: %x, pmport: %x",
2294 port, pmp);
2296 } else if (signature == SI_SIGNATURE_DISK) {
2298 if (pmp != PORTMULT_CONTROL_PORT) {
2299 /* We are behind port multiplier. */
2300 si_portp->siport_portmult_state.sipm_port_type[pmp] =
2301 PORT_TYPE_DISK;
2302 } else {
2303 si_portp->siport_port_type = PORT_TYPE_DISK;
2304 si_init_port(si_ctlp, port);
2306 SIDBG_P(SIDBG_INIT, si_portp,
2307 "found disk at : cport: %x, pmport: %x",
2308 port, pmp);
2310 } else {
2311 if (pmp != PORTMULT_CONTROL_PORT) {
2312 /* We are behind port multiplier. */
2313 si_portp->siport_portmult_state.sipm_port_type[pmp] =
2314 PORT_TYPE_UNKNOWN;
2315 } else {
2316 si_portp->siport_port_type = PORT_TYPE_UNKNOWN;
2318 SIDBG_P(SIDBG_INIT, si_portp,
2319 "Found unknown signature 0x%x at: port: %x, pmp: %x",
2320 signature, port, pmp);
2323 mutex_exit(&si_portp->siport_mutex);
2328 * Polls for the completion of the command. This is safe with both
2329 * interrupts enabled or disabled.
2331 static void
2332 si_poll_cmd(
2333 si_ctl_state_t *si_ctlp,
2334 si_port_state_t *si_portp,
2335 int port,
2336 int slot,
2337 sata_pkt_t *satapkt)
2339 uint32_t slot_status;
2340 int pkt_timeout_ticks;
2341 uint32_t port_intr_status;
2342 int in_panic = ddi_in_panic();
2344 SIDBG_P(SIDBG_ENTRY, si_portp, "si_poll_cmd entered: port: 0x%x", port);
2346 pkt_timeout_ticks = drv_usectohz((clock_t)satapkt->satapkt_time *
2347 1000000);
2350 /* we start out with SATA_PKT_COMPLETED as the satapkt_reason */
2351 satapkt->satapkt_reason = SATA_PKT_COMPLETED;
2353 do {
2354 slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
2355 (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
2357 if (slot_status & SI_SLOT_MASK & (0x1 << slot)) {
2358 if (in_panic) {
2360 * If we are in panic, we can't rely on
2361 * timers; so, busy wait instead of delay().
2363 mutex_exit(&si_portp->siport_mutex);
2364 drv_usecwait(SI_1MS_USECS);
2365 mutex_enter(&si_portp->siport_mutex);
2366 } else {
2367 mutex_exit(&si_portp->siport_mutex);
2368 #ifndef __lock_lint
2369 delay(SI_1MS_TICKS);
2370 #endif /* __lock_lint */
2371 mutex_enter(&si_portp->siport_mutex);
2373 } else {
2374 break;
2377 pkt_timeout_ticks -= SI_1MS_TICKS;
2379 } while (pkt_timeout_ticks > 0);
2381 if (satapkt->satapkt_reason != SATA_PKT_COMPLETED) {
2382 /* The si_mop_command() got to our packet before us */
2384 return;
2388 * Interrupts and timers may not be working properly in a crash dump
2389 * situation; we may need to handle all the three conditions here:
2390 * successful completion, packet failure and packet timeout.
2392 if (IS_ATTENTION_RAISED(slot_status)) { /* error seen on port */
2394 port_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
2395 (uint32_t *)PORT_INTERRUPT_STATUS(si_ctlp, port));
2397 SIDBG_P(SIDBG_VERBOSE, si_portp,
2398 "si_poll_cmd: port_intr_status: 0x%x, port: %x",
2399 port_intr_status, port);
2401 if (port_intr_status & INTR_COMMAND_ERROR) {
2402 mutex_exit(&si_portp->siport_mutex);
2403 (void) si_intr_command_error(si_ctlp, si_portp, port);
2404 mutex_enter(&si_portp->siport_mutex);
2406 return;
2409 * Why do we need to call si_intr_command_error() ?
2411 * Answer: Even if the current packet is not the
2412 * offending command, we need to restart the stalled
2413 * port; (may be, the interrupts are not working well
2414 * in panic condition). The call to routine
2415 * si_intr_command_error() will achieve that.
2417 * What if the interrupts are working fine and the
2418 * si_intr_command_error() gets called once more from
2419 * interrupt context ?
2421 * Answer: The second instance of routine
2422 * si_intr_command_error() will not mop anything
2423 * since the first error handler has already blown
2424 * away the hardware pending queues through reset.
2426 * Will the si_intr_command_error() hurt current
2427 * packet ?
2429 * Answer: No.
2431 } else {
2432 /* Ignore any non-error interrupts at this stage */
2433 ddi_put32(si_ctlp->sictl_port_acc_handle,
2434 (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp,
2435 port)),
2436 port_intr_status & INTR_MASK);
2439 } else if (slot_status & SI_SLOT_MASK & (0x1 << slot)) {
2440 satapkt->satapkt_reason = SATA_PKT_TIMEOUT;
2442 } /* else: the command completed successfully */
2444 if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
2445 si_copy_out_regs(&satapkt->satapkt_cmd, si_ctlp, port, slot);
2448 if ((satapkt->satapkt_cmd.satacmd_cmd_reg ==
2449 SATAC_WRITE_FPDMA_QUEUED) ||
2450 (satapkt->satapkt_cmd.satacmd_cmd_reg ==
2451 SATAC_READ_FPDMA_QUEUED)) {
2452 si_portp->siport_pending_ncq_count--;
2455 CLEAR_BIT(si_portp->siport_pending_tags, slot);
2458 * tidbit: What is the interaction of abort with polling ?
2459 * What happens if the current polled pkt is aborted in parallel ?
2461 * Answer: Assuming that the si_mop_commands() completes ahead
2462 * of polling, all it does is to set the satapkt_reason to
2463 * SPKT_PKT_ABORTED. That would be fine with us.
2465 * The same logic applies to reset interacting with polling.
2471 * Searches for and claims a free slot.
2473 * Returns: SI_FAILURE if no slots found
2474 * claimed slot number if successful
2476 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
2477 * before calling us.
2479 /*ARGSUSED*/
2480 static int
2481 si_claim_free_slot(si_ctl_state_t *si_ctlp, si_port_state_t *si_portp, int port)
2483 uint32_t free_slots;
2484 int slot;
2486 _NOTE(ASSUMING_PROTECTED(si_portp))
2488 SIDBG_P(SIDBG_ENTRY, si_portp,
2489 "si_claim_free_slot entry: siport_pending_tags: %x",
2490 si_portp->siport_pending_tags);
2492 free_slots = (~si_portp->siport_pending_tags) & SI_SLOT_MASK;
2493 slot = ddi_ffs(free_slots) - 1;
2494 if (slot == -1) {
2495 SIDBG_P(SIDBG_VERBOSE, si_portp,
2496 "si_claim_free_slot: no empty slots", NULL);
2497 return (SI_FAILURE);
2500 si_portp->siport_pending_tags |= (0x1 << slot);
2501 SIDBG_P(SIDBG_VERBOSE, si_portp, "si_claim_free_slot: found slot: 0x%x",
2502 slot);
2503 return (slot);
2507 * Builds the PRB for the sata packet and delivers it to controller.
2509 * Returns:
2510 * slot number if we can obtain a slot successfully
2511 * otherwise, return SI_FAILURE
2513 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
2514 * before calling us.
2516 static int
2517 si_deliver_satapkt(
2518 si_ctl_state_t *si_ctlp,
2519 si_port_state_t *si_portp,
2520 int port,
2521 sata_pkt_t *spkt)
2523 int slot;
2524 si_prb_t *prb;
2525 sata_cmd_t *cmd;
2526 si_sge_t *sgep; /* scatter gather entry pointer */
2527 si_sgt_t *sgtp; /* scatter gather table pointer */
2528 si_sgblock_t *sgbp; /* scatter gather block pointer */
2529 int i, j, cookie_index;
2530 int ncookies;
2531 int is_atapi = 0;
2532 ddi_dma_cookie_t cookie;
2534 _NOTE(ASSUMING_PROTECTED(si_portp))
2536 slot = si_claim_free_slot(si_ctlp, si_portp, port);
2537 if (slot == SI_FAILURE) {
2538 return (SI_FAILURE);
2541 if (spkt->satapkt_device.satadev_type == SATA_DTYPE_ATAPICD) {
2542 is_atapi = 1;
2545 if ((si_portp->siport_port_type == PORT_TYPE_NODEV) ||
2546 !si_portp->siport_active) {
2548 * si_intr_phy_ready_change() may have rendered it to
2549 * PORT_TYPE_NODEV. cfgadm operation may have rendered
2550 * it inactive.
2552 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
2553 fill_dev_sregisters(si_ctlp, port, &spkt->satapkt_device);
2554 CLEAR_BIT(si_portp->siport_pending_tags, slot);
2556 return (SI_FAILURE);
2560 prb = &(si_portp->siport_prbpool[slot]);
2561 bzero((void *)prb, sizeof (si_prb_t));
2563 cmd = &spkt->satapkt_cmd;
2565 SIDBG_P(SIDBG_ENTRY, si_portp,
2566 "si_deliver_satpkt entry: cmd_reg: 0x%x, slot: 0x%x, \
2567 port: %x, satapkt: %x",
2568 cmd->satacmd_cmd_reg, slot, port, (uint32_t)(intptr_t)spkt);
2570 /* Now fill the prb. */
2571 if (is_atapi) {
2572 if (spkt->satapkt_cmd.satacmd_flags.sata_data_direction ==
2573 SATA_DIR_READ) {
2574 SET_PRB_CONTROL_PKT_READ(prb);
2575 } else if (spkt->satapkt_cmd.satacmd_flags.sata_data_direction
2576 == SATA_DIR_WRITE) {
2577 SET_PRB_CONTROL_PKT_WRITE(prb);
2581 SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
2582 if ((spkt->satapkt_device.satadev_addr.qual == SATA_ADDR_PMPORT) ||
2583 (spkt->satapkt_device.satadev_addr.qual == SATA_ADDR_DPMPORT)) {
2584 SET_FIS_PMP(prb->prb_fis,
2585 spkt->satapkt_device.satadev_addr.pmport);
2587 SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
2588 SET_FIS_COMMAND(prb->prb_fis, cmd->satacmd_cmd_reg);
2589 SET_FIS_FEATURES(prb->prb_fis, cmd->satacmd_features_reg);
2590 SET_FIS_SECTOR_COUNT(prb->prb_fis, cmd->satacmd_sec_count_lsb);
2592 switch (cmd->satacmd_addr_type) {
2594 case 0:
2596 * satacmd_addr_type will be 0 for the commands below:
2597 * SATAC_PACKET
2598 * SATAC_IDLE_IM
2599 * SATAC_STANDBY_IM
2600 * SATAC_DOWNLOAD_MICROCODE
2601 * SATAC_FLUSH_CACHE
2602 * SATAC_SET_FEATURES
2603 * SATAC_SMART
2604 * SATAC_ID_PACKET_DEVICE
2605 * SATAC_ID_DEVICE
2606 * SATAC_READ_PORTMULT
2607 * SATAC_WRITE_PORTMULT
2609 /* FALLTHRU */
2611 case ATA_ADDR_LBA:
2612 /* FALLTHRU */
2614 case ATA_ADDR_LBA28:
2615 /* LBA[7:0] */
2616 SET_FIS_SECTOR(prb->prb_fis, cmd->satacmd_lba_low_lsb);
2618 /* LBA[15:8] */
2619 SET_FIS_CYL_LOW(prb->prb_fis, cmd->satacmd_lba_mid_lsb);
2621 /* LBA[23:16] */
2622 SET_FIS_CYL_HI(prb->prb_fis, cmd->satacmd_lba_high_lsb);
2624 /* LBA [27:24] (also called dev_head) */
2625 SET_FIS_DEV_HEAD(prb->prb_fis, cmd->satacmd_device_reg);
2627 break;
2629 case ATA_ADDR_LBA48:
2630 /* LBA[7:0] */
2631 SET_FIS_SECTOR(prb->prb_fis, cmd->satacmd_lba_low_lsb);
2633 /* LBA[15:8] */
2634 SET_FIS_CYL_LOW(prb->prb_fis, cmd->satacmd_lba_mid_lsb);
2636 /* LBA[23:16] */
2637 SET_FIS_CYL_HI(prb->prb_fis, cmd->satacmd_lba_high_lsb);
2639 /* LBA [31:24] */
2640 SET_FIS_SECTOR_EXP(prb->prb_fis, cmd->satacmd_lba_low_msb);
2642 /* LBA [39:32] */
2643 SET_FIS_CYL_LOW_EXP(prb->prb_fis, cmd->satacmd_lba_mid_msb);
2645 /* LBA [47:40] */
2646 SET_FIS_CYL_HI_EXP(prb->prb_fis, cmd->satacmd_lba_high_msb);
2648 /* Set dev_head */
2649 SET_FIS_DEV_HEAD(prb->prb_fis, cmd->satacmd_device_reg);
2651 /* Set the extended sector count and features */
2652 SET_FIS_SECTOR_COUNT_EXP(prb->prb_fis,
2653 cmd->satacmd_sec_count_msb);
2654 SET_FIS_FEATURES_EXP(prb->prb_fis,
2655 cmd->satacmd_features_reg_ext);
2657 break;
2661 if (cmd->satacmd_flags.sata_queued) {
2663 * For queued commands, the TAG for the sector count lsb is
2664 * generated from current slot number.
2666 SET_FIS_SECTOR_COUNT(prb->prb_fis, slot << 3);
2669 if ((cmd->satacmd_cmd_reg == SATAC_WRITE_FPDMA_QUEUED) ||
2670 (cmd->satacmd_cmd_reg == SATAC_READ_FPDMA_QUEUED)) {
2671 si_portp->siport_pending_ncq_count++;
2674 /* *** now fill the scatter gather list ******* */
2676 if (is_atapi) { /* It is an ATAPI drive */
2677 /* atapi command goes into sge0 */
2678 bcopy(cmd->satacmd_acdb, &prb->prb_sge0, sizeof (si_sge_t));
2680 /* Now fill sge1 with pointer to external SGT. */
2681 if (spkt->satapkt_cmd.satacmd_num_dma_cookies) {
2682 prb->prb_sge1.sge_addr =
2683 si_portp->siport_sgbpool_physaddr +
2684 slot * sizeof (si_sgblock_t) * si_dma_sg_number;
2685 SET_SGE_LNK(prb->prb_sge1);
2686 } else {
2687 SET_SGE_TRM(prb->prb_sge1);
2689 } else {
2690 /* Fill the sge0 */
2691 if (spkt->satapkt_cmd.satacmd_num_dma_cookies) {
2692 prb->prb_sge0.sge_addr =
2693 si_portp->siport_sgbpool_physaddr +
2694 slot * sizeof (si_sgblock_t) * si_dma_sg_number;
2695 SET_SGE_LNK(prb->prb_sge0);
2697 } else {
2698 SET_SGE_TRM(prb->prb_sge0);
2701 /* sge1 is left empty in non-ATAPI case */
2704 bzero(&si_portp->siport_sgbpool[slot * si_dma_sg_number],
2705 sizeof (si_sgblock_t) * si_dma_sg_number);
2707 ncookies = spkt->satapkt_cmd.satacmd_num_dma_cookies;
2708 ASSERT(ncookies <= (SGE_LENGTH(si_dma_sg_number)));
2710 SIDBG_P(SIDBG_COOKIES, si_portp, "total ncookies: %d", ncookies);
2711 if (ncookies == 0) {
2712 sgbp = &si_portp->siport_sgbpool[slot * si_dma_sg_number];
2713 sgtp = &sgbp->sgb_sgt[0];
2714 sgep = &sgtp->sgt_sge[0];
2716 /* No cookies. Terminate the chain. */
2717 SIDBG_P(SIDBG_COOKIES, si_portp, "empty cookies: terminating.",
2718 NULL);
2720 sgep->sge_addr_low = 0;
2721 sgep->sge_addr_high = 0;
2722 sgep->sge_data_count = 0;
2723 SET_SGE_TRM((*sgep));
2725 goto sgl_fill_done;
2728 for (i = 0, cookie_index = 0,
2729 sgbp = &si_portp->siport_sgbpool[slot * si_dma_sg_number];
2730 i < si_dma_sg_number; i++) {
2732 sgtp = &sgbp->sgb_sgt[0] + i;
2734 /* Now fill the first 3 entries of SGT in the loop below. */
2735 for (j = 0, sgep = &sgtp->sgt_sge[0];
2736 ((j < 3) && (cookie_index < ncookies-1));
2737 j++, cookie_index++, sgep++) {
2738 ASSERT(cookie_index < ncookies);
2739 SIDBG_P(SIDBG_COOKIES, si_portp,
2740 "inner loop: cookie_index: %d, ncookies: %d",
2741 cookie_index,
2742 ncookies);
2743 cookie = spkt->satapkt_cmd.
2744 satacmd_dma_cookie_list[cookie_index];
2746 sgep->sge_addr_low = cookie._dmu._dmac_la[0];
2747 sgep->sge_addr_high = cookie._dmu._dmac_la[1];
2748 sgep->sge_data_count = (uint32_t)cookie.dmac_size;
2752 * If this happens to be the last cookie, we terminate it here.
2753 * Otherwise, we link to next SGT.
2756 if (cookie_index == ncookies-1) {
2757 /* This is the last cookie. Terminate the chain. */
2758 SIDBG_P(SIDBG_COOKIES, si_portp,
2759 "filling the last: cookie_index: %d, "
2760 "ncookies: %d",
2761 cookie_index,
2762 ncookies);
2763 cookie = spkt->satapkt_cmd.
2764 satacmd_dma_cookie_list[cookie_index];
2766 sgep->sge_addr_low = cookie._dmu._dmac_la[0];
2767 sgep->sge_addr_high = cookie._dmu._dmac_la[1];
2768 sgep->sge_data_count = (uint32_t)cookie.dmac_size;
2769 SET_SGE_TRM((*sgep));
2771 break; /* we break the loop */
2773 } else {
2774 /* This is not the last one. So link it. */
2775 SIDBG_P(SIDBG_COOKIES, si_portp,
2776 "linking SGT: cookie_index: %d, ncookies: %d",
2777 cookie_index,
2778 ncookies);
2779 sgep->sge_addr = si_portp->siport_sgbpool_physaddr +
2780 slot * sizeof (si_sgblock_t) * si_dma_sg_number +
2781 (i+1) * sizeof (si_sgt_t);
2783 SET_SGE_LNK((*sgep));
2788 /* *** finished filling the scatter gather list ******* */
2790 sgl_fill_done:
2791 /* Now remember the sata packet in siport_slot_pkts[]. */
2792 si_portp->siport_slot_pkts[slot] = spkt;
2795 * We are overloading satapkt_hba_driver_private with
2796 * watched_cycle count.
2798 spkt->satapkt_hba_driver_private = (void *)(intptr_t)0;
2800 if (is_atapi) {
2801 /* program the packet_lenth if it is atapi device. */
2804 #ifdef ATAPI_2nd_PHASE
2806 * Framework needs to calculate the acdb_len based on
2807 * identify packet data. This needs to be accomplished
2808 * in second phase of the project.
2810 ASSERT((cmd->satacmd_acdb_len == 12) ||
2811 (cmd->satacmd_acdb_len == 16));
2812 SIDBG_P(SIDBG_VERBOSE, si_portp, "deliver: acdb_len: %d",
2813 cmd->satacmd_acdb_len);
2815 if (cmd->satacmd_acdb_len == 16) {
2816 ddi_put32(si_ctlp->sictl_port_acc_handle,
2817 (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
2818 PORT_CONTROL_SET_BITS_PACKET_LEN);
2819 } else {
2820 ddi_put32(si_ctlp->sictl_port_acc_handle,
2821 (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
2822 PORT_CONTROL_CLEAR_BITS_PACKET_LEN);
2825 #else /* ATAPI_2nd_PHASE */
2826 /* hard coding for now to 12 bytes */
2827 ddi_put32(si_ctlp->sictl_port_acc_handle,
2828 (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
2829 PORT_CONTROL_CLEAR_BITS_PACKET_LEN);
2830 #endif /* ATAPI_2nd_PHASE */
2834 #if SI_DEBUG
2835 if (si_debug_flags & SIDBG_DUMP_PRB) {
2836 if (!(is_atapi && (prb->prb_sge0.sge_addr_low == 0))) {
2838 * Do not dump the atapi Test-Unit-Ready commands.
2839 * The sd_media_watch spews too many of these.
2841 int *ptr;
2842 si_sge_t *tmpsgep;
2843 int j;
2845 ptr = (int *)(void *)prb;
2846 cmn_err(CE_WARN, "si_deliver_satpkt prb: ");
2847 for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
2848 cmn_err(CE_WARN, "%x ", ptr[j]);
2851 cmn_err(CE_WARN,
2852 "si_deliver_satpkt sgt: low, high, count link");
2853 for (j = 0,
2854 tmpsgep = (si_sge_t *)
2855 &si_portp->siport_sgbpool[slot * si_dma_sg_number];
2856 j < (sizeof (si_sgblock_t)/ sizeof (si_sge_t))
2857 *si_dma_sg_number;
2858 j++, tmpsgep++) {
2859 ptr = (int *)(void *)tmpsgep;
2860 cmn_err(CE_WARN, "%x %x %x %x",
2861 ptr[0],
2862 ptr[1],
2863 ptr[2],
2864 ptr[3]);
2865 if (IS_SGE_TRM_SET((*tmpsgep))) {
2866 break;
2873 #endif /* SI_DEBUG */
2875 /* Deliver PRB */
2876 POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
2878 return (slot);
2882 * Initialize the controller and set up driver data structures.
2884 * This routine can be called from three separate cases: DDI_ATTACH, PM_LEVEL_D0
2885 * and DDI_RESUME. The DDI_ATTACH case is different from other two cases; the
2886 * memory allocation & device signature probing are attempted only during
2887 * DDI_ATTACH case. In the case of PM_LEVEL_D0 & DDI_RESUME, we are starting
2888 * from a previously initialized state; so there is no need to allocate memory
2889 * or to attempt probing the device signatures.
2891 static int
2892 si_initialize_controller(si_ctl_state_t *si_ctlp)
2894 uint32_t port_status;
2895 uint32_t SStatus;
2896 uint32_t SControl;
2897 uint8_t port;
2898 int loop_count = 0;
2899 si_port_state_t *si_portp;
2901 SIDBG_C(SIDBG_INIT, si_ctlp,
2902 "si3124: si_initialize_controller entered", NULL);
2904 mutex_enter(&si_ctlp->sictl_mutex);
2906 /* Remove the Global Reset. */
2907 ddi_put32(si_ctlp->sictl_global_acc_handle,
2908 (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp),
2909 GLOBAL_CONTROL_REG_BITS_CLEAR);
2911 for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
2913 if (si_ctlp->sictl_flags & SI_ATTACH) {
2915 * We allocate the port state only during attach
2916 * sequence. We don't want to do it during
2917 * suspend/resume sequence.
2919 if (si_alloc_port_state(si_ctlp, port)) {
2920 mutex_exit(&si_ctlp->sictl_mutex);
2921 return (SI_FAILURE);
2925 si_portp = si_ctlp->sictl_ports[port];
2926 mutex_enter(&si_portp->siport_mutex);
2927 si_portp->siport_ctlp = si_ctlp;
2928 si_portp->siport_port_num = port;
2930 /* Clear Port Reset. */
2931 ddi_put32(si_ctlp->sictl_port_acc_handle,
2932 (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
2933 PORT_CONTROL_SET_BITS_PORT_RESET);
2934 ddi_put32(si_ctlp->sictl_port_acc_handle,
2935 (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
2936 PORT_CONTROL_CLEAR_BITS_PORT_RESET);
2939 * Arm the interrupts for: Cmd completion, Cmd error,
2940 * Port Ready, PM Change, PhyRdyChange, Commwake,
2941 * UnrecFIS, Devxchanged, SDBNotify.
2943 ddi_put32(si_ctlp->sictl_port_acc_handle,
2944 (uint32_t *)PORT_INTERRUPT_ENABLE_SET(si_ctlp, port),
2945 (INTR_COMMAND_COMPLETE |
2946 INTR_COMMAND_ERROR |
2947 INTR_PORT_READY |
2948 INTR_POWER_CHANGE |
2949 INTR_PHYRDY_CHANGE |
2950 INTR_COMWAKE_RECEIVED |
2951 INTR_UNRECOG_FIS |
2952 INTR_DEV_XCHANGED |
2953 INTR_SETDEVBITS_NOTIFY));
2955 /* Now enable the interrupts. */
2956 si_enable_port_interrupts(si_ctlp, port);
2959 * The following PHY initialization is redundant in
2960 * in x86 since the BIOS anyway does this as part of
2961 * device enumeration during the power up. But this
2962 * is a required step in sparc since there is no BIOS.
2964 * The way to initialize the PHY is to write a 1 and then
2965 * a 0 to DET field of SControl register.
2969 * Fetch the current SControl before writing the
2970 * DET part with 1
2972 SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
2973 (uint32_t *)PORT_SCONTROL(si_ctlp, port));
2974 SCONTROL_SET_DET(SControl, SCONTROL_DET_COMRESET);
2975 ddi_put32(si_ctlp->sictl_port_acc_handle,
2976 (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
2977 SControl);
2978 #ifndef __lock_lint
2979 delay(SI_10MS_TICKS); /* give time for COMRESET to percolate */
2980 #endif /* __lock_lint */
2983 * Now fetch the SControl again and rewrite the
2984 * DET part with 0
2986 SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
2987 (uint32_t *)PORT_SCONTROL(si_ctlp, port));
2988 SCONTROL_SET_DET(SControl, SCONTROL_DET_NOACTION);
2989 ddi_put32(si_ctlp->sictl_port_acc_handle,
2990 (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
2991 SControl);
2994 * PHY may be initialized by now. Check the DET field of
2995 * SStatus to determine if there is a device present.
2997 * The DET field is valid only if IPM field indicates that
2998 * the interface is in active state.
3001 loop_count = 0;
3002 do {
3003 SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
3004 (uint32_t *)PORT_SSTATUS(si_ctlp, port));
3006 if (SSTATUS_GET_IPM(SStatus) !=
3007 SSTATUS_IPM_INTERFACE_ACTIVE) {
3009 * If the interface is not active, the DET field
3010 * is considered not accurate. So we want to
3011 * continue looping.
3013 SSTATUS_SET_DET(SStatus,
3014 SSTATUS_DET_NODEV_NOPHY);
3017 if (loop_count++ > SI_POLLRATE_SSTATUS) {
3019 * We are effectively timing out after 0.1 sec.
3021 break;
3024 /* Wait for 10 millisec */
3025 #ifndef __lock_lint
3026 delay(SI_10MS_TICKS);
3027 #endif /* __lock_lint */
3029 } while (SSTATUS_GET_DET(SStatus) !=
3030 SSTATUS_DET_DEVPRESENT_PHYONLINE);
3032 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3033 "si_initialize_controller: 1st loop count: %d, "
3034 "SStatus: 0x%x",
3035 loop_count,
3036 SStatus);
3038 if ((SSTATUS_GET_IPM(SStatus) !=
3039 SSTATUS_IPM_INTERFACE_ACTIVE) ||
3040 (SSTATUS_GET_DET(SStatus) !=
3041 SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
3043 * Either the port is not active or there
3044 * is no device present.
3046 si_ctlp->sictl_ports[port]->siport_port_type =
3047 PORT_TYPE_NODEV;
3048 mutex_exit(&si_portp->siport_mutex);
3049 continue;
3052 /* Wait until Port Ready */
3053 loop_count = 0;
3054 do {
3055 port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3056 (uint32_t *)PORT_STATUS(si_ctlp, port));
3058 if (loop_count++ > SI_POLLRATE_PORTREADY) {
3060 * We are effectively timing out after 0.5 sec.
3062 break;
3065 /* Wait for 10 millisec */
3066 #ifndef __lock_lint
3067 delay(SI_10MS_TICKS);
3068 #endif /* __lock_lint */
3070 } while (!(port_status & PORT_STATUS_BITS_PORT_READY));
3072 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3073 "si_initialize_controller: 2nd loop count: %d",
3074 loop_count);
3076 if (si_ctlp->sictl_flags & SI_ATTACH) {
3078 * We want to probe for dev signature only during attach
3079 * case. Don't do it during suspend/resume sequence.
3081 if (port_status & PORT_STATUS_BITS_PORT_READY) {
3082 mutex_exit(&si_portp->siport_mutex);
3083 si_find_dev_signature(si_ctlp, si_portp, port,
3084 PORTMULT_CONTROL_PORT);
3085 mutex_enter(&si_portp->siport_mutex);
3086 } else {
3087 si_ctlp->sictl_ports[port]->siport_port_type =
3088 PORT_TYPE_NODEV;
3092 if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
3093 si_check_port_handles(si_portp) != DDI_SUCCESS) {
3094 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3095 DDI_SERVICE_LOST);
3096 mutex_exit(&si_portp->siport_mutex);
3097 mutex_exit(&si_ctlp->sictl_mutex);
3098 return (SI_FAILURE);
3101 mutex_exit(&si_portp->siport_mutex);
3104 mutex_exit(&si_ctlp->sictl_mutex);
3105 return (SI_SUCCESS);
3109 * Reverse of si_initialize_controller().
3111 * WARNING, WARNING: The caller is expected to obtain the sictl_mutex
3112 * before calling us.
3114 static void
3115 si_deinitialize_controller(si_ctl_state_t *si_ctlp)
3117 int port;
3119 _NOTE(ASSUMING_PROTECTED(si_ctlp))
3121 SIDBG_C(SIDBG_INIT, si_ctlp,
3122 "si3124: si_deinitialize_controller entered", NULL);
3124 /* disable all the interrupts. */
3125 si_disable_all_interrupts(si_ctlp);
3127 if (si_ctlp->sictl_flags & SI_DETACH) {
3129 * We want to dealloc all the memory in detach case.
3131 for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
3132 si_dealloc_port_state(si_ctlp, port);
3139 * Prepare the port ready for usage.
3141 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
3142 * before calling us.
3144 static void
3145 si_init_port(si_ctl_state_t *si_ctlp, int port)
3148 SIDBG_C(SIDBG_INIT, si_ctlp,
3149 "si_init_port entered: port: 0x%x",
3150 port);
3152 /* Initialize the port. */
3153 ddi_put32(si_ctlp->sictl_port_acc_handle,
3154 (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
3155 PORT_CONTROL_SET_BITS_PORT_INITIALIZE);
3158 * Clear the InterruptNCOR (Interrupt No Clear on Read).
3159 * This step ensures that a mere reading of slot_status will clear
3160 * the interrupt; no explicit clearing of interrupt condition
3161 * will be needed for successful completion of commands.
3163 ddi_put32(si_ctlp->sictl_port_acc_handle,
3164 (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
3165 PORT_CONTROL_CLEAR_BITS_INTR_NCoR);
3167 /* clear any pending interrupts at this point */
3168 ddi_put32(si_ctlp->sictl_port_acc_handle,
3169 (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp, port)),
3170 INTR_MASK);
3176 * Enumerate the devices connected to the port multiplier.
3177 * Once a device is detected, we call si_find_dev_signature()
3178 * to find the type of device connected. Even though we are
3179 * called from within si_find_dev_signature(), there is no
3180 * recursion possible.
3182 static int
3183 si_enumerate_port_multiplier(
3184 si_ctl_state_t *si_ctlp,
3185 si_port_state_t *si_portp,
3186 int port)
3188 uint32_t num_dev_ports = 0;
3189 int pmport;
3190 uint32_t SControl = 0;
3191 uint32_t SStatus = 0;
3192 uint32_t SError = 0;
3193 int loop_count = 0;
3195 SIDBG_P(SIDBG_INIT, si_portp,
3196 "si_enumerate_port_multiplier entered: port: %d",
3197 port);
3199 mutex_enter(&si_portp->siport_mutex);
3201 /* Enable Port Multiplier context switching. */
3202 ddi_put32(si_ctlp->sictl_port_acc_handle,
3203 (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
3204 PORT_CONTROL_SET_BITS_PM_ENABLE);
3207 * Read the num dev ports connected.
3208 * GSCR[2] contains the number of device ports.
3210 if (si_read_portmult_reg(si_ctlp, si_portp, port, PORTMULT_CONTROL_PORT,
3211 PSCR_REG2, &num_dev_ports)) {
3212 mutex_exit(&si_portp->siport_mutex);
3213 return (SI_FAILURE);
3215 si_portp->siport_portmult_state.sipm_num_ports = num_dev_ports;
3217 SIDBG_P(SIDBG_INIT, si_portp,
3218 "si_enumerate_port_multiplier: ports found: %d",
3219 num_dev_ports);
3221 for (pmport = 0; pmport < num_dev_ports-1; pmport++) {
3223 * Enable PHY by writing a 1, then a 0 to SControl
3224 * (i.e. PSCR[2]) DET field.
3226 if (si_read_portmult_reg(si_ctlp, si_portp, port, pmport,
3227 PSCR_REG2, &SControl)) {
3228 continue;
3231 /* First write a 1 to DET field of SControl. */
3232 SCONTROL_SET_DET(SControl, SCONTROL_DET_COMRESET);
3233 if (si_write_portmult_reg(si_ctlp, si_portp, port, pmport,
3234 PSCR_REG2, SControl)) {
3235 continue;
3237 #ifndef __lock_lint
3238 delay(SI_10MS_TICKS); /* give time for COMRESET to percolate */
3239 #endif /* __lock_lint */
3241 /* Then write a 0 to the DET field of SControl. */
3242 SCONTROL_SET_DET(SControl, SCONTROL_DET_NOACTION);
3243 if (si_write_portmult_reg(si_ctlp, si_portp, port, pmport,
3244 PSCR_REG2, SControl)) {
3245 continue;
3248 /* Wait for PHYRDY by polling SStatus (i.e. PSCR[0]). */
3249 loop_count = 0;
3250 do {
3251 if (si_read_portmult_reg(si_ctlp, si_portp, port,
3252 pmport, PSCR_REG0, &SStatus)) {
3253 break;
3255 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3256 "looping for PHYRDY: SStatus: %x",
3257 SStatus);
3259 if (SSTATUS_GET_IPM(SStatus) !=
3260 SSTATUS_IPM_INTERFACE_ACTIVE) {
3262 * If the interface is not active, the DET field
3263 * is considered not accurate. So we want to
3264 * continue looping.
3266 SSTATUS_SET_DET(SStatus,
3267 SSTATUS_DET_NODEV_NOPHY);
3270 if (loop_count++ > SI_POLLRATE_SSTATUS) {
3272 * We are effectively timing out after 0.1 sec.
3274 break;
3277 /* Wait for 10 millisec */
3278 #ifndef __lock_lint
3279 delay(SI_10MS_TICKS);
3280 #endif /* __lock_lint */
3282 } while (SSTATUS_GET_DET(SStatus) !=
3283 SSTATUS_DET_DEVPRESENT_PHYONLINE);
3285 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3286 "si_enumerate_port_multiplier: "
3287 "loop count: %d, SStatus: 0x%x",
3288 loop_count,
3289 SStatus);
3291 if ((SSTATUS_GET_IPM(SStatus) ==
3292 SSTATUS_IPM_INTERFACE_ACTIVE) &&
3293 (SSTATUS_GET_DET(SStatus) ==
3294 SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
3295 /* The interface is active and the device is present */
3296 SIDBG_P(SIDBG_INIT, si_portp,
3297 "Status: %x, device exists",
3298 SStatus);
3300 * Clear error bits in SError register (i.e. PSCR[1]
3301 * by writing back error bits.
3303 if (si_read_portmult_reg(si_ctlp, si_portp, port,
3304 pmport, PSCR_REG1, &SError)) {
3305 continue;
3307 SIDBG_P(SIDBG_INIT, si_portp,
3308 "SError bits are: %x", SError);
3309 if (si_write_portmult_reg(si_ctlp, si_portp, port,
3310 pmport, PSCR_REG1, SError)) {
3311 continue;
3314 /* There exists a device. */
3315 mutex_exit(&si_portp->siport_mutex);
3316 si_find_dev_signature(si_ctlp, si_portp, port, pmport);
3317 mutex_enter(&si_portp->siport_mutex);
3321 mutex_exit(&si_portp->siport_mutex);
3323 return (SI_SUCCESS);
3328 * Read a port multiplier register.
3330 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
3331 * before calling us.
3333 static int
3334 si_read_portmult_reg(
3335 si_ctl_state_t *si_ctlp,
3336 si_port_state_t *si_portp,
3337 int port,
3338 int pmport,
3339 int regnum,
3340 uint32_t *regval)
3342 int slot;
3343 si_prb_t *prb;
3344 uint32_t *prb_word_ptr;
3345 int i;
3346 uint32_t slot_status;
3347 int loop_count = 0;
3349 _NOTE(ASSUMING_PROTECTED(si_portp))
3351 SIDBG_P(SIDBG_ENTRY, si_portp, "si_read_portmult_reg: port: %x,"
3352 "pmport: %x, regnum: %x",
3353 port, pmport, regnum);
3355 slot = si_claim_free_slot(si_ctlp, si_portp, port);
3356 if (slot == SI_FAILURE) {
3357 return (SI_FAILURE);
3360 prb = &(si_portp->siport_prbpool[slot]);
3361 bzero((void *)prb, sizeof (si_prb_t));
3363 /* Now fill the prb. */
3364 SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
3365 SET_FIS_PMP(prb->prb_fis, PORTMULT_CONTROL_PORT);
3366 SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
3367 SET_FIS_COMMAND(prb->prb_fis, SATAC_READ_PM_REG);
3369 SET_FIS_DEV_HEAD(prb->prb_fis, pmport);
3370 SET_FIS_FEATURES(prb->prb_fis, regnum);
3372 /* no real data transfer is involved. */
3373 SET_SGE_TRM(prb->prb_sge0);
3375 #if SI_DEBUG
3376 if (si_debug_flags & SIDBG_DUMP_PRB) {
3377 int *ptr;
3378 int j;
3380 ptr = (int *)(void *)prb;
3381 cmn_err(CE_WARN, "read_port_mult_reg, prb: ");
3382 for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
3383 cmn_err(CE_WARN, "%x ", ptr[j]);
3387 #endif /* SI_DEBUG */
3389 /* Deliver PRB */
3390 POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
3392 /* Loop till the command is finished. */
3393 do {
3394 slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3395 (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
3397 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3398 "looping read_pm slot_status: 0x%x",
3399 slot_status);
3401 if (loop_count++ > SI_POLLRATE_SLOTSTATUS) {
3402 /* We are effectively timing out after 0.5 sec. */
3403 break;
3406 /* Wait for 10 millisec */
3407 #ifndef __lock_lint
3408 delay(SI_10MS_TICKS);
3409 #endif /* __lock_lint */
3411 } while (slot_status & SI_SLOT_MASK & (0x1 << slot));
3413 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3414 "read_portmult_reg: loop count: %d",
3415 loop_count);
3417 CLEAR_BIT(si_portp->siport_pending_tags, slot);
3419 /* Now inspect the port LRAM for the modified FIS. */
3420 prb_word_ptr = (uint32_t *)(void *)prb;
3421 for (i = 0; i < (sizeof (si_prb_t)/4); i++) {
3422 prb_word_ptr[i] = ddi_get32(si_ctlp->sictl_port_acc_handle,
3423 (uint32_t *)(PORT_LRAM(si_ctlp, port, slot)+i*4));
3426 if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
3427 si_check_port_handles(si_portp) != DDI_SUCCESS) {
3428 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3429 DDI_SERVICE_UNAFFECTED);
3430 return (SI_FAILURE);
3433 if (((GET_FIS_COMMAND(prb->prb_fis) & 0x1) != 0) ||
3434 (GET_FIS_FEATURES(prb->prb_fis) != 0)) {
3435 /* command failed. */
3436 return (SI_FAILURE);
3439 /* command succeeded. */
3440 *regval = (GET_FIS_SECTOR_COUNT(prb->prb_fis) & 0xff) |
3441 ((GET_FIS_SECTOR(prb->prb_fis) << 8) & 0xff00) |
3442 ((GET_FIS_CYL_LOW(prb->prb_fis) << 16) & 0xff0000) |
3443 ((GET_FIS_CYL_HI(prb->prb_fis) << 24) & 0xff000000);
3445 return (SI_SUCCESS);
3449 * Write a port multiplier register.
3451 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
3452 * before calling us.
3454 static int
3455 si_write_portmult_reg(
3456 si_ctl_state_t *si_ctlp,
3457 si_port_state_t *si_portp,
3458 int port,
3459 int pmport,
3460 int regnum,
3461 uint32_t regval)
3463 int slot;
3464 si_prb_t *prb;
3465 uint32_t *prb_word_ptr;
3466 uint32_t slot_status;
3467 int i;
3468 int loop_count = 0;
3470 _NOTE(ASSUMING_PROTECTED(si_portp))
3472 SIDBG_P(SIDBG_ENTRY, si_portp,
3473 "si_write_portmult_reg: port: %x, pmport: %x,"
3474 "regnum: %x, regval: %x",
3475 port, pmport, regnum, regval);
3477 slot = si_claim_free_slot(si_ctlp, si_portp, port);
3478 if (slot == SI_FAILURE) {
3479 return (SI_FAILURE);
3482 prb = &(si_portp->siport_prbpool[slot]);
3483 bzero((void *)prb, sizeof (si_prb_t));
3485 /* Now fill the prb. */
3486 SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
3487 SET_FIS_PMP(prb->prb_fis, PORTMULT_CONTROL_PORT);
3488 SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
3490 SET_FIS_COMMAND(prb->prb_fis, SATAC_WRITE_PM_REG);
3491 SET_FIS_DEV_HEAD(prb->prb_fis, pmport);
3492 SET_FIS_FEATURES(prb->prb_fis, regnum);
3494 SET_FIS_SECTOR_COUNT(prb->prb_fis, regval & 0xff);
3495 SET_FIS_SECTOR(prb->prb_fis, (regval >> 8) & 0xff);
3496 SET_FIS_CYL_LOW(prb->prb_fis, (regval >> 16) & 0xff);
3497 SET_FIS_CYL_HI(prb->prb_fis, (regval >> 24) & 0xff);
3499 /* no real data transfer is involved. */
3500 SET_SGE_TRM(prb->prb_sge0);
3502 #if SI_DEBUG
3503 if (si_debug_flags & SIDBG_DUMP_PRB) {
3504 int *ptr;
3505 int j;
3507 ptr = (int *)(void *)prb;
3508 cmn_err(CE_WARN, "read_port_mult_reg, prb: ");
3509 for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
3510 cmn_err(CE_WARN, "%x ", ptr[j]);
3514 #endif /* SI_DEBUG */
3516 /* Deliver PRB */
3517 POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
3519 /* Loop till the command is finished. */
3520 do {
3521 slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3522 (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
3524 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3525 "looping write_pmp slot_status: 0x%x",
3526 slot_status);
3528 if (loop_count++ > SI_POLLRATE_SLOTSTATUS) {
3529 /* We are effectively timing out after 0.5 sec. */
3530 break;
3533 /* Wait for 10 millisec */
3534 #ifndef __lock_lint
3535 delay(SI_10MS_TICKS);
3536 #endif /* __lock_lint */
3538 } while (slot_status & SI_SLOT_MASK & (0x1 << slot));
3540 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3541 "write_portmult_reg: loop count: %d",
3542 loop_count);
3544 CLEAR_BIT(si_portp->siport_pending_tags, slot);
3546 /* Now inspect the port LRAM for the modified FIS. */
3547 prb_word_ptr = (uint32_t *)(void *)prb;
3548 for (i = 0; i < (sizeof (si_prb_t)/4); i++) {
3549 prb_word_ptr[i] = ddi_get32(si_ctlp->sictl_port_acc_handle,
3550 (uint32_t *)(PORT_LRAM(si_ctlp, port, slot)+i*4));
3553 if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
3554 si_check_port_handles(si_portp) != DDI_SUCCESS) {
3555 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3556 DDI_SERVICE_UNAFFECTED);
3557 return (SI_FAILURE);
3560 if (((GET_FIS_COMMAND(prb->prb_fis) & 0x1) != 0) ||
3561 (GET_FIS_FEATURES(prb->prb_fis) != 0)) {
3562 /* command failed */
3563 return (SI_FAILURE);
3566 /* command succeeded */
3567 return (SI_SUCCESS);
3572 * Set the auto sense data for ATAPI devices.
3574 * Note: Currently the sense data is simulated; this code will be enhanced
3575 * in second phase to fetch the real sense data from the atapi device.
3577 static void
3578 si_set_sense_data(sata_pkt_t *satapkt, int reason)
3580 struct scsi_extended_sense *sense;
3582 sense = (struct scsi_extended_sense *)
3583 satapkt->satapkt_cmd.satacmd_rqsense;
3584 bzero(sense, sizeof (struct scsi_extended_sense));
3585 sense->es_valid = 1; /* Valid sense */
3586 sense->es_class = 7; /* Response code 0x70 - current err */
3587 sense->es_key = 0;
3588 sense->es_info_1 = 0;
3589 sense->es_info_2 = 0;
3590 sense->es_info_3 = 0;
3591 sense->es_info_4 = 0;
3592 sense->es_add_len = 6; /* Additional length */
3593 sense->es_cmd_info[0] = 0;
3594 sense->es_cmd_info[1] = 0;
3595 sense->es_cmd_info[2] = 0;
3596 sense->es_cmd_info[3] = 0;
3597 sense->es_add_code = 0;
3598 sense->es_qual_code = 0;
3600 if ((reason == SATA_PKT_DEV_ERROR) || (reason == SATA_PKT_TIMEOUT)) {
3601 sense->es_key = KEY_HARDWARE_ERROR;
3607 * Interrupt service handler. We loop through each of the ports to find
3608 * if the interrupt belongs to any of them.
3610 * Bulk of the interrupt handling is actually done out of subroutines
3611 * like si_intr_command_complete() etc.
3613 /*ARGSUSED*/
3614 static uint_t
3615 si_intr(caddr_t arg1, caddr_t arg2)
3617 si_ctl_state_t *si_ctlp = (si_ctl_state_t *)(void *)arg1;
3618 si_port_state_t *si_portp;
3619 uint32_t global_intr_status;
3620 uint32_t mask, port_intr_status;
3621 int port;
3623 global_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
3624 (uint32_t *)GLOBAL_INTERRUPT_STATUS(si_ctlp));
3626 SIDBG_C(SIDBG_INTR, si_ctlp,
3627 "si_intr: global_int_status: 0x%x",
3628 global_intr_status);
3630 if (si_check_acc_handle(si_ctlp->sictl_global_acc_handle) !=
3631 DDI_SUCCESS) {
3632 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3633 DDI_SERVICE_UNAFFECTED);
3634 return (DDI_INTR_UNCLAIMED);
3637 if (!(global_intr_status & SI31xx_INTR_PORT_MASK)) {
3638 /* Sorry, the interrupt is not ours. */
3639 return (DDI_INTR_UNCLAIMED);
3642 /* Loop for all the ports. */
3643 for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
3645 mask = 0x1 << port;
3646 if (!(global_intr_status & mask)) {
3647 continue;
3650 mutex_enter(&si_ctlp->sictl_mutex);
3651 si_portp = si_ctlp->sictl_ports[port];
3652 mutex_exit(&si_ctlp->sictl_mutex);
3654 port_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
3655 (uint32_t *)PORT_INTERRUPT_STATUS(si_ctlp, port));
3657 SIDBG_P(SIDBG_VERBOSE, si_portp,
3658 "s_intr: port_intr_status: 0x%x, port: %x",
3659 port_intr_status,
3660 port);
3662 if (port_intr_status & INTR_COMMAND_COMPLETE) {
3663 (void) si_intr_command_complete(si_ctlp, si_portp,
3664 port);
3666 mutex_enter(&si_portp->siport_mutex);
3667 if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
3668 si_check_port_handles(si_portp) != DDI_SUCCESS) {
3669 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3670 DDI_SERVICE_UNAFFECTED);
3671 si_schedule_port_initialize(si_ctlp, si_portp,
3672 port);
3674 mutex_exit(&si_portp->siport_mutex);
3675 } else {
3676 /* Clear the interrupts */
3677 ddi_put32(si_ctlp->sictl_port_acc_handle,
3678 (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp, port)),
3679 port_intr_status & INTR_MASK);
3683 * Note that we did not clear the interrupt for command
3684 * completion interrupt. Reading of slot_status takes care
3685 * of clearing the interrupt for command completion case.
3688 if (port_intr_status & INTR_COMMAND_ERROR) {
3689 si_schedule_intr_command_error(si_ctlp, si_portp, port);
3692 if (port_intr_status & INTR_PORT_READY) {
3693 (void) si_intr_port_ready(si_ctlp, si_portp, port);
3696 if (port_intr_status & INTR_POWER_CHANGE) {
3697 (void) si_intr_pwr_change(si_ctlp, si_portp, port);
3700 if (port_intr_status & INTR_PHYRDY_CHANGE) {
3701 (void) si_intr_phy_ready_change(si_ctlp, si_portp,
3702 port);
3705 if (port_intr_status & INTR_COMWAKE_RECEIVED) {
3706 (void) si_intr_comwake_rcvd(si_ctlp, si_portp,
3707 port);
3710 if (port_intr_status & INTR_UNRECOG_FIS) {
3711 (void) si_intr_unrecognised_fis(si_ctlp, si_portp,
3712 port);
3715 if (port_intr_status & INTR_DEV_XCHANGED) {
3716 (void) si_intr_dev_xchanged(si_ctlp, si_portp, port);
3719 if (port_intr_status & INTR_8B10B_DECODE_ERROR) {
3720 (void) si_intr_decode_err_threshold(si_ctlp, si_portp,
3721 port);
3724 if (port_intr_status & INTR_CRC_ERROR) {
3725 (void) si_intr_crc_err_threshold(si_ctlp, si_portp,
3726 port);
3729 if (port_intr_status & INTR_HANDSHAKE_ERROR) {
3730 (void) si_intr_handshake_err_threshold(si_ctlp,
3731 si_portp, port);
3734 if (port_intr_status & INTR_SETDEVBITS_NOTIFY) {
3735 (void) si_intr_set_devbits_notify(si_ctlp, si_portp,
3736 port);
3740 return (DDI_INTR_CLAIMED);
3744 * Interrupt which indicates that one or more commands have successfully
3745 * completed.
3747 * Since we disabled W1C (write-one-to-clear) previously, mere reading
3748 * of slot_status register clears the interrupt. There is no need to
3749 * explicitly clear the interrupt.
3751 static int
3752 si_intr_command_complete(
3753 si_ctl_state_t *si_ctlp,
3754 si_port_state_t *si_portp,
3755 int port)
3758 uint32_t slot_status;
3759 uint32_t finished_tags;
3760 int finished_slot;
3761 sata_pkt_t *satapkt;
3763 SIDBG_P(SIDBG_INTR, si_portp,
3764 "si_intr_command_complete enter", NULL);
3766 mutex_enter(&si_portp->siport_mutex);
3768 slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3769 (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
3771 if (!si_portp->siport_pending_tags) {
3773 * Spurious interrupt. Nothing to be done.
3774 * The interrupt was cleared when slot_status was read.
3776 mutex_exit(&si_portp->siport_mutex);
3777 return (SI_SUCCESS);
3780 SIDBG_P(SIDBG_VERBOSE, si_portp, "si3124: si_intr_command_complete: "
3781 "pending_tags: %x, slot_status: %x",
3782 si_portp->siport_pending_tags,
3783 slot_status);
3785 finished_tags = si_portp->siport_pending_tags &
3786 ~slot_status & SI_SLOT_MASK;
3787 while (finished_tags) {
3789 finished_slot = ddi_ffs(finished_tags) - 1;
3790 if (finished_slot == -1) {
3791 break;
3794 satapkt = si_portp->siport_slot_pkts[finished_slot];
3796 if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
3797 si_copy_out_regs(&satapkt->satapkt_cmd, si_ctlp, port,
3798 finished_slot);
3801 CLEAR_BIT(si_portp->siport_pending_tags, finished_slot);
3802 CLEAR_BIT(finished_tags, finished_slot);
3803 SENDUP_PACKET(si_portp, satapkt, SATA_PKT_COMPLETED);
3806 SIDBG_P(SIDBG_PKTCOMP, si_portp,
3807 "command_complete done: pend_tags: 0x%x, slot_status: 0x%x",
3808 si_portp->siport_pending_tags,
3809 slot_status);
3812 * tidbit: no need to clear the interrupt since reading of
3813 * slot_status automatically clears the interrupt in the case
3814 * of a successful command completion.
3817 mutex_exit(&si_portp->siport_mutex);
3819 return (SI_SUCCESS);
3823 * Schedule a call to si_intr_command_error using a timeout to get it done
3824 * off the interrupt thread.
3826 static void
3827 si_schedule_intr_command_error(
3828 si_ctl_state_t *si_ctlp,
3829 si_port_state_t *si_portp,
3830 int port)
3832 si_event_arg_t *args;
3834 mutex_enter(&si_portp->siport_mutex);
3836 args = si_portp->siport_event_args;
3837 if (args->siea_ctlp != NULL) {
3838 cmn_err(CE_WARN, "si_schedule_intr_command_error: "
3839 "args->si_ctlp != NULL");
3840 mutex_exit(&si_portp->siport_mutex);
3841 return;
3844 args->siea_ctlp = si_ctlp;
3845 args->siea_port = port;
3847 (void) timeout(si_do_intr_command_error, si_portp, 1);
3849 mutex_exit(&si_portp->siport_mutex);
3853 * Called from timeout()
3854 * Unpack the arguments and call si_intr_command_error()
3856 static void
3857 si_do_intr_command_error(void *arg)
3859 si_event_arg_t *args;
3860 si_ctl_state_t *si_ctlp;
3861 si_port_state_t *si_portp;
3862 int port;
3864 si_portp = arg;
3865 mutex_enter(&si_portp->siport_mutex);
3867 args = si_portp->siport_event_args;
3868 si_ctlp = args->siea_ctlp;
3869 port = args->siea_port;
3870 args->siea_ctlp = NULL; /* mark siport_event_args as free */
3872 mutex_exit(&si_portp->siport_mutex);
3873 (void) si_intr_command_error(si_ctlp, si_portp, port);
3877 * Interrupt which indicates that a command did not complete successfully.
3879 * The port halts whenever a command error interrupt is received.
3880 * The only way to restart it is to reset or reinitialize the port
3881 * but such an operation throws away all the pending commands on
3882 * the port.
3884 * We reset the device and mop the commands on the port.
3886 static int
3887 si_intr_command_error(
3888 si_ctl_state_t *si_ctlp,
3889 si_port_state_t *si_portp,
3890 int port)
3892 uint32_t command_error, slot_status;
3893 uint32_t failed_tags;
3895 command_error = ddi_get32(si_ctlp->sictl_port_acc_handle,
3896 (uint32_t *)(PORT_COMMAND_ERROR(si_ctlp, port)));
3898 SIDBG_P(SIDBG_ERRS, si_portp,
3899 "si_intr_command_error: command_error: 0x%x",
3900 command_error);
3902 mutex_enter(&si_portp->siport_mutex);
3905 * Remember the slot_status since any of the recovery handler
3906 * can blow it away with reset operation.
3908 slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3909 (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
3911 si_log_error_message(si_ctlp, port, command_error);
3913 switch (command_error) {
3915 case CMD_ERR_DEVICEERRROR:
3916 si_error_recovery_DEVICEERROR(si_ctlp, si_portp, port);
3917 break;
3919 case CMD_ERR_SDBERROR:
3920 si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR, "SBD error");
3921 si_error_recovery_SDBERROR(si_ctlp, si_portp, port);
3922 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3923 DDI_SERVICE_UNAFFECTED);
3924 break;
3926 case CMD_ERR_DATAFISERROR:
3927 si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR,
3928 "Data FIS error");
3929 si_error_recovery_DATAFISERROR(si_ctlp, si_portp, port);
3930 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3931 DDI_SERVICE_UNAFFECTED);
3932 break;
3934 case CMD_ERR_SENDFISERROR:
3935 si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR,
3936 "Send FIS error");
3937 si_error_recovery_SENDFISERROR(si_ctlp, si_portp, port);
3938 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3939 DDI_SERVICE_UNAFFECTED);
3940 break;
3942 default:
3943 si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR,
3944 "Unknown error");
3945 si_error_recovery_default(si_ctlp, si_portp, port);
3946 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3947 DDI_SERVICE_UNAFFECTED);
3948 break;
3953 * Compute the failed_tags by adding up the error tags.
3955 * The siport_err_tags_SDBERROR and siport_err_tags_nonSDBERROR
3956 * were filled in by the si_error_recovery_* routines.
3958 failed_tags = si_portp->siport_pending_tags &
3959 (si_portp->siport_err_tags_SDBERROR |
3960 si_portp->siport_err_tags_nonSDBERROR);
3962 SIDBG_P(SIDBG_ERRS, si_portp, "si_intr_command_error: "
3963 "err_tags_SDBERROR: 0x%x, "
3964 "err_tags_nonSDBERRROR: 0x%x, "
3965 "failed_tags: 0x%x",
3966 si_portp->siport_err_tags_SDBERROR,
3967 si_portp->siport_err_tags_nonSDBERROR,
3968 failed_tags);
3970 SIDBG_P(SIDBG_ERRS, si_portp,
3971 "si3124: si_intr_command_error: "
3972 "slot_status:0x%x, pending_tags: 0x%x",
3973 slot_status,
3974 si_portp->siport_pending_tags);
3976 si_portp->mopping_in_progress++;
3978 si_mop_commands(si_ctlp,
3979 si_portp,
3980 port,
3981 slot_status,
3982 failed_tags,
3983 0, /* timedout_tags */
3984 0, /* aborting_tags */
3985 0); /* reset_tags */
3987 ASSERT(si_portp->siport_pending_tags == 0);
3989 si_portp->siport_err_tags_SDBERROR = 0;
3990 si_portp->siport_err_tags_nonSDBERROR = 0;
3992 mutex_exit(&si_portp->siport_mutex);
3994 return (SI_SUCCESS);
3998 * There is a subtle difference between errors on a normal port and
3999 * a port-mult port. When an error happens on a normal port, the port
4000 * is halted effectively until the port is reset or initialized.
4001 * However, in port-mult port errors, port does not get halted since
4002 * other non-error devices behind the port multiplier can still
4003 * continue to operate. So we wait till all the commands are drained
4004 * instead of resetting it right away.
4006 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4007 * before calling us.
4009 static void
4010 si_recover_portmult_errors(
4011 si_ctl_state_t *si_ctlp,
4012 si_port_state_t *si_portp,
4013 int port)
4015 uint32_t command_error, slot_status, port_status;
4016 int failed_slot;
4017 int loop_count = 0;
4019 _NOTE(ASSUMING_PROTECTED(si_portp))
4021 SIDBG_P(SIDBG_ERRS, si_portp,
4022 "si_recover_portmult_errors: port: 0x%x",
4023 port);
4025 /* Resume the port */
4026 ddi_put32(si_ctlp->sictl_port_acc_handle,
4027 (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
4028 PORT_CONTROL_SET_BITS_RESUME);
4030 port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4031 (uint32_t *)PORT_STATUS(si_ctlp, port));
4033 failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4034 command_error = ddi_get32(si_ctlp->sictl_port_acc_handle,
4035 (uint32_t *)(PORT_COMMAND_ERROR(si_ctlp, port)));
4037 if (command_error == CMD_ERR_SDBERROR) {
4038 si_portp->siport_err_tags_SDBERROR |= (0x1 << failed_slot);
4039 } else {
4040 si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4043 /* Now we drain the pending commands. */
4044 do {
4045 slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4046 (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
4049 * Since we have not yet returned DDI_INTR_CLAIMED,
4050 * our interrupt handler is guaranteed not to be called again.
4051 * So we need to check IS_ATTENTION_RAISED() for further
4052 * decisions.
4054 * This is a too big a delay for an interrupt context.
4055 * But this is supposed to be a rare condition.
4058 if (IS_ATTENTION_RAISED(slot_status)) {
4059 /* Resume again */
4060 ddi_put32(si_ctlp->sictl_port_acc_handle,
4061 (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
4062 PORT_CONTROL_SET_BITS_RESUME);
4064 port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4065 (uint32_t *)PORT_STATUS(si_ctlp, port));
4066 failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4067 command_error = ddi_get32(
4068 si_ctlp->sictl_port_acc_handle,
4069 (uint32_t *)(PORT_COMMAND_ERROR(si_ctlp,
4070 port)));
4071 if (command_error == CMD_ERR_SDBERROR) {
4072 si_portp->siport_err_tags_SDBERROR |=
4073 (0x1 << failed_slot);
4074 } else {
4075 si_portp->siport_err_tags_nonSDBERROR |=
4076 (0x1 << failed_slot);
4080 if (loop_count++ > SI_POLLRATE_RECOVERPORTMULT) {
4081 /* We are effectively timing out after 10 sec. */
4082 break;
4085 /* Wait for 10 millisec */
4086 #ifndef __lock_lint
4087 delay(SI_10MS_TICKS);
4088 #endif /* __lock_lint */
4090 } while (slot_status & SI_SLOT_MASK);
4093 * The above loop can be improved for 3132 since we could obtain the
4094 * Port Multiplier Context of the device in error. Then we could
4095 * do a better job in filtering out commands for the device in error.
4096 * The loop could finish much earlier with such a logic.
4099 /* Clear the RESUME bit. */
4100 ddi_put32(si_ctlp->sictl_port_acc_handle,
4101 (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
4102 PORT_CONTROL_CLEAR_BITS_RESUME);
4107 * If we are connected to port multiplier, drain the non-failed devices.
4108 * Otherwise, we initialize the port (which effectively fails all the
4109 * pending commands in the hope that sd would retry them later).
4111 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4112 * before calling us.
4114 static void
4115 si_error_recovery_DEVICEERROR(
4116 si_ctl_state_t *si_ctlp,
4117 si_port_state_t *si_portp,
4118 int port)
4120 uint32_t port_status;
4121 int failed_slot;
4123 _NOTE(ASSUMING_PROTECTED(si_portp))
4125 SIDBG_P(SIDBG_ERRS, si_portp,
4126 "si_error_recovery_DEVICEERROR: port: 0x%x",
4127 port);
4129 if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
4130 si_recover_portmult_errors(si_ctlp, si_portp, port);
4131 } else {
4132 port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4133 (uint32_t *)PORT_STATUS(si_ctlp, port));
4134 failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4135 si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4138 /* In either case (port-mult or not), we reinitialize the port. */
4139 (void) si_initialize_port_wait_till_ready(si_ctlp, port);
4143 * Handle exactly like DEVICEERROR. Remember the tags with SDBERROR
4144 * to perform read_log_ext on them later. SDBERROR means that the
4145 * error was for an NCQ command.
4147 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4148 * before calling us.
4150 static void
4151 si_error_recovery_SDBERROR(
4152 si_ctl_state_t *si_ctlp,
4153 si_port_state_t *si_portp,
4154 int port)
4156 uint32_t port_status;
4157 int failed_slot;
4159 _NOTE(ASSUMING_PROTECTED(si_portp))
4161 SIDBG_P(SIDBG_ERRS, si_portp,
4162 "si3124: si_error_recovery_SDBERROR: port: 0x%x",
4163 port);
4165 if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
4166 si_recover_portmult_errors(si_ctlp, si_portp, port);
4167 } else {
4168 port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4169 (uint32_t *)PORT_STATUS(si_ctlp, port));
4170 failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4171 si_portp->siport_err_tags_SDBERROR |= (0x1 << failed_slot);
4174 /* In either case (port-mult or not), we reinitialize the port. */
4175 (void) si_initialize_port_wait_till_ready(si_ctlp, port);
4179 * Handle exactly like DEVICEERROR except resetting the port if there was
4180 * an NCQ command on the port.
4182 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4183 * before calling us.
4185 static void
4186 si_error_recovery_DATAFISERROR(
4187 si_ctl_state_t *si_ctlp,
4188 si_port_state_t *si_portp,
4189 int port)
4191 uint32_t port_status;
4192 int failed_slot;
4194 _NOTE(ASSUMING_PROTECTED(si_portp))
4196 SIDBG_P(SIDBG_ERRS, si_portp,
4197 "si3124: si_error_recovery_DATAFISERROR: port: 0x%x",
4198 port);
4200 /* reset device if we were waiting for any ncq commands. */
4201 if (si_portp->siport_pending_ncq_count) {
4202 port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4203 (uint32_t *)PORT_STATUS(si_ctlp, port));
4204 failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4205 si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4206 (void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
4207 SI_DEVICE_RESET);
4208 return;
4212 * If we don't have any ncq commands pending, the rest of
4213 * the process is similar to the one for DEVICEERROR.
4215 si_error_recovery_DEVICEERROR(si_ctlp, si_portp, port);
4219 * We handle just like DEVICERROR except that we reset the device instead
4220 * of initializing the port.
4222 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4223 * before calling us.
4225 static void
4226 si_error_recovery_SENDFISERROR(
4227 si_ctl_state_t *si_ctlp,
4228 si_port_state_t *si_portp,
4229 int port)
4231 uint32_t port_status;
4232 int failed_slot;
4234 _NOTE(ASSUMING_PROTECTED(si_portp))
4236 SIDBG_P(SIDBG_ERRS, si_portp,
4237 "si3124: si_error_recovery_SENDFISERROR: port: 0x%x",
4238 port);
4240 if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
4241 si_recover_portmult_errors(si_ctlp, si_portp, port);
4242 } else {
4243 port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4244 (uint32_t *)PORT_STATUS(si_ctlp, port));
4245 failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4246 si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4247 (void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
4248 SI_DEVICE_RESET);
4253 * The default behavior for all other errors is to reset the device.
4255 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4256 * before calling us.
4258 static void
4259 si_error_recovery_default(
4260 si_ctl_state_t *si_ctlp,
4261 si_port_state_t *si_portp,
4262 int port)
4264 uint32_t port_status;
4265 int failed_slot;
4267 _NOTE(ASSUMING_PROTECTED(si_portp))
4269 SIDBG_P(SIDBG_ERRS, si_portp,
4270 "si3124: si_error_recovery_default: port: 0x%x",
4271 port);
4273 port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4274 (uint32_t *)PORT_STATUS(si_ctlp, port));
4275 failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4276 si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4278 (void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
4279 SI_DEVICE_RESET);
4283 * Read Log Ext with PAGE 10 to retrieve the error for an NCQ command.
4285 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4286 * before calling us.
4288 static uint8_t
4289 si_read_log_ext(si_ctl_state_t *si_ctlp, si_port_state_t *si_portp, int port)
4291 int slot;
4292 si_prb_t *prb;
4293 int i;
4294 uint32_t slot_status;
4295 int loop_count = 0;
4296 uint32_t *prb_word_ptr;
4297 uint8_t error;
4299 _NOTE(ASSUMING_PROTECTED(si_portp))
4301 SIDBG_P(SIDBG_ERRS, si_portp,
4302 "si_read_log_ext: port: %x", port);
4304 slot = si_claim_free_slot(si_ctlp, si_portp, port);
4305 if (slot == SI_FAILURE) {
4306 return (0);
4309 prb = &(si_portp->siport_prbpool[slot]);
4310 bzero((void *)prb, sizeof (si_prb_t));
4312 /* Now fill the prb */
4313 SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
4314 SET_FIS_PMP(prb->prb_fis, PORTMULT_CONTROL_PORT);
4315 SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
4316 SET_FIS_COMMAND(prb->prb_fis, SATAC_READ_LOG_EXT);
4317 SET_FIS_SECTOR(prb->prb_fis, SATA_LOG_PAGE_10);
4319 /* no real data transfer is involved */
4320 SET_SGE_TRM(prb->prb_sge0);
4322 #if SI_DEBUG
4323 if (si_debug_flags & SIDBG_DUMP_PRB) {
4324 int *ptr;
4325 int j;
4327 ptr = (int *)(void *)prb;
4328 cmn_err(CE_WARN, "read_port_mult_reg, prb: ");
4329 for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
4330 cmn_err(CE_WARN, "%x ", ptr[j]);
4334 #endif /* SI_DEBUG */
4336 /* Deliver PRB */
4337 POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
4339 /* Loop till the command is finished. */
4340 do {
4341 slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4342 (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
4344 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
4345 "looping read_log_ext slot_status: 0x%x",
4346 slot_status);
4348 if (loop_count++ > SI_POLLRATE_SLOTSTATUS) {
4349 /* We are effectively timing out after 0.5 sec. */
4350 break;
4353 /* Wait for 10 millisec */
4354 #ifndef __lock_lint
4355 delay(SI_10MS_TICKS);
4356 #endif /* __lock_lint */
4358 } while (slot_status & SI_SLOT_MASK & (0x1 << slot));
4360 if (slot_status & SI_SLOT_MASK & (0x1 << slot)) {
4362 * If we fail with the READ LOG EXT command, we need to
4363 * initialize the port to clear the slot_status register.
4364 * We don't need to worry about any other valid commands
4365 * being thrown away because we are already in recovery
4366 * mode and READ LOG EXT is the only pending command.
4368 (void) si_initialize_port_wait_till_ready(si_ctlp, port);
4371 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
4372 "read_portmult_reg: loop count: %d",
4373 loop_count);
4376 * The LRAM contains the the modified FIS.
4377 * Read the modified FIS to obtain the Error.
4379 prb_word_ptr = (uint32_t *)(void *)prb;
4380 for (i = 0; i < (sizeof (si_prb_t)/4); i++) {
4381 prb_word_ptr[i] = ddi_get32(si_ctlp->sictl_port_acc_handle,
4382 (uint32_t *)(PORT_LRAM(si_ctlp, port, slot)+i*4));
4385 if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
4386 si_check_port_handles(si_portp) != DDI_SUCCESS) {
4387 ddi_fm_service_impact(si_ctlp->sictl_devinfop,
4388 DDI_SERVICE_UNAFFECTED);
4391 error = GET_FIS_FEATURES(prb->prb_fis);
4393 CLEAR_BIT(si_portp->siport_pending_tags, slot);
4395 return (error);
4400 * Dump the error message to the log.
4402 static void
4403 si_log_error_message(si_ctl_state_t *si_ctlp, int port, uint32_t command_error)
4405 #if SI_DEBUG
4406 #ifndef __lock_lint
4407 _NOTE(ARGUNUSED(si_ctlp))
4408 _NOTE(ARGUNUSED(port))
4409 #endif /* __lock_lint */
4411 char *errstr;
4412 si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
4414 switch (command_error) {
4416 case CMD_ERR_DEVICEERRROR:
4417 errstr = "Standard Error: Error bit set in register - device"
4418 " to host FIS";
4419 break;
4421 case CMD_ERR_SDBERROR:
4422 errstr = "NCQ Error: Error bit set in register - device"
4423 " to host FIS";
4424 break;
4426 case CMD_ERR_DATAFISERROR:
4427 errstr = "Error in data FIS not detected by device";
4428 break;
4430 case CMD_ERR_SENDFISERROR:
4431 errstr = "Initial command FIS transmission failed";
4432 break;
4434 case CMD_ERR_INCONSISTENTSTATE:
4435 errstr = "Inconsistency in protocol";
4436 break;
4438 case CMD_ERR_DIRECTIONERROR:
4439 errstr = "DMA direction flag does not match the command";
4440 break;
4442 case CMD_ERR_UNDERRUNERROR:
4443 errstr = "Run out of scatter gather entries while writing data";
4444 break;
4446 case CMD_ERR_OVERRUNERROR:
4447 errstr = "Run out of scatter gather entries while reading data";
4448 break;
4450 case CMD_ERR_PACKETPROTOCOLERROR:
4451 errstr = "Packet protocol error";
4452 break;
4454 case CMD_ERR_PLDSGTERRORBOUNDARY:
4455 errstr = "Scatter/gather table not on quadword boundary";
4456 break;
4458 case CMD_ERR_PLDSGTERRORTARETABORT:
4459 errstr = "PCI(X) Target abort while fetching scatter/gather"
4460 " table";
4461 break;
4463 case CMD_ERR_PLDSGTERRORMASTERABORT:
4464 errstr = "PCI(X) Master abort while fetching scatter/gather"
4465 " table";
4466 break;
4468 case CMD_ERR_PLDSGTERRORPCIERR:
4469 errstr = "PCI(X) parity error while fetching scatter/gather"
4470 " table";
4471 break;
4473 case CMD_ERR_PLDCMDERRORBOUNDARY:
4474 errstr = "PRB not on quadword boundary";
4475 break;
4477 case CMD_ERR_PLDCMDERRORTARGETABORT:
4478 errstr = "PCI(X) Target abort while fetching PRB";
4479 break;
4481 case CMD_ERR_PLDCMDERRORMASTERABORT:
4482 errstr = "PCI(X) Master abort while fetching PRB";
4483 break;
4485 case CMD_ERR_PLDCMDERORPCIERR:
4486 errstr = "PCI(X) parity error while fetching PRB";
4487 break;
4489 case CMD_ERR_PSDERRORTARGETABORT:
4490 errstr = "PCI(X) Target abort during data transfer";
4491 break;
4493 case CMD_ERR_PSDERRORMASTERABORT:
4494 errstr = "PCI(X) Master abort during data transfer";
4495 break;
4497 case CMD_ERR_PSDERRORPCIERR:
4498 errstr = "PCI(X) parity error during data transfer";
4499 break;
4501 case CMD_ERR_SENDSERVICEERROR:
4502 errstr = "FIS received while sending service FIS in"
4503 " legacy queuing operation";
4504 break;
4506 default:
4507 errstr = "Unknown Error";
4508 break;
4512 SIDBG_P(SIDBG_ERRS, si_portp,
4513 "command error: error: %s",
4514 errstr);
4515 #else
4516 #ifndef __lock_lint
4517 _NOTE(ARGUNUSED(si_ctlp))
4518 _NOTE(ARGUNUSED(port))
4519 _NOTE(ARGUNUSED(command_error))
4520 #endif /* __lock_lint */
4522 #endif /* SI_DEBUG */
4527 * Interrupt which indicates that the Port Ready state has changed
4528 * from zero to one.
4530 * We are not interested in this interrupt; we just log a debug message.
4532 /*ARGSUSED*/
4533 static int
4534 si_intr_port_ready(
4535 si_ctl_state_t *si_ctlp,
4536 si_port_state_t *si_portp,
4537 int port)
4539 SIDBG_P(SIDBG_INTR, si_portp, "si_intr_ready", NULL);
4540 return (SI_SUCCESS);
4544 * Interrupt which indicates that the port power management state
4545 * has been modified.
4547 * We are not interested in this interrupt; we just log a debug message.
4549 /*ARGSUSED*/
4550 static int
4551 si_intr_pwr_change(
4552 si_ctl_state_t *si_ctlp,
4553 si_port_state_t *si_portp,
4554 int port)
4556 SIDBG_P(SIDBG_INTR, si_portp, "si_intr_pwr_change", NULL);
4557 return (SI_SUCCESS);
4561 * Interrupt which indicates that the PHY state has changed either from
4562 * Not-Ready to Ready or from Ready to Not-Ready.
4564 static int
4565 si_intr_phy_ready_change(
4566 si_ctl_state_t *si_ctlp,
4567 si_port_state_t *si_portp,
4568 int port)
4570 sata_device_t sdevice;
4571 uint32_t SStatus = 0; /* No dev present & PHY not established. */
4572 int dev_exists_now = 0;
4573 int dev_existed_previously = 0;
4575 SIDBG_P(SIDBG_INTR, si_portp,
4576 "si_intr_phy_rdy_change", NULL);
4578 mutex_enter(&si_ctlp->sictl_mutex);
4579 if ((si_ctlp->sictl_sata_hba_tran == NULL) || (si_portp == NULL)) {
4580 /* the whole controller setup is not yet done. */
4581 mutex_exit(&si_ctlp->sictl_mutex);
4582 return (SI_SUCCESS);
4585 mutex_exit(&si_ctlp->sictl_mutex);
4587 mutex_enter(&si_portp->siport_mutex);
4589 /* SStatus tells the presence of device. */
4590 SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
4591 (uint32_t *)PORT_SSTATUS(si_ctlp, port));
4592 dev_exists_now =
4593 (SSTATUS_GET_DET(SStatus) == SSTATUS_DET_DEVPRESENT_PHYONLINE);
4595 if (si_portp->siport_port_type != PORT_TYPE_NODEV) {
4596 dev_existed_previously = 1;
4599 bzero((void *)&sdevice, sizeof (sata_device_t));
4601 sdevice.satadev_addr.cport = (uint8_t)port;
4602 sdevice.satadev_addr.pmport = PORTMULT_CONTROL_PORT;
4604 /* we don't have a way of determining the exact port-mult port. */
4605 if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
4606 sdevice.satadev_addr.qual = SATA_ADDR_PMPORT;
4607 } else {
4608 sdevice.satadev_addr.qual = SATA_ADDR_CPORT;
4611 sdevice.satadev_state = SATA_STATE_READY; /* port state */
4613 if (dev_exists_now) {
4614 if (dev_existed_previously) {
4616 /* Things are fine now. The loss was temporary. */
4617 SIDBG_P(SIDBG_INTR, si_portp,
4618 "phyrdy: doing BOTH EVENTS TOGETHER", NULL);
4619 if (si_portp->siport_active) {
4620 SIDBG_P(SIDBG_EVENT, si_portp,
4621 "sending event: LINK_LOST & "
4622 "LINK_ESTABLISHED", NULL);
4624 sata_hba_event_notify(
4625 si_ctlp->sictl_sata_hba_tran->\
4626 sata_tran_hba_dip,
4627 &sdevice,
4628 SATA_EVNT_LINK_LOST|
4629 SATA_EVNT_LINK_ESTABLISHED);
4632 } else {
4634 /* A new device has been detected. */
4635 mutex_exit(&si_portp->siport_mutex);
4636 si_find_dev_signature(si_ctlp, si_portp, port,
4637 PORTMULT_CONTROL_PORT);
4638 mutex_enter(&si_portp->siport_mutex);
4639 SIDBG_P(SIDBG_INTR, si_portp,
4640 "phyrdy: doing ATTACH event", NULL);
4641 if (si_portp->siport_active) {
4642 SIDBG_P(SIDBG_EVENT, si_portp,
4643 "sending event up: LINK_ESTABLISHED", NULL);
4645 sata_hba_event_notify(
4646 si_ctlp->sictl_sata_hba_tran->\
4647 sata_tran_hba_dip,
4648 &sdevice,
4649 SATA_EVNT_LINK_ESTABLISHED);
4653 } else { /* No device exists now */
4655 if (dev_existed_previously) {
4657 /* An existing device is lost. */
4658 if (si_portp->siport_active) {
4659 SIDBG_P(SIDBG_EVENT, si_portp,
4660 "sending event up: LINK_LOST", NULL);
4662 sata_hba_event_notify(
4663 si_ctlp->sictl_sata_hba_tran->
4664 sata_tran_hba_dip,
4665 &sdevice,
4666 SATA_EVNT_LINK_LOST);
4668 si_portp->siport_port_type = PORT_TYPE_NODEV;
4670 } else {
4672 /* spurious interrupt */
4673 SIDBG_P(SIDBG_INTR, si_portp,
4674 "spurious phy ready interrupt", NULL);
4678 mutex_exit(&si_portp->siport_mutex);
4679 return (SI_SUCCESS);
4684 * Interrupt which indicates that a COMWAKE OOB signal has been decoded
4685 * on the receiver.
4687 * We are not interested in this interrupt; we just log a debug message.
4689 /*ARGSUSED*/
4690 static int
4691 si_intr_comwake_rcvd(
4692 si_ctl_state_t *si_ctlp,
4693 si_port_state_t *si_portp,
4694 int port)
4696 SIDBG_P(SIDBG_INTR, si_portp,
4697 "si_intr_commwake_rcvd", NULL);
4698 return (SI_SUCCESS);
4702 * Interrupt which indicates that the F-bit has been set in SError
4703 * Diag field.
4705 * We are not interested in this interrupt; we just log a debug message.
4707 /*ARGSUSED*/
4708 static int
4709 si_intr_unrecognised_fis(
4710 si_ctl_state_t *si_ctlp,
4711 si_port_state_t *si_portp,
4712 int port)
4714 SIDBG_P(SIDBG_INTR, si_portp,
4715 "si_intr_unrecognised_fis", NULL);
4716 return (SI_SUCCESS);
4720 * Interrupt which indicates that the X-bit has been set in SError
4721 * Diag field.
4723 * We are not interested in this interrupt; we just log a debug message.
4725 /*ARGSUSED*/
4726 static int
4727 si_intr_dev_xchanged(
4728 si_ctl_state_t *si_ctlp,
4729 si_port_state_t *si_portp,
4730 int port)
4733 SIDBG_P(SIDBG_INTR, si_portp,
4734 "si_intr_dev_xchanged", NULL);
4735 return (SI_SUCCESS);
4739 * Interrupt which indicates that the 8b/10b Decode Error counter has
4740 * exceeded the programmed non-zero threshold value.
4742 * We are not interested in this interrupt; we just log a debug message.
4744 /*ARGSUSED*/
4745 static int
4746 si_intr_decode_err_threshold(
4747 si_ctl_state_t *si_ctlp,
4748 si_port_state_t *si_portp,
4749 int port)
4751 SIDBG_P(SIDBG_INTR, si_portp,
4752 "si_intr_err_threshold", NULL);
4753 return (SI_SUCCESS);
4757 * Interrupt which indicates that the CRC Error counter has exceeded the
4758 * programmed non-zero threshold value.
4760 * We are not interested in this interrupt; we just log a debug message.
4762 /*ARGSUSED*/
4763 static int
4764 si_intr_crc_err_threshold(
4765 si_ctl_state_t *si_ctlp,
4766 si_port_state_t *si_portp,
4767 int port)
4769 SIDBG_P(SIDBG_INTR, si_portp,
4770 "si_intr_crc_threshold", NULL);
4771 return (SI_SUCCESS);
4775 * Interrupt which indicates that the Handshake Error counter has
4776 * exceeded the programmed non-zero threshold value.
4778 * We are not interested in this interrupt; we just log a debug message.
4780 /*ARGSUSED*/
4781 static int
4782 si_intr_handshake_err_threshold(
4783 si_ctl_state_t *si_ctlp,
4784 si_port_state_t *si_portp,
4785 int port)
4787 SIDBG_P(SIDBG_INTR, si_portp,
4788 "si_intr_handshake_err_threshold", NULL);
4789 return (SI_SUCCESS);
4793 * Interrupt which indicates that a "Set Device Bits" FIS has been
4794 * received with N-bit set in the control field.
4796 * We are not interested in this interrupt; we just log a debug message.
4798 /*ARGSUSED*/
4799 static int
4800 si_intr_set_devbits_notify(
4801 si_ctl_state_t *si_ctlp,
4802 si_port_state_t *si_portp,
4803 int port)
4805 SIDBG_P(SIDBG_INTR, si_portp,
4806 "si_intr_set_devbits_notify", NULL);
4807 return (SI_SUCCESS);
4812 * Enable the interrupts for a particular port.
4814 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4815 * before calling us.
4817 static void
4818 si_enable_port_interrupts(si_ctl_state_t *si_ctlp, int port)
4820 uint32_t mask;
4821 si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
4823 /* get the current settings first. */
4824 mask = ddi_get32(si_ctlp->sictl_global_acc_handle,
4825 (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp));
4827 SIDBG_P(SIDBG_INIT, si_portp,
4828 "si_enable_port_interrupts: current mask: 0x%x",
4829 mask);
4831 /* enable the bit for current port. */
4832 SET_BIT(mask, port);
4834 /* now use this mask to enable the interrupt. */
4835 ddi_put32(si_ctlp->sictl_global_acc_handle,
4836 (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp),
4837 mask);
4841 * Enable interrupts for all the ports.
4843 static void
4844 si_enable_all_interrupts(si_ctl_state_t *si_ctlp)
4846 int port;
4848 for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
4849 si_enable_port_interrupts(si_ctlp, port);
4854 * Disable interrupts for a particular port.
4856 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4857 * before calling us.
4859 static void
4860 si_disable_port_interrupts(si_ctl_state_t *si_ctlp, int port)
4862 uint32_t mask;
4864 /* get the current settings first. */
4865 mask = ddi_get32(si_ctlp->sictl_global_acc_handle,
4866 (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp));
4868 /* clear the bit for current port. */
4869 CLEAR_BIT(mask, port);
4871 /* now use this mask to disable the interrupt. */
4872 ddi_put32(si_ctlp->sictl_global_acc_handle,
4873 (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp),
4874 mask);
4879 * Disable interrupts for all the ports.
4881 static void
4882 si_disable_all_interrupts(si_ctl_state_t *si_ctlp)
4884 int port;
4886 for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
4887 si_disable_port_interrupts(si_ctlp, port);
4892 * Fetches the latest sstatus, scontrol, serror, sactive registers
4893 * and stuffs them into sata_device_t structure.
4895 static void
4896 fill_dev_sregisters(si_ctl_state_t *si_ctlp, int port, sata_device_t *satadev)
4898 satadev->satadev_scr.sstatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
4899 (uint32_t *)(PORT_SSTATUS(si_ctlp, port)));
4900 satadev->satadev_scr.serror = ddi_get32(si_ctlp->sictl_port_acc_handle,
4901 (uint32_t *)(PORT_SERROR(si_ctlp, port)));
4902 satadev->satadev_scr.sactive = ddi_get32(si_ctlp->sictl_port_acc_handle,
4903 (uint32_t *)(PORT_SACTIVE(si_ctlp, port)));
4904 satadev->satadev_scr.scontrol =
4905 ddi_get32(si_ctlp->sictl_port_acc_handle,
4906 (uint32_t *)(PORT_SCONTROL(si_ctlp, port)));
4911 * si_add_legacy_intrs() handles INTx and legacy interrupts.
4913 static int
4914 si_add_legacy_intrs(si_ctl_state_t *si_ctlp)
4916 dev_info_t *devinfo = si_ctlp->sictl_devinfop;
4917 int actual, count = 0;
4918 int x, y, rc, inum = 0;
4920 SIDBG_C(SIDBG_INIT, si_ctlp, "si_add_legacy_intrs", NULL);
4922 /* get number of interrupts. */
4923 rc = ddi_intr_get_nintrs(devinfo, DDI_INTR_TYPE_FIXED, &count);
4924 if ((rc != DDI_SUCCESS) || (count == 0)) {
4925 SIDBG_C(SIDBG_ERRS, si_ctlp,
4926 "ddi_intr_get_nintrs() failed, "
4927 "rc %d count %d\n", rc, count);
4928 return (DDI_FAILURE);
4931 /* Allocate an array of interrupt handles. */
4932 si_ctlp->sictl_intr_size = count * sizeof (ddi_intr_handle_t);
4933 si_ctlp->sictl_htable = kmem_zalloc(si_ctlp->sictl_intr_size, KM_SLEEP);
4935 /* call ddi_intr_alloc(). */
4936 rc = ddi_intr_alloc(devinfo, si_ctlp->sictl_htable, DDI_INTR_TYPE_FIXED,
4937 inum, count, &actual, DDI_INTR_ALLOC_STRICT);
4939 if ((rc != DDI_SUCCESS) || (actual == 0)) {
4940 SIDBG_C(SIDBG_ERRS, si_ctlp,
4941 "ddi_intr_alloc() failed, rc %d\n", rc);
4942 kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
4943 return (DDI_FAILURE);
4946 if (actual < count) {
4947 SIDBG_C(SIDBG_ERRS, si_ctlp,
4948 "Requested: %d, Received: %d", count, actual);
4950 for (x = 0; x < actual; x++) {
4951 (void) ddi_intr_free(si_ctlp->sictl_htable[x]);
4954 kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
4955 return (DDI_FAILURE);
4958 si_ctlp->sictl_intr_cnt = actual;
4960 /* Get intr priority. */
4961 if (ddi_intr_get_pri(si_ctlp->sictl_htable[0],
4962 &si_ctlp->sictl_intr_pri) != DDI_SUCCESS) {
4963 SIDBG_C(SIDBG_ERRS, si_ctlp,
4964 "ddi_intr_get_pri() failed", NULL);
4966 for (x = 0; x < actual; x++) {
4967 (void) ddi_intr_free(si_ctlp->sictl_htable[x]);
4970 kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
4971 return (DDI_FAILURE);
4974 /* Test for high level mutex. */
4975 if (si_ctlp->sictl_intr_pri >= ddi_intr_get_hilevel_pri()) {
4976 SIDBG_C(SIDBG_ERRS, si_ctlp,
4977 "si_add_legacy_intrs: Hi level intr not supported", NULL);
4979 for (x = 0; x < actual; x++) {
4980 (void) ddi_intr_free(si_ctlp->sictl_htable[x]);
4983 kmem_free(si_ctlp->sictl_htable, sizeof (ddi_intr_handle_t));
4985 return (DDI_FAILURE);
4988 /* Call ddi_intr_add_handler(). */
4989 for (x = 0; x < actual; x++) {
4990 if (ddi_intr_add_handler(si_ctlp->sictl_htable[x], si_intr,
4991 (caddr_t)si_ctlp, NULL) != DDI_SUCCESS) {
4992 SIDBG_C(SIDBG_ERRS, si_ctlp,
4993 "ddi_intr_add_handler() failed", NULL);
4995 for (y = 0; y < actual; y++) {
4996 (void) ddi_intr_free(si_ctlp->sictl_htable[y]);
4999 kmem_free(si_ctlp->sictl_htable,
5000 si_ctlp->sictl_intr_size);
5001 return (DDI_FAILURE);
5005 /* Call ddi_intr_enable() for legacy interrupts. */
5006 for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
5007 (void) ddi_intr_enable(si_ctlp->sictl_htable[x]);
5010 return (DDI_SUCCESS);
5014 * si_add_msictl_intrs() handles MSI interrupts.
5016 static int
5017 si_add_msi_intrs(si_ctl_state_t *si_ctlp)
5019 dev_info_t *devinfo = si_ctlp->sictl_devinfop;
5020 int count, avail, actual;
5021 int x, y, rc, inum = 0;
5023 SIDBG_C(SIDBG_INIT, si_ctlp, "si_add_msi_intrs", NULL);
5025 /* get number of interrupts. */
5026 rc = ddi_intr_get_nintrs(devinfo, DDI_INTR_TYPE_MSI, &count);
5027 if ((rc != DDI_SUCCESS) || (count == 0)) {
5028 SIDBG_C(SIDBG_ERRS, si_ctlp,
5029 "ddi_intr_get_nintrs() failed, "
5030 "rc %d count %d\n", rc, count);
5031 return (DDI_FAILURE);
5034 /* get number of available interrupts. */
5035 rc = ddi_intr_get_navail(devinfo, DDI_INTR_TYPE_MSI, &avail);
5036 if ((rc != DDI_SUCCESS) || (avail == 0)) {
5037 SIDBG_C(SIDBG_ERRS, si_ctlp,
5038 "ddi_intr_get_navail() failed, "
5039 "rc %d avail %d\n", rc, avail);
5040 return (DDI_FAILURE);
5043 if (avail < count) {
5044 SIDBG_C(SIDBG_INIT, si_ctlp,
5045 "ddi_intr_get_nvail returned %d, navail() returned %d",
5046 count, avail);
5049 /* Allocate an array of interrupt handles. */
5050 si_ctlp->sictl_intr_size = count * sizeof (ddi_intr_handle_t);
5051 si_ctlp->sictl_htable = kmem_alloc(si_ctlp->sictl_intr_size, KM_SLEEP);
5053 /* call ddi_intr_alloc(). */
5054 rc = ddi_intr_alloc(devinfo, si_ctlp->sictl_htable, DDI_INTR_TYPE_MSI,
5055 inum, count, &actual, DDI_INTR_ALLOC_NORMAL);
5057 if ((rc != DDI_SUCCESS) || (actual == 0)) {
5058 SIDBG_C(SIDBG_ERRS, si_ctlp,
5059 "ddi_intr_alloc() failed, rc %d\n", rc);
5060 kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
5061 return (DDI_FAILURE);
5064 /* use interrupt count returned */
5065 if (actual < count) {
5066 SIDBG_C(SIDBG_INIT, si_ctlp,
5067 "Requested: %d, Received: %d", count, actual);
5070 si_ctlp->sictl_intr_cnt = actual;
5073 * Get priority for first msi, assume remaining are all the same.
5075 if (ddi_intr_get_pri(si_ctlp->sictl_htable[0],
5076 &si_ctlp->sictl_intr_pri) != DDI_SUCCESS) {
5077 SIDBG_C(SIDBG_ERRS, si_ctlp, "ddi_intr_get_pri() failed", NULL);
5079 /* Free already allocated intr. */
5080 for (y = 0; y < actual; y++) {
5081 (void) ddi_intr_free(si_ctlp->sictl_htable[y]);
5084 kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
5085 return (DDI_FAILURE);
5088 /* Test for high level mutex. */
5089 if (si_ctlp->sictl_intr_pri >= ddi_intr_get_hilevel_pri()) {
5090 SIDBG_C(SIDBG_ERRS, si_ctlp,
5091 "si_add_msi_intrs: Hi level intr not supported", NULL);
5093 /* Free already allocated intr. */
5094 for (y = 0; y < actual; y++) {
5095 (void) ddi_intr_free(si_ctlp->sictl_htable[y]);
5098 kmem_free(si_ctlp->sictl_htable, sizeof (ddi_intr_handle_t));
5100 return (DDI_FAILURE);
5103 /* Call ddi_intr_add_handler(). */
5104 for (x = 0; x < actual; x++) {
5105 if (ddi_intr_add_handler(si_ctlp->sictl_htable[x], si_intr,
5106 (caddr_t)si_ctlp, NULL) != DDI_SUCCESS) {
5107 SIDBG_C(SIDBG_ERRS, si_ctlp,
5108 "ddi_intr_add_handler() failed", NULL);
5110 /* Free already allocated intr. */
5111 for (y = 0; y < actual; y++) {
5112 (void) ddi_intr_free(si_ctlp->sictl_htable[y]);
5115 kmem_free(si_ctlp->sictl_htable,
5116 si_ctlp->sictl_intr_size);
5117 return (DDI_FAILURE);
5121 (void) ddi_intr_get_cap(si_ctlp->sictl_htable[0],
5122 &si_ctlp->sictl_intr_cap);
5124 if (si_ctlp->sictl_intr_cap & DDI_INTR_FLAG_BLOCK) {
5125 /* Call ddi_intr_block_enable() for MSI. */
5126 (void) ddi_intr_block_enable(si_ctlp->sictl_htable,
5127 si_ctlp->sictl_intr_cnt);
5128 } else {
5129 /* Call ddi_intr_enable() for MSI non block enable. */
5130 for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
5131 (void) ddi_intr_enable(si_ctlp->sictl_htable[x]);
5135 return (DDI_SUCCESS);
5139 * Removes the registered interrupts irrespective of whether they
5140 * were legacy or MSI.
5142 static void
5143 si_rem_intrs(si_ctl_state_t *si_ctlp)
5145 int x;
5147 SIDBG_C(SIDBG_INIT, si_ctlp, "si_rem_intrs entered", NULL);
5149 /* Disable all interrupts. */
5150 if ((si_ctlp->sictl_intr_type == DDI_INTR_TYPE_MSI) &&
5151 (si_ctlp->sictl_intr_cap & DDI_INTR_FLAG_BLOCK)) {
5152 /* Call ddi_intr_block_disable(). */
5153 (void) ddi_intr_block_disable(si_ctlp->sictl_htable,
5154 si_ctlp->sictl_intr_cnt);
5155 } else {
5156 for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
5157 (void) ddi_intr_disable(si_ctlp->sictl_htable[x]);
5161 /* Call ddi_intr_remove_handler(). */
5162 for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
5163 (void) ddi_intr_remove_handler(si_ctlp->sictl_htable[x]);
5164 (void) ddi_intr_free(si_ctlp->sictl_htable[x]);
5167 kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
5171 * Resets either the port or the device connected to the port based on
5172 * the flag variable.
5174 * The reset effectively throws away all the pending commands. So, the caller
5175 * has to make provision to handle the pending commands.
5177 * After the reset, we wait till the port is ready again.
5179 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
5180 * before calling us.
5182 * Note: Not port-mult aware.
5184 static int
5185 si_reset_dport_wait_till_ready(
5186 si_ctl_state_t *si_ctlp,
5187 si_port_state_t *si_portp,
5188 int port,
5189 int flag)
5191 uint32_t port_status;
5192 int loop_count = 0;
5193 sata_device_t sdevice;
5194 uint32_t SStatus;
5195 uint32_t SControl;
5196 uint32_t port_intr_status;
5198 _NOTE(ASSUMING_PROTECTED(si_portp))
5200 if (flag == SI_PORT_RESET) {
5201 ddi_put32(si_ctlp->sictl_port_acc_handle,
5202 (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
5203 PORT_CONTROL_SET_BITS_PORT_RESET);
5205 /* Port reset is not self clearing. So clear it now. */
5206 ddi_put32(si_ctlp->sictl_port_acc_handle,
5207 (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
5208 PORT_CONTROL_CLEAR_BITS_PORT_RESET);
5209 } else {
5210 /* Reset the device. */
5211 ddi_put32(si_ctlp->sictl_port_acc_handle,
5212 (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
5213 PORT_CONTROL_SET_BITS_DEV_RESET);
5216 * tidbit: this bit is self clearing; so there is no need
5217 * for manual clear as we did for port reset.
5221 /* Set the reset in progress flag */
5222 if (!(flag & SI_RESET_NO_EVENTS_UP)) {
5223 si_portp->siport_reset_in_progress = 1;
5228 * Every reset needs a PHY initialization.
5230 * The way to initialize the PHY is to write a 1 and then
5231 * a 0 to DET field of SControl register.
5234 /* Fetch the current SControl before writing the DET part with 1. */
5235 SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
5236 (uint32_t *)PORT_SCONTROL(si_ctlp, port));
5237 SCONTROL_SET_DET(SControl, SCONTROL_DET_COMRESET);
5238 ddi_put32(si_ctlp->sictl_port_acc_handle,
5239 (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
5240 SControl);
5241 #ifndef __lock_lint
5242 delay(SI_10MS_TICKS); /* give time for COMRESET to percolate */
5243 #endif /* __lock_lint */
5245 /* Now fetch the SControl again and rewrite the DET part with 0 */
5246 SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
5247 (uint32_t *)PORT_SCONTROL(si_ctlp, port));
5248 SCONTROL_SET_DET(SControl, SCONTROL_DET_NOACTION);
5249 ddi_put32(si_ctlp->sictl_port_acc_handle,
5250 (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
5251 SControl);
5254 * PHY may be initialized by now. Check the DET field of SStatus
5255 * to determine if there is a device present.
5257 * The DET field is valid only if IPM field indicates that
5258 * the interface is in active state.
5261 loop_count = 0;
5262 do {
5263 SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
5264 (uint32_t *)PORT_SSTATUS(si_ctlp, port));
5266 if (SSTATUS_GET_IPM(SStatus) !=
5267 SSTATUS_IPM_INTERFACE_ACTIVE) {
5269 * If the interface is not active, the DET field
5270 * is considered not accurate. So we want to
5271 * continue looping.
5273 SSTATUS_SET_DET(SStatus, SSTATUS_DET_NODEV_NOPHY);
5276 if (loop_count++ > SI_POLLRATE_SSTATUS) {
5277 /* We are effectively timing out after 0.1 sec. */
5278 break;
5281 /* Wait for 10 millisec */
5282 #ifndef __lock_lint
5283 delay(SI_10MS_TICKS);
5284 #endif /* __lock_lint */
5286 } while (SSTATUS_GET_DET(SStatus) != SSTATUS_DET_DEVPRESENT_PHYONLINE);
5288 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
5289 "si_reset_dport_wait_till_ready: loop count: %d, \
5290 SStatus: 0x%x",
5291 loop_count,
5292 SStatus);
5294 /* Now check for port readiness. */
5295 loop_count = 0;
5296 do {
5297 port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
5298 (uint32_t *)PORT_STATUS(si_ctlp, port));
5300 if (loop_count++ > SI_POLLRATE_PORTREADY) {
5301 /* We are effectively timing out after 0.5 sec. */
5302 break;
5305 /* Wait for 10 millisec */
5306 #ifndef __lock_lint
5307 delay(SI_10MS_TICKS);
5308 #endif /* __lock_lint */
5310 } while (!(port_status & PORT_STATUS_BITS_PORT_READY));
5312 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
5313 "si_reset_dport_wait_till_ready: loop count: %d, \
5314 port_status: 0x%x, SStatus: 0x%x",
5315 loop_count,
5316 port_status,
5317 SStatus);
5319 /* Indicate to the framework that a reset has happened. */
5320 if (!(flag & SI_RESET_NO_EVENTS_UP)) {
5322 bzero((void *)&sdevice, sizeof (sata_device_t));
5324 sdevice.satadev_addr.cport = (uint8_t)port;
5325 sdevice.satadev_addr.pmport = PORTMULT_CONTROL_PORT;
5327 if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
5328 sdevice.satadev_addr.qual = SATA_ADDR_DPMPORT;
5329 } else {
5330 sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
5332 sdevice.satadev_state = SATA_DSTATE_RESET |
5333 SATA_DSTATE_PWR_ACTIVE;
5334 if (si_ctlp->sictl_sata_hba_tran) {
5335 sata_hba_event_notify(
5336 si_ctlp->sictl_sata_hba_tran->sata_tran_hba_dip,
5337 &sdevice,
5338 SATA_EVNT_DEVICE_RESET);
5341 SIDBG_P(SIDBG_EVENT, si_portp,
5342 "sending event up: SATA_EVNT_RESET", NULL);
5345 if ((SSTATUS_GET_IPM(SStatus) == SSTATUS_IPM_INTERFACE_ACTIVE) &&
5346 (SSTATUS_GET_DET(SStatus) ==
5347 SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
5348 /* The interface is active and the device is present */
5349 if (!(port_status & PORT_STATUS_BITS_PORT_READY)) {
5350 /* But the port is is not ready for some reason */
5351 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
5352 "si_reset_dport_wait_till_ready failed", NULL);
5353 return (SI_FAILURE);
5359 * For some reason, we are losing the interrupt enablement after
5360 * any reset condition. So restore them back now.
5363 SIDBG_P(SIDBG_INIT, si_portp,
5364 "current interrupt enable set: 0x%x",
5365 ddi_get32(si_ctlp->sictl_port_acc_handle,
5366 (uint32_t *)PORT_INTERRUPT_ENABLE_SET(si_ctlp, port)));
5368 ddi_put32(si_ctlp->sictl_port_acc_handle,
5369 (uint32_t *)PORT_INTERRUPT_ENABLE_SET(si_ctlp, port),
5370 (INTR_COMMAND_COMPLETE |
5371 INTR_COMMAND_ERROR |
5372 INTR_PORT_READY |
5373 INTR_POWER_CHANGE |
5374 INTR_PHYRDY_CHANGE |
5375 INTR_COMWAKE_RECEIVED |
5376 INTR_UNRECOG_FIS |
5377 INTR_DEV_XCHANGED |
5378 INTR_SETDEVBITS_NOTIFY));
5380 si_enable_port_interrupts(si_ctlp, port);
5383 * make sure interrupts are cleared
5385 port_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
5386 (uint32_t *)PORT_INTERRUPT_STATUS(si_ctlp, port));
5388 ddi_put32(si_ctlp->sictl_port_acc_handle,
5389 (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp,
5390 port)),
5391 port_intr_status & INTR_MASK);
5394 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
5395 "si_reset_dport_wait_till_ready returning success", NULL);
5397 return (SI_SUCCESS);
5401 * Schedule an initialization of the port using a timeout to get it done
5402 * off an interrupt thread.
5404 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
5405 * before calling us.
5407 static void
5408 si_schedule_port_initialize(
5409 si_ctl_state_t *si_ctlp,
5410 si_port_state_t *si_portp,
5411 int port)
5413 si_event_arg_t *args;
5415 ASSERT(mutex_owned(&si_portp->siport_mutex));
5417 args = si_portp->siport_event_args;
5418 if (args->siea_ctlp != NULL) {
5419 cmn_err(CE_WARN, "si_schedule_port_initialize: "
5420 "args->si_ctlp != NULL");
5421 return;
5424 args->siea_ctlp = si_ctlp;
5425 args->siea_port = port;
5427 (void) timeout(si_do_initialize_port, si_portp, 1);
5431 * Called from timeout()
5432 * Unpack the arguments and call si_initialize_port_wait_till_ready()
5434 static void
5435 si_do_initialize_port(void *arg)
5437 si_event_arg_t *args;
5438 si_ctl_state_t *si_ctlp;
5439 si_port_state_t *si_portp;
5440 int port;
5442 si_portp = arg;
5443 mutex_enter(&si_portp->siport_mutex);
5445 args = si_portp->siport_event_args;
5446 si_ctlp = args->siea_ctlp;
5447 port = args->siea_port;
5448 args->siea_ctlp = NULL; /* mark siport_event_args as free */
5449 (void) si_initialize_port_wait_till_ready(si_ctlp, port);
5451 mutex_exit(&si_portp->siport_mutex);
5456 * Initializes the port.
5458 * Initialization effectively throws away all the pending commands on
5459 * the port. So, the caller has to make provision to handle the pending
5460 * commands.
5462 * After the port initialization, we wait till the port is ready again.
5464 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
5465 * before calling us.
5467 static int
5468 si_initialize_port_wait_till_ready(si_ctl_state_t *si_ctlp, int port)
5470 uint32_t port_status;
5471 int loop_count = 0;
5472 uint32_t SStatus;
5473 si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
5475 /* Initialize the port. */
5476 ddi_put32(si_ctlp->sictl_port_acc_handle,
5477 (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
5478 PORT_CONTROL_SET_BITS_PORT_INITIALIZE);
5480 /* Wait until Port Ready */
5481 loop_count = 0;
5482 do {
5483 port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
5484 (uint32_t *)PORT_STATUS(si_ctlp, port));
5486 if (loop_count++ > SI_POLLRATE_PORTREADY) {
5487 SIDBG_P(SIDBG_INTR, si_portp,
5488 "si_initialize_port_wait is timing out: "
5489 "port_status: %x",
5490 port_status);
5491 /* We are effectively timing out after 0.5 sec. */
5492 break;
5495 /* Wait for 10 millisec */
5496 #ifndef __lock_lint
5497 delay(SI_10MS_TICKS);
5498 #endif /* __lock_lint */
5500 } while (!(port_status & PORT_STATUS_BITS_PORT_READY));
5502 SIDBG_P(SIDBG_POLL_LOOP, si_portp,
5503 "si_initialize_port_wait_till_ready: loop count: %d",
5504 loop_count);
5506 SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
5507 (uint32_t *)PORT_SSTATUS(si_ctlp, port));
5509 if ((SSTATUS_GET_IPM(SStatus) == SSTATUS_IPM_INTERFACE_ACTIVE) &&
5510 (SSTATUS_GET_DET(SStatus) ==
5511 SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
5512 /* The interface is active and the device is present */
5513 if (!(port_status & PORT_STATUS_BITS_PORT_READY)) {
5514 /* But the port is is not ready for some reason */
5515 return (SI_FAILURE);
5519 return (SI_SUCCESS);
5524 * si_watchdog_handler() calls us if it detects that there are some
5525 * commands which timed out. We recalculate the timed out commands once
5526 * again since some of them may have finished recently.
5528 static void
5529 si_timeout_pkts(
5530 si_ctl_state_t *si_ctlp,
5531 si_port_state_t *si_portp,
5532 int port,
5533 uint32_t timedout_tags)
5535 uint32_t slot_status;
5536 uint32_t finished_tags;
5538 SIDBG_P(SIDBG_TIMEOUT, si_portp,
5539 "si_timeout_pkts entry", NULL);
5541 mutex_enter(&si_portp->siport_mutex);
5542 slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
5543 (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
5545 si_portp->mopping_in_progress++;
5548 * Initialize the controller. The only way to timeout the commands
5549 * is to reset or initialize the controller. We mop commands after
5550 * the initialization.
5552 (void) si_initialize_port_wait_till_ready(si_ctlp, port);
5555 * Recompute the timedout tags since some of them may have finished
5556 * meanwhile.
5558 finished_tags = si_portp->siport_pending_tags &
5559 ~slot_status & SI_SLOT_MASK;
5560 timedout_tags &= ~finished_tags;
5562 SIDBG_P(SIDBG_TIMEOUT, si_portp,
5563 "si_timeout_pkts: finished: %x, timeout: %x",
5564 finished_tags,
5565 timedout_tags);
5567 si_mop_commands(si_ctlp,
5568 si_portp,
5569 port,
5570 slot_status,
5571 0, /* failed_tags */
5572 timedout_tags,
5573 0, /* aborting_tags */
5574 0); /* reset_tags */
5576 mutex_exit(&si_portp->siport_mutex);
5582 * Watchdog handler kicks in every 5 seconds to timeout any commands pending
5583 * for long time.
5585 static void
5586 si_watchdog_handler(si_ctl_state_t *si_ctlp)
5588 uint32_t pending_tags = 0;
5589 uint32_t timedout_tags = 0;
5590 si_port_state_t *si_portp;
5591 int port;
5592 int tmpslot;
5593 sata_pkt_t *satapkt;
5595 /* max number of cycles this packet should survive */
5596 int max_life_cycles;
5598 /* how many cycles this packet survived so far */
5599 int watched_cycles;
5601 mutex_enter(&si_ctlp->sictl_mutex);
5602 SIDBG_C(SIDBG_ENTRY, si_ctlp,
5603 "si_watchdog_handler entered", NULL);
5605 for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
5607 si_portp = si_ctlp->sictl_ports[port];
5608 if (si_portp == NULL) {
5609 continue;
5612 mutex_enter(&si_portp->siport_mutex);
5614 if (si_portp->siport_port_type == PORT_TYPE_NODEV) {
5615 mutex_exit(&si_portp->siport_mutex);
5616 continue;
5619 /* Skip the check for those ports in error recovery */
5620 if (si_portp->mopping_in_progress > 0) {
5621 SIDBG_P(SIDBG_INFO, si_portp,
5622 "si_watchdog_handler: port %d mopping "
5623 "in progress, so just return", port);
5624 mutex_exit(&si_portp->siport_mutex);
5625 continue;
5628 pending_tags = si_portp->siport_pending_tags;
5629 timedout_tags = 0;
5630 while (pending_tags) {
5631 tmpslot = ddi_ffs(pending_tags) - 1;
5632 if (tmpslot == -1) {
5633 break;
5635 satapkt = si_portp->siport_slot_pkts[tmpslot];
5637 if ((satapkt != NULL) && satapkt->satapkt_time) {
5640 * We are overloading satapkt_hba_driver_private
5641 * with watched_cycle count.
5643 * If a packet has survived for more than it's
5644 * max life cycles, it is a candidate for time
5645 * out.
5647 watched_cycles = (int)(intptr_t)
5648 satapkt->satapkt_hba_driver_private;
5649 watched_cycles++;
5650 max_life_cycles = (satapkt->satapkt_time +
5651 si_watchdog_timeout - 1) /
5652 si_watchdog_timeout;
5653 if (watched_cycles > max_life_cycles) {
5654 timedout_tags |= (0x1 << tmpslot);
5655 SIDBG_P(SIDBG_TIMEOUT,
5656 si_portp,
5657 "watchdog: timedout_tags: 0x%x",
5658 timedout_tags);
5660 satapkt->satapkt_hba_driver_private =
5661 (void *)(intptr_t)watched_cycles;
5664 CLEAR_BIT(pending_tags, tmpslot);
5667 if (timedout_tags) {
5668 mutex_exit(&si_portp->siport_mutex);
5669 mutex_exit(&si_ctlp->sictl_mutex);
5670 si_timeout_pkts(si_ctlp, si_portp, port, timedout_tags);
5671 mutex_enter(&si_ctlp->sictl_mutex);
5672 mutex_enter(&si_portp->siport_mutex);
5675 mutex_exit(&si_portp->siport_mutex);
5678 /* Reinstall the watchdog timeout handler. */
5679 if (!(si_ctlp->sictl_flags & SI_NO_TIMEOUTS)) {
5680 si_ctlp->sictl_timeout_id =
5681 timeout((void (*)(void *))si_watchdog_handler,
5682 (caddr_t)si_ctlp, si_watchdog_tick);
5684 mutex_exit(&si_ctlp->sictl_mutex);
5688 * FMA Functions
5692 * The IO fault service error handling callback function
5694 /*ARGSUSED*/
5695 static int
5696 si_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
5699 * as the driver can always deal with an error in any dma or
5700 * access handle, we can just return the fme_status value.
5702 pci_ereport_post(dip, err, NULL);
5703 return (err->fme_status);
5707 * si_fm_init - initialize fma capabilities and register with IO
5708 * fault services.
5710 static void
5711 si_fm_init(si_ctl_state_t *si_ctlp)
5714 * Need to change iblock to priority for new MSI intr
5716 ddi_iblock_cookie_t fm_ibc;
5718 /* Only register with IO Fault Services if we have some capability */
5719 if (si_ctlp->fm_capabilities) {
5720 /* Adjust access and dma attributes for FMA */
5721 accattr.devacc_attr_access = DDI_FLAGERR_ACC;
5722 prb_sgt_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
5723 buffer_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
5726 * Register capabilities with IO Fault Services.
5727 * fm_capabilities will be updated to indicate
5728 * capabilities actually supported (not requested.)
5730 ddi_fm_init(si_ctlp->sictl_devinfop, &si_ctlp->fm_capabilities,
5731 &fm_ibc);
5733 if (si_ctlp->fm_capabilities == DDI_FM_NOT_CAPABLE)
5734 cmn_err(CE_WARN, "si_fm_init: ddi_fm_init fail");
5737 * Initialize pci ereport capabilities if ereport
5738 * capable (should always be.)
5740 if (DDI_FM_EREPORT_CAP(si_ctlp->fm_capabilities) ||
5741 DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
5742 pci_ereport_setup(si_ctlp->sictl_devinfop);
5746 * Register error callback if error callback capable.
5748 if (DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
5749 ddi_fm_handler_register(si_ctlp->sictl_devinfop,
5750 si_fm_error_cb, (void *) si_ctlp);
5756 * si_fm_fini - Releases fma capabilities and un-registers with IO
5757 * fault services.
5759 static void
5760 si_fm_fini(si_ctl_state_t *si_ctlp)
5762 /* Only unregister FMA capabilities if registered */
5763 if (si_ctlp->fm_capabilities) {
5765 * Un-register error callback if error callback capable.
5767 if (DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
5768 ddi_fm_handler_unregister(si_ctlp->sictl_devinfop);
5772 * Release any resources allocated by pci_ereport_setup()
5774 if (DDI_FM_EREPORT_CAP(si_ctlp->fm_capabilities) ||
5775 DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
5776 pci_ereport_teardown(si_ctlp->sictl_devinfop);
5779 /* Unregister from IO Fault Services */
5780 ddi_fm_fini(si_ctlp->sictl_devinfop);
5782 /* Adjust access and dma attributes for FMA */
5783 accattr.devacc_attr_access = DDI_DEFAULT_ACC;
5784 prb_sgt_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
5785 buffer_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
5789 static int
5790 si_check_acc_handle(ddi_acc_handle_t handle)
5792 ddi_fm_error_t de;
5794 ASSERT(handle != NULL);
5795 ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION);
5796 return (de.fme_status);
5799 static int
5800 si_check_dma_handle(ddi_dma_handle_t handle)
5802 ddi_fm_error_t de;
5804 ASSERT(handle != NULL);
5805 ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION);
5806 return (de.fme_status);
5809 static int
5810 si_check_ctl_handles(si_ctl_state_t *si_ctlp)
5812 if ((si_check_acc_handle(si_ctlp->sictl_pci_conf_handle)
5813 != DDI_SUCCESS) ||
5814 (si_check_acc_handle(si_ctlp->sictl_global_acc_handle)
5815 != DDI_SUCCESS) ||
5816 (si_check_acc_handle(si_ctlp->sictl_port_acc_handle)
5817 != DDI_SUCCESS)) {
5818 return (DDI_FAILURE);
5821 return (DDI_SUCCESS);
5825 * WARNING: The caller is expected to obtain the siport_mutex
5826 * before calling us.
5828 static int
5829 si_check_port_handles(si_port_state_t *si_portp)
5831 if ((si_check_dma_handle(si_portp->siport_prbpool_dma_handle)
5832 != DDI_SUCCESS) ||
5833 (si_check_acc_handle(si_portp->siport_prbpool_acc_handle)
5834 != DDI_SUCCESS) ||
5835 (si_check_dma_handle(si_portp->siport_sgbpool_dma_handle)
5836 != DDI_SUCCESS) ||
5837 (si_check_acc_handle(si_portp->siport_sgbpool_acc_handle)
5838 != DDI_SUCCESS)) {
5839 return (DDI_FAILURE);
5842 return (DDI_SUCCESS);
5845 static void
5846 si_fm_ereport(si_ctl_state_t *si_ctlp, char *detail, char *payload)
5848 uint64_t ena;
5849 char buf[FM_MAX_CLASS];
5851 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
5852 ena = fm_ena_generate(0, FM_ENA_FMT1);
5854 if (DDI_FM_EREPORT_CAP(si_ctlp->fm_capabilities)) {
5855 ddi_fm_ereport_post(si_ctlp->sictl_devinfop, buf, ena,
5856 DDI_NOSLEEP,
5857 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERSION,
5858 "detailed_err_type", DATA_TYPE_STRING, payload,
5859 NULL);
5864 * Logs the message.
5866 static void
5867 si_log(si_ctl_state_t *si_ctlp, si_port_state_t *si_portp, char *fmt, ...)
5869 va_list ap;
5871 mutex_enter(&si_log_mutex);
5873 va_start(ap, fmt);
5875 if (si_portp == NULL && si_ctlp == NULL) {
5876 sata_vtrace_debug(NULL, fmt, ap);
5877 va_end(ap);
5878 mutex_exit(&si_log_mutex);
5879 return;
5882 if (si_portp == NULL && si_ctlp != NULL) {
5883 sata_vtrace_debug(si_ctlp->sictl_devinfop, fmt, ap);
5884 va_end(ap);
5885 mutex_exit(&si_log_mutex);
5886 return;
5890 * si_portp is not NULL, but si_ctlp might be.
5891 * Reference si_portp for both port and dip.
5893 (void) snprintf(si_log_buf, SI_LOGBUF_LEN, "port%d: %s",
5894 si_portp->siport_port_num, fmt);
5896 if (si_portp->siport_ctlp == NULL) {
5897 sata_vtrace_debug(NULL, si_log_buf, ap);
5898 va_end(ap);
5899 mutex_exit(&si_log_mutex);
5900 return;
5903 sata_vtrace_debug(si_portp->siport_ctlp->sictl_devinfop,
5904 si_log_buf, ap);
5906 va_end(ap);
5908 mutex_exit(&si_log_mutex);
5912 static void
5913 si_copy_out_regs(sata_cmd_t *scmd, si_ctl_state_t *si_ctlp, uint8_t port,
5914 uint8_t slot)
5916 uint32_t *fis_word_ptr;
5917 si_prb_t *prb;
5918 int i;
5919 si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
5922 * The LRAM contains the the modified FIS after command completion, so
5923 * first copy it back to the in-core PRB pool. To save read cycles,
5924 * just copy over the FIS portion of the PRB pool.
5926 prb = &si_ctlp->sictl_ports[port]->siport_prbpool[slot];
5928 fis_word_ptr = (uint32_t *)(void *)(&prb->prb_fis);
5930 for (i = 0; i < (sizeof (fis_reg_h2d_t)/4); i++) {
5931 fis_word_ptr[i] = ddi_get32(
5932 si_ctlp->sictl_port_acc_handle,
5933 (uint32_t *)(PORT_LRAM(si_ctlp, port,
5934 slot) + i * 4 + 0x08));
5938 * always get the status register
5940 scmd->satacmd_status_reg = GET_FIS_COMMAND(prb->prb_fis);
5942 DTRACE_PROBE1(satacmd_status_reg, int, scmd->satacmd_status_reg);
5944 if (scmd->satacmd_flags.sata_copy_out_sec_count_msb) {
5945 scmd->satacmd_sec_count_msb =
5946 GET_FIS_SECTOR_COUNT_EXP(prb->prb_fis);
5947 SIDBG_P(SIDBG_VERBOSE, si_portp,
5948 "copyout satacmd_sec_count_msb %x\n",
5949 scmd->satacmd_sec_count_msb);
5952 if (scmd->satacmd_flags.sata_copy_out_lba_low_msb) {
5953 scmd->satacmd_lba_low_msb = GET_FIS_SECTOR_EXP(prb->prb_fis);
5954 SIDBG_P(SIDBG_VERBOSE, si_portp,
5955 "copyout satacmd_lba_low_msb %x\n",
5956 scmd->satacmd_lba_low_msb);
5959 if (scmd->satacmd_flags.sata_copy_out_lba_mid_msb) {
5960 scmd->satacmd_lba_mid_msb = GET_FIS_CYL_LOW_EXP(prb->prb_fis);
5961 SIDBG_P(SIDBG_VERBOSE, si_portp,
5962 "copyout satacmd_lba_mid_msb %x\n",
5963 scmd->satacmd_lba_mid_msb);
5966 if (scmd->satacmd_flags.sata_copy_out_lba_high_msb) {
5967 scmd->satacmd_lba_high_msb = GET_FIS_CYL_HI_EXP(prb->prb_fis);
5968 SIDBG_P(SIDBG_VERBOSE, si_portp,
5969 "copyout satacmd_lba_high_msb %x\n",
5970 scmd->satacmd_lba_high_msb);
5973 if (scmd->satacmd_flags.sata_copy_out_sec_count_lsb) {
5974 scmd->satacmd_sec_count_lsb =
5975 GET_FIS_SECTOR_COUNT(prb->prb_fis);
5976 SIDBG_P(SIDBG_VERBOSE, si_portp,
5977 "copyout satacmd_sec_count_lsb %x\n",
5978 scmd->satacmd_sec_count_lsb);
5981 if (scmd->satacmd_flags.sata_copy_out_lba_low_lsb) {
5982 scmd->satacmd_lba_low_lsb = GET_FIS_SECTOR(prb->prb_fis);
5983 SIDBG_P(SIDBG_VERBOSE, si_portp,
5984 "copyout satacmd_lba_low_lsb %x\n",
5985 scmd->satacmd_lba_low_lsb);
5988 if (scmd->satacmd_flags.sata_copy_out_lba_mid_lsb) {
5989 scmd->satacmd_lba_mid_lsb = GET_FIS_CYL_LOW(prb->prb_fis);
5990 SIDBG_P(SIDBG_VERBOSE, si_portp,
5991 "copyout satacmd_lba_mid_lsb %x\n",
5992 scmd->satacmd_lba_mid_lsb);
5995 if (scmd->satacmd_flags.sata_copy_out_lba_high_lsb) {
5996 scmd->satacmd_lba_high_lsb = GET_FIS_CYL_HI(prb->prb_fis);
5997 SIDBG_P(SIDBG_VERBOSE, si_portp,
5998 "copyout satacmd_lba_high_lsb %x\n",
5999 scmd->satacmd_lba_high_lsb);
6002 if (scmd->satacmd_flags.sata_copy_out_device_reg) {
6003 scmd->satacmd_device_reg = GET_FIS_DEV_HEAD(prb->prb_fis);
6004 SIDBG_P(SIDBG_VERBOSE, si_portp,
6005 "copyout satacmd_device_reg %x\n",
6006 scmd->satacmd_device_reg);
6009 if (scmd->satacmd_flags.sata_copy_out_error_reg) {
6010 scmd->satacmd_error_reg = GET_FIS_FEATURES(prb->prb_fis);
6011 SIDBG_P(SIDBG_VERBOSE, si_portp,
6012 "copyout satacmd_error_reg %x\n",
6013 scmd->satacmd_error_reg);
6018 * This function clear the special port by send the PORT RESET
6019 * After reset was sent, all commands running on the port
6020 * is aborted
6022 static int
6023 si_clear_port(si_ctl_state_t *si_ctlp, int port)
6026 if (si_ctlp == NULL)
6027 return (SI_FAILURE);
6029 * reset this port so that all existing command
6030 * is clear
6032 ddi_put32(si_ctlp->sictl_port_acc_handle,
6033 (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
6034 PORT_CONTROL_SET_BITS_PORT_RESET);
6036 /* Port reset is not self clearing. So clear it now. */
6037 ddi_put32(si_ctlp->sictl_port_acc_handle,
6038 (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
6039 PORT_CONTROL_CLEAR_BITS_PORT_RESET);
6040 return (SI_SUCCESS);
6044 * quiesce(9E) entry point.
6045 * This function is called when the system is single-threaded at high
6046 * PIL with preemption disabled. Therefore, this function must not be
6047 * blocked.
6049 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
6050 * DDI_FAILURE indicates an error condition and should almost never happen.
6052 static int
6053 si_quiesce(dev_info_t *dip)
6055 si_ctl_state_t *si_ctlp;
6056 int instance;
6057 int port;
6059 instance = ddi_get_instance(dip);
6060 si_ctlp = ddi_get_soft_state(si_statep, instance);
6061 if (si_ctlp == NULL)
6062 return (DDI_FAILURE);
6064 SIDBG_C(SIDBG_ENTRY, si_ctlp, "si_quiesce enter", NULL);
6066 * Disable all the interrupts before quiesce
6069 for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
6070 si_disable_port_interrupts(si_ctlp, port);
6071 (void) si_clear_port(si_ctlp, port);
6074 return (DDI_SUCCESS);