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]
23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
28 * SiliconImage 3124/3132/3531 sata controller driver
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.
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
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[]
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
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
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
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
149 * d) for DATAFISERROR:
150 * If the port was executing an NCQ command, issue a Device
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
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
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].
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>
204 #include <sys/sata/sata_hba.h>
205 #include <sys/sata/adapters/si3124/si3124reg.h>
206 #include <sys/sata/adapters/si3124/si3124var.h>
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
*,
251 static void si_poll_cmd(si_ctl_state_t
*, si_port_state_t
*, int, int,
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,
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
*);
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
= {
378 DDI_STRUCTURE_LE_ACC
,
384 static struct dev_ops sictl_dev_ops
= {
385 DEVO_REV
, /* devo_rev */
387 si_getinfo
, /* info */
388 nulldev
, /* identify */
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 */
414 &sictl_dev_ops
, /* driver ops */
417 static struct modlinkage modlinkage
= {
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
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.
452 error
= ddi_soft_state_init(&si_statep
, sizeof (si_ctl_state_t
), 0);
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
);
465 error
= mod_install(&modlinkage
);
467 sata_hba_fini(&modlinkage
);
468 mutex_destroy(&si_log_mutex
);
469 ddi_soft_state_fini(&si_statep
);
473 si_watchdog_tick
= drv_usectohz((clock_t)si_watchdog_timeout
* 1000000);
479 * si3124 module uninitialize.
487 error
= mod_remove(&modlinkage
);
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
);
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.
518 si_attach(dev_info_t
*dip
, ddi_attach_cmd_t cmd
)
520 si_ctl_state_t
*si_ctlp
;
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
;
535 /* Allocate si_softc. */
536 status
= ddi_soft_state_zalloc(si_statep
, instance
);
537 if (status
!= DDI_SUCCESS
) {
541 si_ctlp
= ddi_get_soft_state(si_statep
, instance
);
542 si_ctlp
->sictl_devinfop
= dip
;
544 attach_state
|= ATTACH_PROGRESS_STATEP_ALLOC
;
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
);
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
) {
562 si_ctlp
->sictl_devid
=
563 pci_config_get16(si_ctlp
->sictl_pci_conf_handle
,
565 switch (si_ctlp
->sictl_devid
) {
567 si_ctlp
->sictl_num_ports
= SI3124_MAX_PORTS
;
571 si_ctlp
->sictl_num_ports
= SI3132_MAX_PORTS
;
575 si_ctlp
->sictl_num_ports
= SI3531_MAX_PORTS
;
580 * Driver should not have attatched if device
581 * ID is not already known and is supported.
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
,
591 (caddr_t
*)&si_ctlp
->sictl_global_addr
,
595 &si_ctlp
->sictl_global_acc_handle
);
596 if (status
!= DDI_SUCCESS
) {
600 attach_state
|= ATTACH_PROGRESS_BAR0_MAP
;
602 /* Now map bar1; the bar1 contains the port registers. */
603 status
= ddi_regs_map_setup(dip
,
605 (caddr_t
*)&si_ctlp
->sictl_port_addr
,
609 &si_ctlp
->sictl_port_acc_handle
);
610 if (status
!= DDI_SUCCESS
) {
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
)
626 SIDBG_C(SIDBG_INIT
, si_ctlp
,
627 "ddi_intr_get_supported_types failed", NULL
);
631 SIDBG_C(SIDBG_INIT
, si_ctlp
,
632 "ddi_intr_get_supported_types() returned: 0x%x",
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
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
);
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
);
670 SIDBG_C(SIDBG_INIT
, si_ctlp
,
671 "legacy interrupt setup failed", NULL
);
676 if (!(attach_state
& ATTACH_PROGRESS_INTR_ADDED
)) {
677 SIDBG_C(SIDBG_INIT
, si_ctlp
,
678 "si3124: No interrupts registered", NULL
);
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
;
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
);
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
);
716 si_ctlp
= ddi_get_soft_state(si_statep
, instance
);
718 status
= si_initialize_controller(si_ctlp
);
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
);
753 return (DDI_FAILURE
);
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
) {
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().
803 si_detach(dev_info_t
*dip
, ddi_detach_cmd_t cmd
)
805 si_ctl_state_t
*si_ctlp
;
808 SIDBG(SIDBG_ENTRY
, "si_detach enter", NULL
);
809 instance
= ddi_get_instance(dip
);
810 si_ctlp
= ddi_get_soft_state(si_statep
, instance
);
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
);
854 /* free the soft state. */
855 ddi_soft_state_free(si_statep
, instance
);
857 return (DDI_SUCCESS
);
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) ==
881 mutex_exit(&si_ctlp
->sictl_mutex
);
882 (void) pm_raise_power(si_ctlp
->sictl_devinfop
, 0,
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",
896 mutex_exit(&si_ctlp
->sictl_mutex
);
898 return (DDI_SUCCESS
);
901 return (DDI_FAILURE
);
908 si_power(dev_info_t
*dip
, int component
, int level
)
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
;
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
;
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
);
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),
950 if (si_ctlp
->sictl_flags
& SI_ATTACH
)
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
);
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
);
992 SIDBG_C(SIDBG_POWER
, si_ctlp
, "si3124%d: turning power OFF. "
993 "old level %d", instance
, old_level
);
998 mutex_exit(&si_ctlp
->sictl_mutex
);
1005 * The info entry point for dev_ops.
1009 si_getinfo(dev_info_t
*dip
, ddi_info_cmd_t infocmd
,
1014 _NOTE(ARGUNUSED(dip
))
1015 #endif /* __lock_lint */
1016 si_ctl_state_t
*si_ctlp
;
1021 instance
= getminor(dev
);
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
);
1031 return (DDI_FAILURE
);
1033 case DDI_INFO_DEVT2INSTANCE
:
1034 *(int *)result
= instance
;
1039 return (DDI_SUCCESS
);
1045 * Registers the si3124 with sata framework.
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
)
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.
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
) !=
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.
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
;
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
);
1175 si_portmultp
= &si_portp
->siport_portmult_state
;
1176 port_type
= si_portmultp
->sipm_port_type
[pmport
];
1179 port_type
= si_portp
->siport_port_type
;
1182 switch (port_type
) {
1184 case PORT_TYPE_DISK
:
1185 sd
->satadev_type
= SATA_DTYPE_ATADISK
;
1188 case PORT_TYPE_ATAPI
:
1189 sd
->satadev_type
= SATA_DTYPE_ATAPICD
;
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
;
1198 case PORT_TYPE_UNKNOWN
:
1199 sd
->satadev_type
= SATA_DTYPE_UNKNOWN
;
1203 /* we don't support any other device types. */
1204 sd
->satadev_type
= SATA_DTYPE_NONE
;
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
);
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().
1245 si_tran_start(dev_info_t
*dip
, sata_pkt_t
*spkt
)
1247 si_ctl_state_t
*si_ctlp
;
1249 si_port_state_t
*si_portp
;
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
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
&&
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
))
1306 spkt
->satapkt_reason
= SATA_PKT_QUEUE_FULL
;
1307 SIDBG_P(SIDBG_ERRS
, si_portp
,
1308 "si_tran_start returning QUEUE_FULL",
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) \
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; \
1338 * We set the satapkt_reason in both synch and \
1339 * non-synch cases. \
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.
1367 si_mop_commands(si_ctl_state_t
*si_ctlp
,
1368 si_port_state_t
*si_portp
,
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
;
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",
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",
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
&
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) {
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
,
1424 SIDBG_P(SIDBG_ERRS
, si_portp
,
1425 "si_mop_commands sending up completed satapkt: %x",
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) {
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
,
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
&
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) {
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",
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) {
1516 satapkt
= si_portp
->siport_slot_pkts
[tmpslot
];
1517 SIDBG_P(SIDBG_ERRS
, si_portp
,
1518 "si_mop_commands aborting spkt: %x",
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) {
1539 satapkt
= si_portp
->siport_slot_pkts
[tmpslot
];
1540 SIDBG_P(SIDBG_ERRS
, si_portp
,
1541 "si_mop_commands sending PKT_RESET for "
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) {
1558 satapkt
= si_portp
->siport_slot_pkts
[tmpslot
];
1559 SIDBG_P(SIDBG_ERRS
, si_portp
,
1560 "si_mop_commands sending SATA_PKT_RESET for "
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.
1581 si_tran_abort(dev_info_t
*dip
, sata_pkt_t
*spkt
, int flag
)
1583 uint32_t slot_status
;
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
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
;
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
);
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
,
1671 0, /* failed_tags */
1672 0, /* timedout_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
1686 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
1687 * before calling us.
1690 si_reject_all_reset_pkts(
1691 si_ctl_state_t
*si_ctlp
,
1692 si_port_state_t
*si_portp
,
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",
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
,
1716 0, /* failed_tags */
1717 0, /* timedout_tags */
1718 0, /* aborting_tags */
1724 * Called by sata framework to reset a port(s) or device.
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
;
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",
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
;
1761 retval
= si_reset_dport_wait_till_ready(si_ctlp
, si_portp
, port
,
1763 si_reject_all_reset_pkts(si_ctlp
, si_portp
, port
);
1764 mutex_exit(&si_portp
->siport_mutex
);
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
;
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
;
1794 retval
= si_reset_dport_wait_till_ready(si_ctlp
, si_portp
, port
,
1796 si_reject_all_reset_pkts(si_ctlp
, si_portp
, port
);
1797 mutex_exit(&si_portp
->siport_mutex
);
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
;
1822 retval
= si_reset_dport_wait_till_ready(si_ctlp
,
1823 si_portp
, i
, SI_PORT_RESET
);
1825 mutex_exit(&si_portp
->siport_mutex
);
1828 si_reject_all_reset_pkts(si_ctlp
, si_portp
, i
);
1829 mutex_exit(&si_portp
->siport_mutex
);
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
);
1840 retval
= SI_FAILURE
;
1849 * Called by sata framework to activate a port as part of hotplug.
1851 * Note: Not port-mult aware.
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
;
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",
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.
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
;
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.
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.
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.
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
)
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
,
2023 &si_portp
->siport_sgbpool_dma_handle
) !=
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
,
2033 DDI_DMA_RDWR
| DDI_DMA_CONSISTENT
,
2036 (caddr_t
*)&si_portp
->siport_sgbpool
,
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
);
2046 if (ddi_dma_addr_bind_handle(si_portp
->siport_sgbpool_dma_handle
,
2048 (caddr_t
)si_portp
->siport_sgbpool
,
2049 incore_sgbpool_size
,
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.
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.
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
);
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
,
2103 &si_portp
->siport_prbpool_dma_handle
) !=
2106 return (SI_FAILURE
);
2109 if (ddi_dma_mem_alloc(si_portp
->siport_prbpool_dma_handle
,
2112 DDI_DMA_RDWR
| DDI_DMA_CONSISTENT
,
2115 (caddr_t
*)&si_portp
->siport_prbpool
,
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
,
2126 (caddr_t
)si_portp
->siport_prbpool
,
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.
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
2170 si_find_dev_signature(
2171 si_ctl_state_t
*si_ctlp
,
2172 si_port_state_t
*si_portp
,
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",
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
] =
2195 si_portp
->siport_port_type
= PORT_TYPE_NODEV
;
2198 mutex_exit(&si_portp
->siport_mutex
);
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
);
2208 if (si_debug_flags
& SIDBG_DUMP_PRB
) {
2213 cmn_err(CE_WARN
, "si_find_dev_signature, prb: ");
2214 for (j
= 0; j
< (sizeof (si_prb_t
)); j
++) {
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
);
2228 /* Loop till the soft reset is finished. */
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. */
2238 /* Wait for 10 millisec */
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
)));
2255 signature
|= (0xff & ddi_get32(si_ctlp
->sictl_port_acc_handle
,
2256 (uint32_t *)(PORT_SIGNATURE_LSB(si_ctlp
,
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",
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
] =
2275 si_portp
->siport_port_type
= PORT_TYPE_MULTIPLIER
;
2276 mutex_exit(&si_portp
->siport_mutex
);
2277 (void) si_enumerate_port_multiplier(si_ctlp
,
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
] =
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",
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
] =
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",
2311 if (pmp
!= PORTMULT_CONTROL_PORT
) {
2312 /* We are behind port multiplier. */
2313 si_portp
->siport_portmult_state
.sipm_port_type
[pmp
] =
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.
2333 si_ctl_state_t
*si_ctlp
,
2334 si_port_state_t
*si_portp
,
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
*
2350 /* we start out with SATA_PKT_COMPLETED as the satapkt_reason */
2351 satapkt
->satapkt_reason
= SATA_PKT_COMPLETED
;
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
)) {
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
);
2367 mutex_exit(&si_portp
->siport_mutex
);
2369 delay(SI_1MS_TICKS
);
2370 #endif /* __lock_lint */
2371 mutex_enter(&si_portp
->siport_mutex
);
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 */
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
);
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
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
,
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.
2481 si_claim_free_slot(si_ctl_state_t
*si_ctlp
, si_port_state_t
*si_portp
, int port
)
2483 uint32_t free_slots
;
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;
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",
2507 * Builds the PRB for the sata packet and delivers it to controller.
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.
2518 si_ctl_state_t
*si_ctlp
,
2519 si_port_state_t
*si_portp
,
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
;
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
) {
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
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. */
2572 if (spkt
->satapkt_cmd
.satacmd_flags
.sata_data_direction
==
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
) {
2596 * satacmd_addr_type will be 0 for the commands below:
2600 * SATAC_DOWNLOAD_MICROCODE
2602 * SATAC_SET_FEATURES
2604 * SATAC_ID_PACKET_DEVICE
2606 * SATAC_READ_PORTMULT
2607 * SATAC_WRITE_PORTMULT
2614 case ATA_ADDR_LBA28
:
2616 SET_FIS_SECTOR(prb
->prb_fis
, cmd
->satacmd_lba_low_lsb
);
2619 SET_FIS_CYL_LOW(prb
->prb_fis
, cmd
->satacmd_lba_mid_lsb
);
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
);
2629 case ATA_ADDR_LBA48
:
2631 SET_FIS_SECTOR(prb
->prb_fis
, cmd
->satacmd_lba_low_lsb
);
2634 SET_FIS_CYL_LOW(prb
->prb_fis
, cmd
->satacmd_lba_mid_lsb
);
2637 SET_FIS_CYL_HI(prb
->prb_fis
, cmd
->satacmd_lba_high_lsb
);
2640 SET_FIS_SECTOR_EXP(prb
->prb_fis
, cmd
->satacmd_lba_low_msb
);
2643 SET_FIS_CYL_LOW_EXP(prb
->prb_fis
, cmd
->satacmd_lba_mid_msb
);
2646 SET_FIS_CYL_HI_EXP(prb
->prb_fis
, cmd
->satacmd_lba_high_msb
);
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
);
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
);
2687 SET_SGE_TRM(prb
->prb_sge1
);
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
);
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.",
2720 sgep
->sge_addr_low
= 0;
2721 sgep
->sge_addr_high
= 0;
2722 sgep
->sge_data_count
= 0;
2723 SET_SGE_TRM((*sgep
));
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",
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, "
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 */
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",
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 ******* */
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;
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
);
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 */
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.
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
]);
2852 "si_deliver_satpkt sgt: low, high, count link");
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
))
2859 ptr
= (int *)(void *)tmpsgep
;
2860 cmn_err(CE_WARN
, "%x %x %x %x",
2865 if (IS_SGE_TRM_SET((*tmpsgep
))) {
2873 #endif /* SI_DEBUG */
2876 POST_PRB_ADDR(si_ctlp
, si_portp
, port
, 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.
2892 si_initialize_controller(si_ctl_state_t
*si_ctlp
)
2894 uint32_t port_status
;
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
|
2949 INTR_PHYRDY_CHANGE
|
2950 INTR_COMWAKE_RECEIVED
|
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
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
)),
2979 delay(SI_10MS_TICKS
); /* give time for COMRESET to percolate */
2980 #endif /* __lock_lint */
2983 * Now fetch the SControl again and rewrite the
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
)),
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.
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
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.
3024 /* Wait for 10 millisec */
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, "
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
=
3048 mutex_exit(&si_portp
->siport_mutex
);
3052 /* Wait until Port Ready */
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.
3065 /* Wait for 10 millisec */
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",
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
);
3087 si_ctlp
->sictl_ports
[port
]->siport_port_type
=
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
,
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.
3115 si_deinitialize_controller(si_ctl_state_t
*si_ctlp
)
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.
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",
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
)),
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.
3183 si_enumerate_port_multiplier(
3184 si_ctl_state_t
*si_ctlp
,
3185 si_port_state_t
*si_portp
,
3188 uint32_t num_dev_ports
= 0;
3190 uint32_t SControl
= 0;
3191 uint32_t SStatus
= 0;
3192 uint32_t SError
= 0;
3195 SIDBG_P(SIDBG_INIT
, si_portp
,
3196 "si_enumerate_port_multiplier entered: port: %d",
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",
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
)) {
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
)) {
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
)) {
3248 /* Wait for PHYRDY by polling SStatus (i.e. PSCR[0]). */
3251 if (si_read_portmult_reg(si_ctlp
, si_portp
, port
,
3252 pmport
, PSCR_REG0
, &SStatus
)) {
3255 SIDBG_P(SIDBG_POLL_LOOP
, si_portp
,
3256 "looping for PHYRDY: SStatus: %x",
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
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.
3277 /* Wait for 10 millisec */
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",
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",
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
)) {
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
)) {
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.
3334 si_read_portmult_reg(
3335 si_ctl_state_t
*si_ctlp
,
3336 si_port_state_t
*si_portp
,
3344 uint32_t *prb_word_ptr
;
3346 uint32_t slot_status
;
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
);
3376 if (si_debug_flags
& SIDBG_DUMP_PRB
) {
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 */
3390 POST_PRB_ADDR(si_ctlp
, si_portp
, port
, slot
);
3392 /* Loop till the command is finished. */
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",
3401 if (loop_count
++ > SI_POLLRATE_SLOTSTATUS
) {
3402 /* We are effectively timing out after 0.5 sec. */
3406 /* Wait for 10 millisec */
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",
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.
3455 si_write_portmult_reg(
3456 si_ctl_state_t
*si_ctlp
,
3457 si_port_state_t
*si_portp
,
3465 uint32_t *prb_word_ptr
;
3466 uint32_t slot_status
;
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
);
3503 if (si_debug_flags
& SIDBG_DUMP_PRB
) {
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 */
3517 POST_PRB_ADDR(si_ctlp
, si_portp
, port
, slot
);
3519 /* Loop till the command is finished. */
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",
3528 if (loop_count
++ > SI_POLLRATE_SLOTSTATUS
) {
3529 /* We are effectively timing out after 0.5 sec. */
3533 /* Wait for 10 millisec */
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",
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.
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 */
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.
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
;
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
) !=
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
++) {
3646 if (!(global_intr_status
& mask
)) {
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",
3662 if (port_intr_status
& INTR_COMMAND_COMPLETE
) {
3663 (void) si_intr_command_complete(si_ctlp
, si_portp
,
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
,
3674 mutex_exit(&si_portp
->siport_mutex
);
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
,
3705 if (port_intr_status
& INTR_COMWAKE_RECEIVED
) {
3706 (void) si_intr_comwake_rcvd(si_ctlp
, si_portp
,
3710 if (port_intr_status
& INTR_UNRECOG_FIS
) {
3711 (void) si_intr_unrecognised_fis(si_ctlp
, si_portp
,
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
,
3724 if (port_intr_status
& INTR_CRC_ERROR
) {
3725 (void) si_intr_crc_err_threshold(si_ctlp
, si_portp
,
3729 if (port_intr_status
& INTR_HANDSHAKE_ERROR
) {
3730 (void) si_intr_handshake_err_threshold(si_ctlp
,
3734 if (port_intr_status
& INTR_SETDEVBITS_NOTIFY
) {
3735 (void) si_intr_set_devbits_notify(si_ctlp
, si_portp
,
3740 return (DDI_INTR_CLAIMED
);
3744 * Interrupt which indicates that one or more commands have successfully
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.
3752 si_intr_command_complete(
3753 si_ctl_state_t
*si_ctlp
,
3754 si_port_state_t
*si_portp
,
3758 uint32_t slot_status
;
3759 uint32_t finished_tags
;
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
,
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) {
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
,
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
,
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.
3827 si_schedule_intr_command_error(
3828 si_ctl_state_t
*si_ctlp
,
3829 si_port_state_t
*si_portp
,
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
);
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()
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
;
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
3884 * We reset the device and mop the commands on the port.
3887 si_intr_command_error(
3888 si_ctl_state_t
*si_ctlp
,
3889 si_port_state_t
*si_portp
,
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",
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
);
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
);
3926 case CMD_ERR_DATAFISERROR
:
3927 si_fm_ereport(si_ctlp
, DDI_FM_DEVICE_INTERN_CORR
,
3929 si_error_recovery_DATAFISERROR(si_ctlp
, si_portp
, port
);
3930 ddi_fm_service_impact(si_ctlp
->sictl_devinfop
,
3931 DDI_SERVICE_UNAFFECTED
);
3934 case CMD_ERR_SENDFISERROR
:
3935 si_fm_ereport(si_ctlp
, DDI_FM_DEVICE_INTERN_CORR
,
3937 si_error_recovery_SENDFISERROR(si_ctlp
, si_portp
, port
);
3938 ddi_fm_service_impact(si_ctlp
->sictl_devinfop
,
3939 DDI_SERVICE_UNAFFECTED
);
3943 si_fm_ereport(si_ctlp
, DDI_FM_DEVICE_INTERN_CORR
,
3945 si_error_recovery_default(si_ctlp
, si_portp
, port
);
3946 ddi_fm_service_impact(si_ctlp
->sictl_devinfop
,
3947 DDI_SERVICE_UNAFFECTED
);
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
,
3970 SIDBG_P(SIDBG_ERRS
, si_portp
,
3971 "si3124: si_intr_command_error: "
3972 "slot_status:0x%x, pending_tags: 0x%x",
3974 si_portp
->siport_pending_tags
);
3976 si_portp
->mopping_in_progress
++;
3978 si_mop_commands(si_ctlp
,
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.
4010 si_recover_portmult_errors(
4011 si_ctl_state_t
*si_ctlp
,
4012 si_port_state_t
*si_portp
,
4015 uint32_t command_error
, slot_status
, port_status
;
4019 _NOTE(ASSUMING_PROTECTED(si_portp
))
4021 SIDBG_P(SIDBG_ERRS
, si_portp
,
4022 "si_recover_portmult_errors: port: 0x%x",
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
);
4040 si_portp
->siport_err_tags_nonSDBERROR
|= (0x1 << failed_slot
);
4043 /* Now we drain the pending commands. */
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
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
)) {
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
,
4071 if (command_error
== CMD_ERR_SDBERROR
) {
4072 si_portp
->siport_err_tags_SDBERROR
|=
4073 (0x1 << failed_slot
);
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. */
4085 /* Wait for 10 millisec */
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.
4115 si_error_recovery_DEVICEERROR(
4116 si_ctl_state_t
*si_ctlp
,
4117 si_port_state_t
*si_portp
,
4120 uint32_t port_status
;
4123 _NOTE(ASSUMING_PROTECTED(si_portp
))
4125 SIDBG_P(SIDBG_ERRS
, si_portp
,
4126 "si_error_recovery_DEVICEERROR: port: 0x%x",
4129 if (si_portp
->siport_port_type
== PORT_TYPE_MULTIPLIER
) {
4130 si_recover_portmult_errors(si_ctlp
, si_portp
, port
);
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.
4151 si_error_recovery_SDBERROR(
4152 si_ctl_state_t
*si_ctlp
,
4153 si_port_state_t
*si_portp
,
4156 uint32_t port_status
;
4159 _NOTE(ASSUMING_PROTECTED(si_portp
))
4161 SIDBG_P(SIDBG_ERRS
, si_portp
,
4162 "si3124: si_error_recovery_SDBERROR: port: 0x%x",
4165 if (si_portp
->siport_port_type
== PORT_TYPE_MULTIPLIER
) {
4166 si_recover_portmult_errors(si_ctlp
, si_portp
, port
);
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.
4186 si_error_recovery_DATAFISERROR(
4187 si_ctl_state_t
*si_ctlp
,
4188 si_port_state_t
*si_portp
,
4191 uint32_t port_status
;
4194 _NOTE(ASSUMING_PROTECTED(si_portp
))
4196 SIDBG_P(SIDBG_ERRS
, si_portp
,
4197 "si3124: si_error_recovery_DATAFISERROR: port: 0x%x",
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
,
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.
4226 si_error_recovery_SENDFISERROR(
4227 si_ctl_state_t
*si_ctlp
,
4228 si_port_state_t
*si_portp
,
4231 uint32_t port_status
;
4234 _NOTE(ASSUMING_PROTECTED(si_portp
))
4236 SIDBG_P(SIDBG_ERRS
, si_portp
,
4237 "si3124: si_error_recovery_SENDFISERROR: port: 0x%x",
4240 if (si_portp
->siport_port_type
== PORT_TYPE_MULTIPLIER
) {
4241 si_recover_portmult_errors(si_ctlp
, si_portp
, port
);
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
,
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.
4259 si_error_recovery_default(
4260 si_ctl_state_t
*si_ctlp
,
4261 si_port_state_t
*si_portp
,
4264 uint32_t port_status
;
4267 _NOTE(ASSUMING_PROTECTED(si_portp
))
4269 SIDBG_P(SIDBG_ERRS
, si_portp
,
4270 "si3124: si_error_recovery_default: port: 0x%x",
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
,
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.
4289 si_read_log_ext(si_ctl_state_t
*si_ctlp
, si_port_state_t
*si_portp
, int port
)
4294 uint32_t slot_status
;
4296 uint32_t *prb_word_ptr
;
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
) {
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
);
4323 if (si_debug_flags
& SIDBG_DUMP_PRB
) {
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 */
4337 POST_PRB_ADDR(si_ctlp
, si_portp
, port
, slot
);
4339 /* Loop till the command is finished. */
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",
4348 if (loop_count
++ > SI_POLLRATE_SLOTSTATUS
) {
4349 /* We are effectively timing out after 0.5 sec. */
4353 /* Wait for 10 millisec */
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",
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
);
4400 * Dump the error message to the log.
4403 si_log_error_message(si_ctl_state_t
*si_ctlp
, int port
, uint32_t command_error
)
4407 _NOTE(ARGUNUSED(si_ctlp
))
4408 _NOTE(ARGUNUSED(port
))
4409 #endif /* __lock_lint */
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"
4421 case CMD_ERR_SDBERROR
:
4422 errstr
= "NCQ Error: Error bit set in register - device"
4426 case CMD_ERR_DATAFISERROR
:
4427 errstr
= "Error in data FIS not detected by device";
4430 case CMD_ERR_SENDFISERROR
:
4431 errstr
= "Initial command FIS transmission failed";
4434 case CMD_ERR_INCONSISTENTSTATE
:
4435 errstr
= "Inconsistency in protocol";
4438 case CMD_ERR_DIRECTIONERROR
:
4439 errstr
= "DMA direction flag does not match the command";
4442 case CMD_ERR_UNDERRUNERROR
:
4443 errstr
= "Run out of scatter gather entries while writing data";
4446 case CMD_ERR_OVERRUNERROR
:
4447 errstr
= "Run out of scatter gather entries while reading data";
4450 case CMD_ERR_PACKETPROTOCOLERROR
:
4451 errstr
= "Packet protocol error";
4454 case CMD_ERR_PLDSGTERRORBOUNDARY
:
4455 errstr
= "Scatter/gather table not on quadword boundary";
4458 case CMD_ERR_PLDSGTERRORTARETABORT
:
4459 errstr
= "PCI(X) Target abort while fetching scatter/gather"
4463 case CMD_ERR_PLDSGTERRORMASTERABORT
:
4464 errstr
= "PCI(X) Master abort while fetching scatter/gather"
4468 case CMD_ERR_PLDSGTERRORPCIERR
:
4469 errstr
= "PCI(X) parity error while fetching scatter/gather"
4473 case CMD_ERR_PLDCMDERRORBOUNDARY
:
4474 errstr
= "PRB not on quadword boundary";
4477 case CMD_ERR_PLDCMDERRORTARGETABORT
:
4478 errstr
= "PCI(X) Target abort while fetching PRB";
4481 case CMD_ERR_PLDCMDERRORMASTERABORT
:
4482 errstr
= "PCI(X) Master abort while fetching PRB";
4485 case CMD_ERR_PLDCMDERORPCIERR
:
4486 errstr
= "PCI(X) parity error while fetching PRB";
4489 case CMD_ERR_PSDERRORTARGETABORT
:
4490 errstr
= "PCI(X) Target abort during data transfer";
4493 case CMD_ERR_PSDERRORMASTERABORT
:
4494 errstr
= "PCI(X) Master abort during data transfer";
4497 case CMD_ERR_PSDERRORPCIERR
:
4498 errstr
= "PCI(X) parity error during data transfer";
4501 case CMD_ERR_SENDSERVICEERROR
:
4502 errstr
= "FIS received while sending service FIS in"
4503 " legacy queuing operation";
4507 errstr
= "Unknown Error";
4512 SIDBG_P(SIDBG_ERRS
, si_portp
,
4513 "command error: error: %s",
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
4530 * We are not interested in this interrupt; we just log a debug message.
4535 si_ctl_state_t
*si_ctlp
,
4536 si_port_state_t
*si_portp
,
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.
4552 si_ctl_state_t
*si_ctlp
,
4553 si_port_state_t
*si_portp
,
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.
4565 si_intr_phy_ready_change(
4566 si_ctl_state_t
*si_ctlp
,
4567 si_port_state_t
*si_portp
,
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
));
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
;
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
->\
4628 SATA_EVNT_LINK_LOST
|
4629 SATA_EVNT_LINK_ESTABLISHED
);
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
->\
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
->
4666 SATA_EVNT_LINK_LOST
);
4668 si_portp
->siport_port_type
= PORT_TYPE_NODEV
;
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
4687 * We are not interested in this interrupt; we just log a debug message.
4691 si_intr_comwake_rcvd(
4692 si_ctl_state_t
*si_ctlp
,
4693 si_port_state_t
*si_portp
,
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
4705 * We are not interested in this interrupt; we just log a debug message.
4709 si_intr_unrecognised_fis(
4710 si_ctl_state_t
*si_ctlp
,
4711 si_port_state_t
*si_portp
,
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
4723 * We are not interested in this interrupt; we just log a debug message.
4727 si_intr_dev_xchanged(
4728 si_ctl_state_t
*si_ctlp
,
4729 si_port_state_t
*si_portp
,
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.
4746 si_intr_decode_err_threshold(
4747 si_ctl_state_t
*si_ctlp
,
4748 si_port_state_t
*si_portp
,
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.
4764 si_intr_crc_err_threshold(
4765 si_ctl_state_t
*si_ctlp
,
4766 si_port_state_t
*si_portp
,
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.
4782 si_intr_handshake_err_threshold(
4783 si_ctl_state_t
*si_ctlp
,
4784 si_port_state_t
*si_portp
,
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.
4800 si_intr_set_devbits_notify(
4801 si_ctl_state_t
*si_ctlp
,
4802 si_port_state_t
*si_portp
,
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.
4818 si_enable_port_interrupts(si_ctl_state_t
*si_ctlp
, int port
)
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",
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
),
4841 * Enable interrupts for all the ports.
4844 si_enable_all_interrupts(si_ctl_state_t
*si_ctlp
)
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.
4860 si_disable_port_interrupts(si_ctl_state_t
*si_ctlp
, int port
)
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
),
4879 * Disable interrupts for all the ports.
4882 si_disable_all_interrupts(si_ctl_state_t
*si_ctlp
)
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.
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.
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.
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",
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
);
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.
5143 si_rem_intrs(si_ctl_state_t
*si_ctlp
)
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
);
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.
5185 si_reset_dport_wait_till_ready(
5186 si_ctl_state_t
*si_ctlp
,
5187 si_port_state_t
*si_portp
,
5191 uint32_t port_status
;
5193 sata_device_t sdevice
;
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
);
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
)),
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
)),
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.
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
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. */
5281 /* Wait for 10 millisec */
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, \
5294 /* Now check for port readiness. */
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. */
5305 /* Wait for 10 millisec */
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",
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
;
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
,
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
|
5374 INTR_PHYRDY_CHANGE
|
5375 INTR_COMWAKE_RECEIVED
|
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
,
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.
5408 si_schedule_port_initialize(
5409 si_ctl_state_t
*si_ctlp
,
5410 si_port_state_t
*si_portp
,
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");
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()
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
;
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
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.
5468 si_initialize_port_wait_till_ready(si_ctl_state_t
*si_ctlp
, int port
)
5470 uint32_t port_status
;
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 */
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: "
5491 /* We are effectively timing out after 0.5 sec. */
5495 /* Wait for 10 millisec */
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",
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.
5530 si_ctl_state_t
*si_ctlp
,
5531 si_port_state_t
*si_portp
,
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
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",
5567 si_mop_commands(si_ctlp
,
5571 0, /* failed_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
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
;
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 */
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
) {
5612 mutex_enter(&si_portp
->siport_mutex
);
5614 if (si_portp
->siport_port_type
== PORT_TYPE_NODEV
) {
5615 mutex_exit(&si_portp
->siport_mutex
);
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
);
5628 pending_tags
= si_portp
->siport_pending_tags
;
5630 while (pending_tags
) {
5631 tmpslot
= ddi_ffs(pending_tags
) - 1;
5632 if (tmpslot
== -1) {
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
5647 watched_cycles
= (int)(intptr_t)
5648 satapkt
->satapkt_hba_driver_private
;
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
,
5657 "watchdog: timedout_tags: 0x%x",
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
);
5692 * The IO fault service error handling callback function
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
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
,
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
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
;
5790 si_check_acc_handle(ddi_acc_handle_t handle
)
5794 ASSERT(handle
!= NULL
);
5795 ddi_fm_acc_err_get(handle
, &de
, DDI_FME_VERSION
);
5796 return (de
.fme_status
);
5800 si_check_dma_handle(ddi_dma_handle_t handle
)
5804 ASSERT(handle
!= NULL
);
5805 ddi_fm_dma_err_get(handle
, &de
, DDI_FME_VERSION
);
5806 return (de
.fme_status
);
5810 si_check_ctl_handles(si_ctl_state_t
*si_ctlp
)
5812 if ((si_check_acc_handle(si_ctlp
->sictl_pci_conf_handle
)
5814 (si_check_acc_handle(si_ctlp
->sictl_global_acc_handle
)
5816 (si_check_acc_handle(si_ctlp
->sictl_port_acc_handle
)
5818 return (DDI_FAILURE
);
5821 return (DDI_SUCCESS
);
5825 * WARNING: The caller is expected to obtain the siport_mutex
5826 * before calling us.
5829 si_check_port_handles(si_port_state_t
*si_portp
)
5831 if ((si_check_dma_handle(si_portp
->siport_prbpool_dma_handle
)
5833 (si_check_acc_handle(si_portp
->siport_prbpool_acc_handle
)
5835 (si_check_dma_handle(si_portp
->siport_sgbpool_dma_handle
)
5837 (si_check_acc_handle(si_portp
->siport_sgbpool_acc_handle
)
5839 return (DDI_FAILURE
);
5842 return (DDI_SUCCESS
);
5846 si_fm_ereport(si_ctl_state_t
*si_ctlp
, char *detail
, char *payload
)
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
,
5857 FM_VERSION
, DATA_TYPE_UINT8
, FM_EREPORT_VERSION
,
5858 "detailed_err_type", DATA_TYPE_STRING
, payload
,
5867 si_log(si_ctl_state_t
*si_ctlp
, si_port_state_t
*si_portp
, char *fmt
, ...)
5871 mutex_enter(&si_log_mutex
);
5875 if (si_portp
== NULL
&& si_ctlp
== NULL
) {
5876 sata_vtrace_debug(NULL
, fmt
, ap
);
5878 mutex_exit(&si_log_mutex
);
5882 if (si_portp
== NULL
&& si_ctlp
!= NULL
) {
5883 sata_vtrace_debug(si_ctlp
->sictl_devinfop
, fmt
, ap
);
5885 mutex_exit(&si_log_mutex
);
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
);
5899 mutex_exit(&si_log_mutex
);
5903 sata_vtrace_debug(si_portp
->siport_ctlp
->sictl_devinfop
,
5908 mutex_exit(&si_log_mutex
);
5913 si_copy_out_regs(sata_cmd_t
*scmd
, si_ctl_state_t
*si_ctlp
, uint8_t port
,
5916 uint32_t *fis_word_ptr
;
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
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
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
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.
6053 si_quiesce(dev_info_t
*dip
)
6055 si_ctl_state_t
*si_ctlp
;
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
);