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