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