xref: /illumos-gate/usr/src/uts/common/io/sata/adapters/si3124/si3124.c (revision 794f0adb050e571bbfde4d2a19b9f88b852079dd)
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 0:
2568 		/*
2569 		 * satacmd_addr_type will be 0 for the commands below:
2570 		 * 	SATAC_PACKET
2571 		 * 	SATAC_IDLE_IM
2572 		 * 	SATAC_STANDBY_IM
2573 		 * 	SATAC_DOWNLOAD_MICROCODE
2574 		 * 	SATAC_FLUSH_CACHE
2575 		 * 	SATAC_SET_FEATURES
2576 		 * 	SATAC_SMART
2577 		 * 	SATAC_ID_PACKET_DEVICE
2578 		 * 	SATAC_ID_DEVICE
2579 		 * 	SATAC_READ_PORTMULT
2580 		 * 	SATAC_WRITE_PORTMULT
2581 		 */
2582 		/* FALLTHRU */
2583 
2584 	case ATA_ADDR_LBA:
2585 		/* FALLTHRU */
2586 
2587 	case ATA_ADDR_LBA28:
2588 		/* LBA[7:0] */
2589 		SET_FIS_SECTOR(prb->prb_fis, cmd->satacmd_lba_low_lsb);
2590 
2591 		/* LBA[15:8] */
2592 		SET_FIS_CYL_LOW(prb->prb_fis, cmd->satacmd_lba_mid_lsb);
2593 
2594 		/* LBA[23:16] */
2595 		SET_FIS_CYL_HI(prb->prb_fis, cmd->satacmd_lba_high_lsb);
2596 
2597 		/* LBA [27:24] (also called dev_head) */
2598 		SET_FIS_DEV_HEAD(prb->prb_fis, cmd->satacmd_device_reg);
2599 
2600 		break;
2601 
2602 	case ATA_ADDR_LBA48:
2603 		/* LBA[7:0] */
2604 		SET_FIS_SECTOR(prb->prb_fis, cmd->satacmd_lba_low_lsb);
2605 
2606 		/* LBA[15:8] */
2607 		SET_FIS_CYL_LOW(prb->prb_fis, cmd->satacmd_lba_mid_lsb);
2608 
2609 		/* LBA[23:16] */
2610 		SET_FIS_CYL_HI(prb->prb_fis, cmd->satacmd_lba_high_lsb);
2611 
2612 		/* LBA [31:24] */
2613 		SET_FIS_SECTOR_EXP(prb->prb_fis, cmd->satacmd_lba_low_msb);
2614 
2615 		/* LBA [39:32] */
2616 		SET_FIS_CYL_LOW_EXP(prb->prb_fis, cmd->satacmd_lba_mid_msb);
2617 
2618 		/* LBA [47:40] */
2619 		SET_FIS_CYL_HI_EXP(prb->prb_fis, cmd->satacmd_lba_high_msb);
2620 
2621 		/* Set dev_head */
2622 		SET_FIS_DEV_HEAD(prb->prb_fis, cmd->satacmd_device_reg);
2623 
2624 		/* Set the extended sector count and features */
2625 		SET_FIS_SECTOR_COUNT_EXP(prb->prb_fis,
2626 		    cmd->satacmd_sec_count_msb);
2627 		SET_FIS_FEATURES_EXP(prb->prb_fis,
2628 		    cmd->satacmd_features_reg_ext);
2629 
2630 		break;
2631 
2632 	}
2633 
2634 	if (cmd->satacmd_flags.sata_queued) {
2635 		/*
2636 		 * For queued commands, the TAG for the sector count lsb is
2637 		 * generated from current slot number.
2638 		 */
2639 		SET_FIS_SECTOR_COUNT(prb->prb_fis, slot << 3);
2640 	}
2641 
2642 	if ((cmd->satacmd_cmd_reg == SATAC_WRITE_FPDMA_QUEUED) ||
2643 	    (cmd->satacmd_cmd_reg == SATAC_READ_FPDMA_QUEUED)) {
2644 		si_portp->siport_pending_ncq_count++;
2645 	}
2646 
2647 	/* *** now fill the scatter gather list ******* */
2648 
2649 	if (is_atapi) { /* It is an ATAPI drive */
2650 		/* atapi command goes into sge0 */
2651 		bcopy(cmd->satacmd_acdb, &prb->prb_sge0, sizeof (si_sge_t));
2652 
2653 		/* Now fill sge1 with pointer to external SGT. */
2654 		if (spkt->satapkt_cmd.satacmd_num_dma_cookies) {
2655 			prb->prb_sge1.sge_addr =
2656 			    si_portp->siport_sgbpool_physaddr +
2657 			    slot * sizeof (si_sgblock_t) * si_dma_sg_number;
2658 			SET_SGE_LNK(prb->prb_sge1);
2659 		} else {
2660 			SET_SGE_TRM(prb->prb_sge1);
2661 		}
2662 	} else {
2663 		/* Fill the sge0 */
2664 		if (spkt->satapkt_cmd.satacmd_num_dma_cookies) {
2665 			prb->prb_sge0.sge_addr =
2666 			    si_portp->siport_sgbpool_physaddr +
2667 			    slot * sizeof (si_sgblock_t) * si_dma_sg_number;
2668 			SET_SGE_LNK(prb->prb_sge0);
2669 
2670 		} else {
2671 			SET_SGE_TRM(prb->prb_sge0);
2672 		}
2673 
2674 		/* sge1 is left empty in non-ATAPI case */
2675 	}
2676 
2677 	bzero(&si_portp->siport_sgbpool[slot * si_dma_sg_number],
2678 	    sizeof (si_sgblock_t) * si_dma_sg_number);
2679 
2680 	ncookies = spkt->satapkt_cmd.satacmd_num_dma_cookies;
2681 	ASSERT(ncookies <= (SGE_LENGTH(si_dma_sg_number)));
2682 
2683 	SIDBG1(SIDBG_COOKIES, si_ctlp, "total ncookies: %d", ncookies);
2684 	if (ncookies == 0) {
2685 		sgbp = &si_portp->siport_sgbpool[slot * si_dma_sg_number];
2686 		sgtp = &sgbp->sgb_sgt[0];
2687 		sgep = &sgtp->sgt_sge[0];
2688 
2689 		/* No cookies. Terminate the chain. */
2690 		SIDBG0(SIDBG_COOKIES, si_ctlp, "empty cookies: terminating.");
2691 
2692 		sgep->sge_addr_low = 0;
2693 		sgep->sge_addr_high = 0;
2694 		sgep->sge_data_count = 0;
2695 		SET_SGE_TRM((*sgep));
2696 
2697 		goto sgl_fill_done;
2698 	}
2699 
2700 	for (i = 0, cookie_index = 0,
2701 	    sgbp = &si_portp->siport_sgbpool[slot * si_dma_sg_number];
2702 	    i < si_dma_sg_number; i++) {
2703 
2704 		sgtp = &sgbp->sgb_sgt[0] + i;
2705 
2706 		/* Now fill the first 3 entries of SGT in the loop below. */
2707 		for (j = 0, sgep = &sgtp->sgt_sge[0];
2708 		    ((j < 3) && (cookie_index < ncookies-1));
2709 		    j++, cookie_index++, sgep++)  {
2710 			ASSERT(cookie_index < ncookies);
2711 			SIDBG2(SIDBG_COOKIES, si_ctlp,
2712 			    "inner loop: cookie_index: %d, ncookies: %d",
2713 			    cookie_index,
2714 			    ncookies);
2715 			cookie = spkt->satapkt_cmd.
2716 			    satacmd_dma_cookie_list[cookie_index];
2717 
2718 			sgep->sge_addr_low = cookie._dmu._dmac_la[0];
2719 			sgep->sge_addr_high = cookie._dmu._dmac_la[1];
2720 			sgep->sge_data_count = (uint32_t)cookie.dmac_size;
2721 		}
2722 
2723 		/*
2724 		 * If this happens to be the last cookie, we terminate it here.
2725 		 * Otherwise, we link to next SGT.
2726 		 */
2727 
2728 		if (cookie_index == ncookies-1) {
2729 			/* This is the last cookie. Terminate the chain. */
2730 			SIDBG2(SIDBG_COOKIES, si_ctlp,
2731 			    "filling the last: cookie_index: %d, "
2732 			    "ncookies: %d",
2733 			    cookie_index,
2734 			    ncookies);
2735 			cookie = spkt->satapkt_cmd.
2736 			    satacmd_dma_cookie_list[cookie_index];
2737 
2738 			sgep->sge_addr_low = cookie._dmu._dmac_la[0];
2739 			sgep->sge_addr_high = cookie._dmu._dmac_la[1];
2740 			sgep->sge_data_count = (uint32_t)cookie.dmac_size;
2741 			SET_SGE_TRM((*sgep));
2742 
2743 			break; /* we break the loop */
2744 
2745 		} else {
2746 			/* This is not the last one. So link it. */
2747 			SIDBG2(SIDBG_COOKIES, si_ctlp,
2748 			    "linking SGT: cookie_index: %d, ncookies: %d",
2749 			    cookie_index,
2750 			    ncookies);
2751 			sgep->sge_addr = si_portp->siport_sgbpool_physaddr +
2752 			    slot * sizeof (si_sgblock_t) * si_dma_sg_number +
2753 			    (i+1) * sizeof (si_sgt_t);
2754 
2755 			SET_SGE_LNK((*sgep));
2756 		}
2757 
2758 	}
2759 
2760 	/* *** finished filling the scatter gather list ******* */
2761 
2762 sgl_fill_done:
2763 	/* Now remember the sata packet in siport_slot_pkts[]. */
2764 	si_portp->siport_slot_pkts[slot] = spkt;
2765 
2766 	/*
2767 	 * We are overloading satapkt_hba_driver_private with
2768 	 * watched_cycle count.
2769 	 */
2770 	spkt->satapkt_hba_driver_private = (void *)(intptr_t)0;
2771 
2772 	if (is_atapi) {
2773 		/* program the packet_lenth if it is atapi device. */
2774 
2775 
2776 #ifdef ATAPI_2nd_PHASE
2777 		/*
2778 		 * Framework needs to calculate the acdb_len based on
2779 		 * identify packet data. This needs to be accomplished
2780 		 * in second phase of the project.
2781 		 */
2782 		ASSERT((cmd->satacmd_acdb_len == 12) ||
2783 		    (cmd->satacmd_acdb_len == 16));
2784 		SIDBG1(SIDBG_VERBOSE, si_ctlp, "deliver: acdb_len: %d",
2785 		    cmd->satacmd_acdb_len);
2786 
2787 		if (cmd->satacmd_acdb_len == 16) {
2788 			ddi_put32(si_ctlp->sictl_port_acc_handle,
2789 			    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
2790 			    PORT_CONTROL_SET_BITS_PACKET_LEN);
2791 		} else {
2792 			ddi_put32(si_ctlp->sictl_port_acc_handle,
2793 			    (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
2794 			    PORT_CONTROL_CLEAR_BITS_PACKET_LEN);
2795 		}
2796 
2797 #else /* ATAPI_2nd_PHASE */
2798 		/* hard coding for now to 12 bytes */
2799 		ddi_put32(si_ctlp->sictl_port_acc_handle,
2800 		    (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
2801 		    PORT_CONTROL_CLEAR_BITS_PACKET_LEN);
2802 #endif /* ATAPI_2nd_PHASE */
2803 	}
2804 
2805 
2806 #if SI_DEBUG
2807 	if (si_debug_flags & SIDBG_DUMP_PRB) {
2808 		if (!(is_atapi && (prb->prb_sge0.sge_addr_low == 0))) {
2809 			/*
2810 			 * Do not dump the atapi Test-Unit-Ready commands.
2811 			 * The sd_media_watch spews too many of these.
2812 			 */
2813 			int *ptr;
2814 			si_sge_t *tmpsgep;
2815 			int j;
2816 
2817 			ptr = (int *)(void *)prb;
2818 			cmn_err(CE_WARN, "si_deliver_satpkt prb: ");
2819 			for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
2820 				cmn_err(CE_WARN, "%x ", ptr[j]);
2821 			}
2822 
2823 			cmn_err(CE_WARN,
2824 			    "si_deliver_satpkt sgt: low, high, count link");
2825 			for (j = 0,
2826 			    tmpsgep = (si_sge_t *)
2827 			    &si_portp->siport_sgbpool[slot * si_dma_sg_number];
2828 			    j < (sizeof (si_sgblock_t)/ sizeof (si_sge_t))
2829 			    *si_dma_sg_number;
2830 			    j++, tmpsgep++) {
2831 				ptr = (int *)(void *)tmpsgep;
2832 				cmn_err(CE_WARN, "%x %x %x %x",
2833 				    ptr[0],
2834 				    ptr[1],
2835 				    ptr[2],
2836 				    ptr[3]);
2837 				if (IS_SGE_TRM_SET((*tmpsgep))) {
2838 					break;
2839 				}
2840 
2841 			}
2842 		}
2843 
2844 	}
2845 #endif  /* SI_DEBUG */
2846 
2847 	/* Deliver PRB */
2848 	POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
2849 
2850 	return (slot);
2851 }
2852 
2853 /*
2854  * Initialize the controller and set up driver data structures.
2855  *
2856  * This routine can be called from three separate cases: DDI_ATTACH, PM_LEVEL_D0
2857  * and DDI_RESUME. The DDI_ATTACH case is different from other two cases; the
2858  * memory allocation & device signature probing are attempted only during
2859  * DDI_ATTACH case. In the case of PM_LEVEL_D0 & DDI_RESUME, we are starting
2860  * from a previously initialized state; so there is no need to allocate memory
2861  * or to attempt probing the device signatures.
2862  */
2863 static int
2864 si_initialize_controller(si_ctl_state_t *si_ctlp)
2865 {
2866 	uint32_t port_status;
2867 	uint32_t SStatus;
2868 	uint32_t SControl;
2869 	int port;
2870 	int loop_count = 0;
2871 	si_port_state_t *si_portp;
2872 
2873 	SIDBG0(SIDBG_INIT|SIDBG_ENTRY, si_ctlp,
2874 	    "si3124: si_initialize_controller entered");
2875 
2876 	mutex_enter(&si_ctlp->sictl_mutex);
2877 
2878 	/* Remove the Global Reset. */
2879 	ddi_put32(si_ctlp->sictl_global_acc_handle,
2880 	    (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp),
2881 	    GLOBAL_CONTROL_REG_BITS_CLEAR);
2882 
2883 	for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
2884 
2885 		if (si_ctlp->sictl_flags & SI_ATTACH) {
2886 			/*
2887 			 * We allocate the port state only during attach
2888 			 * sequence. We don't want to do it during
2889 			 * suspend/resume sequence.
2890 			 */
2891 			if (si_alloc_port_state(si_ctlp, port)) {
2892 				mutex_exit(&si_ctlp->sictl_mutex);
2893 				return (SI_FAILURE);
2894 			}
2895 		}
2896 
2897 		si_portp = si_ctlp->sictl_ports[port];
2898 		mutex_enter(&si_portp->siport_mutex);
2899 
2900 		/* Clear Port Reset. */
2901 		ddi_put32(si_ctlp->sictl_port_acc_handle,
2902 		    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
2903 		    PORT_CONTROL_SET_BITS_PORT_RESET);
2904 		ddi_put32(si_ctlp->sictl_port_acc_handle,
2905 		    (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
2906 		    PORT_CONTROL_CLEAR_BITS_PORT_RESET);
2907 
2908 		/*
2909 		 * Arm the interrupts for: Cmd completion, Cmd error,
2910 		 * Port Ready, PM Change, PhyRdyChange, Commwake,
2911 		 * UnrecFIS, Devxchanged, SDBNotify.
2912 		 */
2913 		ddi_put32(si_ctlp->sictl_port_acc_handle,
2914 		    (uint32_t *)PORT_INTERRUPT_ENABLE_SET(si_ctlp, port),
2915 		    (INTR_COMMAND_COMPLETE |
2916 		    INTR_COMMAND_ERROR |
2917 		    INTR_PORT_READY |
2918 		    INTR_POWER_CHANGE |
2919 		    INTR_PHYRDY_CHANGE |
2920 		    INTR_COMWAKE_RECEIVED |
2921 		    INTR_UNRECOG_FIS |
2922 		    INTR_DEV_XCHANGED |
2923 		    INTR_SETDEVBITS_NOTIFY));
2924 
2925 		/* Now enable the interrupts. */
2926 		si_enable_port_interrupts(si_ctlp, port);
2927 
2928 		/*
2929 		 * The following PHY initialization is redundant in
2930 		 * in x86 since the BIOS anyway does this as part of
2931 		 * device enumeration during the power up. But this
2932 		 * is a required step in sparc since there is no BIOS.
2933 		 *
2934 		 * The way to initialize the PHY is to write a 1 and then
2935 		 * a 0 to DET field of SControl register.
2936 		 */
2937 
2938 		/*
2939 		 * Fetch the current SControl before writing the
2940 		 * DET part with 1
2941 		 */
2942 		SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
2943 		    (uint32_t *)PORT_SCONTROL(si_ctlp, port));
2944 		SCONTROL_SET_DET(SControl, SCONTROL_DET_COMRESET);
2945 		ddi_put32(si_ctlp->sictl_port_acc_handle,
2946 		    (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
2947 		    SControl);
2948 #ifndef __lock_lint
2949 		delay(SI_10MS_TICKS); /* give time for COMRESET to percolate */
2950 #endif /* __lock_lint */
2951 
2952 		/*
2953 		 * Now fetch the SControl again and rewrite the
2954 		 * DET part with 0
2955 		 */
2956 		SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
2957 		    (uint32_t *)PORT_SCONTROL(si_ctlp, port));
2958 		SCONTROL_SET_DET(SControl, SCONTROL_DET_NOACTION);
2959 		ddi_put32(si_ctlp->sictl_port_acc_handle,
2960 		    (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
2961 		    SControl);
2962 
2963 		/*
2964 		 * PHY may be initialized by now. Check the DET field of
2965 		 * SStatus to determine if there is a device present.
2966 		 *
2967 		 * The DET field is valid only if IPM field indicates that
2968 		 * the interface is in active state.
2969 		 */
2970 
2971 		loop_count = 0;
2972 		do {
2973 			SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
2974 			    (uint32_t *)PORT_SSTATUS(si_ctlp, port));
2975 
2976 			if (SSTATUS_GET_IPM(SStatus) !=
2977 			    SSTATUS_IPM_INTERFACE_ACTIVE) {
2978 				/*
2979 				 * If the interface is not active, the DET field
2980 				 * is considered not accurate. So we want to
2981 				 * continue looping.
2982 				 */
2983 				SSTATUS_SET_DET(SStatus,
2984 				    SSTATUS_DET_NODEV_NOPHY);
2985 			}
2986 
2987 			if (loop_count++ > SI_POLLRATE_SSTATUS) {
2988 				/*
2989 				 * We are effectively timing out after 0.1 sec.
2990 				 */
2991 				break;
2992 			}
2993 
2994 			/* Wait for 10 millisec */
2995 #ifndef __lock_lint
2996 			delay(SI_10MS_TICKS);
2997 #endif /* __lock_lint */
2998 
2999 		} while (SSTATUS_GET_DET(SStatus) !=
3000 		    SSTATUS_DET_DEVPRESENT_PHYONLINE);
3001 
3002 		SIDBG2(SIDBG_POLL_LOOP|SIDBG_INIT, si_ctlp,
3003 		    "si_initialize_controller: 1st loop count: %d, "
3004 		    "SStatus: 0x%x",
3005 		    loop_count,
3006 		    SStatus);
3007 
3008 		if ((SSTATUS_GET_IPM(SStatus) !=
3009 		    SSTATUS_IPM_INTERFACE_ACTIVE) ||
3010 		    (SSTATUS_GET_DET(SStatus) !=
3011 		    SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
3012 			/*
3013 			 * Either the port is not active or there
3014 			 * is no device present.
3015 			 */
3016 			si_ctlp->sictl_ports[port]->siport_port_type =
3017 			    PORT_TYPE_NODEV;
3018 			mutex_exit(&si_portp->siport_mutex);
3019 			continue;
3020 		}
3021 
3022 		/* Wait until Port Ready */
3023 		loop_count = 0;
3024 		do {
3025 			port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3026 			    (uint32_t *)PORT_STATUS(si_ctlp, port));
3027 
3028 			if (loop_count++ > SI_POLLRATE_PORTREADY) {
3029 				/*
3030 				 * We are effectively timing out after 0.5 sec.
3031 				 */
3032 				break;
3033 			}
3034 
3035 			/* Wait for 10 millisec */
3036 #ifndef __lock_lint
3037 			delay(SI_10MS_TICKS);
3038 #endif /* __lock_lint */
3039 
3040 		} while (!(port_status & PORT_STATUS_BITS_PORT_READY));
3041 
3042 		SIDBG1(SIDBG_POLL_LOOP|SIDBG_INIT, si_ctlp,
3043 		    "si_initialize_controller: 2nd loop count: %d",
3044 		    loop_count);
3045 
3046 		if (si_ctlp->sictl_flags & SI_ATTACH) {
3047 			/*
3048 			 * We want to probe for dev signature only during attach
3049 			 * case. Don't do it during suspend/resume sequence.
3050 			 */
3051 			if (port_status & PORT_STATUS_BITS_PORT_READY) {
3052 				mutex_exit(&si_portp->siport_mutex);
3053 				si_find_dev_signature(si_ctlp, si_portp, port,
3054 				    PORTMULT_CONTROL_PORT);
3055 				mutex_enter(&si_portp->siport_mutex);
3056 			} else {
3057 				si_ctlp->sictl_ports[port]->siport_port_type =
3058 				    PORT_TYPE_NODEV;
3059 			}
3060 		}
3061 
3062 		if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
3063 		    si_check_port_handles(si_portp) != DDI_SUCCESS) {
3064 			ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3065 			    DDI_SERVICE_LOST);
3066 			mutex_exit(&si_portp->siport_mutex);
3067 			mutex_exit(&si_ctlp->sictl_mutex);
3068 			return (SI_FAILURE);
3069 		}
3070 
3071 		mutex_exit(&si_portp->siport_mutex);
3072 	}
3073 
3074 	mutex_exit(&si_ctlp->sictl_mutex);
3075 	return (SI_SUCCESS);
3076 }
3077 
3078 /*
3079  * Reverse of si_initialize_controller().
3080  *
3081  * WARNING, WARNING: The caller is expected to obtain the sictl_mutex
3082  * before calling us.
3083  */
3084 static void
3085 si_deinitialize_controller(si_ctl_state_t *si_ctlp)
3086 {
3087 	int port;
3088 
3089 	_NOTE(ASSUMING_PROTECTED(si_ctlp))
3090 
3091 	SIDBG0(SIDBG_INIT|SIDBG_ENTRY, si_ctlp,
3092 	    "si3124: si_deinitialize_controller entered");
3093 
3094 	/* disable all the interrupts. */
3095 	si_disable_all_interrupts(si_ctlp);
3096 
3097 	if (si_ctlp->sictl_flags & SI_DETACH) {
3098 		/*
3099 		 * We want to dealloc all the memory in detach case.
3100 		 */
3101 		for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
3102 			si_dealloc_port_state(si_ctlp, port);
3103 		}
3104 	}
3105 
3106 }
3107 
3108 /*
3109  * Prepare the port ready for usage.
3110  *
3111  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
3112  * before calling us.
3113  */
3114 static void
3115 si_init_port(si_ctl_state_t *si_ctlp, int port)
3116 {
3117 
3118 	SIDBG1(SIDBG_ENTRY|SIDBG_INIT, si_ctlp,
3119 	    "si_init_port entered: port: 0x%x",
3120 	    port);
3121 
3122 	/* Initialize the port. */
3123 	ddi_put32(si_ctlp->sictl_port_acc_handle,
3124 	    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
3125 	    PORT_CONTROL_SET_BITS_PORT_INITIALIZE);
3126 
3127 	/*
3128 	 * Clear the InterruptNCOR (Interrupt No Clear on Read).
3129 	 * This step ensures that a mere reading of slot_status will clear
3130 	 * the interrupt; no explicit clearing of interrupt condition
3131 	 * will be needed for successful completion of commands.
3132 	 */
3133 	ddi_put32(si_ctlp->sictl_port_acc_handle,
3134 	    (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
3135 	    PORT_CONTROL_CLEAR_BITS_INTR_NCoR);
3136 
3137 	/* clear any pending interrupts at this point */
3138 	ddi_put32(si_ctlp->sictl_port_acc_handle,
3139 	    (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp, port)),
3140 	    INTR_MASK);
3141 
3142 }
3143 
3144 
3145 /*
3146  * Enumerate the devices connected to the port multiplier.
3147  * Once a device is detected, we call si_find_dev_signature()
3148  * to find the type of device connected. Even though we are
3149  * called from within si_find_dev_signature(), there is no
3150  * recursion possible.
3151  */
3152 static int
3153 si_enumerate_port_multiplier(
3154 	si_ctl_state_t *si_ctlp,
3155 	si_port_state_t *si_portp,
3156 	int port)
3157 {
3158 	uint32_t num_dev_ports = 0;
3159 	int pmport;
3160 	uint32_t SControl = 0;
3161 	uint32_t SStatus = 0;
3162 	uint32_t SError = 0;
3163 	int loop_count = 0;
3164 
3165 	SIDBG1(SIDBG_ENTRY|SIDBG_INIT, si_ctlp,
3166 	    "si_enumerate_port_multiplier entered: port: %d",
3167 	    port);
3168 
3169 	mutex_enter(&si_portp->siport_mutex);
3170 
3171 	/* Enable Port Multiplier context switching. */
3172 	ddi_put32(si_ctlp->sictl_port_acc_handle,
3173 	    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
3174 	    PORT_CONTROL_SET_BITS_PM_ENABLE);
3175 
3176 	/*
3177 	 * Read the num dev ports connected.
3178 	 * GSCR[2] contains the number of device ports.
3179 	 */
3180 	if (si_read_portmult_reg(si_ctlp, si_portp, port, PORTMULT_CONTROL_PORT,
3181 	    PSCR_REG2, &num_dev_ports)) {
3182 		mutex_exit(&si_portp->siport_mutex);
3183 		return (SI_FAILURE);
3184 	}
3185 	si_portp->siport_portmult_state.sipm_num_ports = num_dev_ports;
3186 
3187 	SIDBG1(SIDBG_INIT, si_ctlp,
3188 	    "si_enumerate_port_multiplier: ports found: %d",
3189 	    num_dev_ports);
3190 
3191 	for (pmport = 0; pmport < num_dev_ports-1; pmport++) {
3192 		/*
3193 		 * Enable PHY by writing a 1, then a 0 to SControl
3194 		 * (i.e. PSCR[2]) DET field.
3195 		 */
3196 		if (si_read_portmult_reg(si_ctlp, si_portp, port, pmport,
3197 		    PSCR_REG2, &SControl)) {
3198 			continue;
3199 		}
3200 
3201 		/* First write a 1 to DET field of SControl. */
3202 		SCONTROL_SET_DET(SControl, SCONTROL_DET_COMRESET);
3203 		if (si_write_portmult_reg(si_ctlp, si_portp, port, pmport,
3204 		    PSCR_REG2, SControl)) {
3205 			continue;
3206 		}
3207 #ifndef __lock_lint
3208 		delay(SI_10MS_TICKS); /* give time for COMRESET to percolate */
3209 #endif /* __lock_lint */
3210 
3211 		/* Then write a 0 to the DET field of SControl. */
3212 		SCONTROL_SET_DET(SControl, SCONTROL_DET_NOACTION);
3213 		if (si_write_portmult_reg(si_ctlp, si_portp, port, pmport,
3214 		    PSCR_REG2, SControl)) {
3215 			continue;
3216 		}
3217 
3218 		/* Wait for PHYRDY by polling SStatus (i.e. PSCR[0]). */
3219 		loop_count = 0;
3220 		do {
3221 			if (si_read_portmult_reg(si_ctlp, si_portp, port,
3222 			    pmport, PSCR_REG0, &SStatus)) {
3223 				break;
3224 			}
3225 			SIDBG1(SIDBG_POLL_LOOP, si_ctlp,
3226 			    "looping for PHYRDY: SStatus: %x",
3227 			    SStatus);
3228 
3229 			if (SSTATUS_GET_IPM(SStatus) !=
3230 			    SSTATUS_IPM_INTERFACE_ACTIVE) {
3231 				/*
3232 				 * If the interface is not active, the DET field
3233 				 * is considered not accurate. So we want to
3234 				 * continue looping.
3235 				 */
3236 				SSTATUS_SET_DET(SStatus,
3237 				    SSTATUS_DET_NODEV_NOPHY);
3238 			}
3239 
3240 			if (loop_count++ > SI_POLLRATE_SSTATUS) {
3241 				/*
3242 				 * We are effectively timing out after 0.1 sec.
3243 				 */
3244 				break;
3245 			}
3246 
3247 			/* Wait for 10 millisec */
3248 #ifndef __lock_lint
3249 			delay(SI_10MS_TICKS);
3250 #endif /* __lock_lint */
3251 
3252 		} while (SSTATUS_GET_DET(SStatus) !=
3253 		    SSTATUS_DET_DEVPRESENT_PHYONLINE);
3254 
3255 		SIDBG2(SIDBG_POLL_LOOP, si_ctlp,
3256 		    "si_enumerate_port_multiplier: "
3257 		    "loop count: %d, SStatus: 0x%x",
3258 		    loop_count,
3259 		    SStatus);
3260 
3261 		if ((SSTATUS_GET_IPM(SStatus) ==
3262 		    SSTATUS_IPM_INTERFACE_ACTIVE) &&
3263 		    (SSTATUS_GET_DET(SStatus) ==
3264 		    SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
3265 			/* The interface is active and the device is present */
3266 			SIDBG1(SIDBG_INIT, si_ctlp,
3267 			    "Status: %x, device exists",
3268 			    SStatus);
3269 			/*
3270 			 * Clear error bits in SError register (i.e. PSCR[1]
3271 			 * by writing back error bits.
3272 			 */
3273 			if (si_read_portmult_reg(si_ctlp, si_portp, port,
3274 			    pmport, PSCR_REG1, &SError)) {
3275 				continue;
3276 			}
3277 			SIDBG1(SIDBG_INIT, si_ctlp,
3278 			    "SError bits are: %x", SError);
3279 			if (si_write_portmult_reg(si_ctlp, si_portp, port,
3280 			    pmport, PSCR_REG1, SError)) {
3281 				continue;
3282 			}
3283 
3284 			/* There exists a device. */
3285 			mutex_exit(&si_portp->siport_mutex);
3286 			si_find_dev_signature(si_ctlp, si_portp, port, pmport);
3287 			mutex_enter(&si_portp->siport_mutex);
3288 		}
3289 	}
3290 
3291 	mutex_exit(&si_portp->siport_mutex);
3292 
3293 	return (SI_SUCCESS);
3294 }
3295 
3296 
3297 /*
3298  * Read a port multiplier register.
3299  *
3300  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
3301  * before calling us.
3302  */
3303 static int
3304 si_read_portmult_reg(
3305 	si_ctl_state_t *si_ctlp,
3306 	si_port_state_t *si_portp,
3307 	int port,
3308 	int pmport,
3309 	int regnum,
3310 	uint32_t *regval)
3311 {
3312 	int slot;
3313 	si_prb_t *prb;
3314 	uint32_t *prb_word_ptr;
3315 	int i;
3316 	uint32_t slot_status;
3317 	int loop_count = 0;
3318 
3319 	_NOTE(ASSUMING_PROTECTED(si_portp))
3320 
3321 	SIDBG3(SIDBG_ENTRY, si_ctlp, "si_read_portmult_reg: port: %x,"
3322 	    "pmport: %x, regnum: %x",
3323 	    port, pmport, regnum);
3324 
3325 	slot = si_claim_free_slot(si_ctlp, si_portp, port);
3326 	if (slot == SI_FAILURE) {
3327 		return (SI_FAILURE);
3328 	}
3329 
3330 	prb =  &(si_portp->siport_prbpool[slot]);
3331 	bzero((void *)prb, sizeof (si_prb_t));
3332 
3333 	/* Now fill the prb. */
3334 	SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
3335 	SET_FIS_PMP(prb->prb_fis, PORTMULT_CONTROL_PORT);
3336 	SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
3337 	SET_FIS_COMMAND(prb->prb_fis, SATAC_READ_PM_REG);
3338 
3339 	SET_FIS_DEV_HEAD(prb->prb_fis, pmport);
3340 	SET_FIS_FEATURES(prb->prb_fis, regnum);
3341 
3342 	/* no real data transfer is involved. */
3343 	SET_SGE_TRM(prb->prb_sge0);
3344 
3345 #if SI_DEBUG
3346 	if (si_debug_flags & SIDBG_DUMP_PRB) {
3347 		int *ptr;
3348 		int j;
3349 
3350 		ptr = (int *)(void *)prb;
3351 		cmn_err(CE_WARN, "read_port_mult_reg, prb: ");
3352 		for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
3353 			cmn_err(CE_WARN, "%x ", ptr[j]);
3354 		}
3355 
3356 	}
3357 #endif /* SI_DEBUG */
3358 
3359 	/* Deliver PRB */
3360 	POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
3361 
3362 	/* Loop till the command is finished. */
3363 	do {
3364 		slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3365 		    (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
3366 
3367 		SIDBG1(SIDBG_POLL_LOOP, si_ctlp,
3368 		    "looping read_pm slot_status: 0x%x",
3369 		    slot_status);
3370 
3371 		if (loop_count++ > SI_POLLRATE_SLOTSTATUS) {
3372 			/* We are effectively timing out after 0.5 sec. */
3373 			break;
3374 		}
3375 
3376 		/* Wait for 10 millisec */
3377 #ifndef __lock_lint
3378 		delay(SI_10MS_TICKS);
3379 #endif /* __lock_lint */
3380 
3381 	} while (slot_status & SI_SLOT_MASK & (0x1 << slot));
3382 
3383 	SIDBG1(SIDBG_POLL_LOOP, si_ctlp,
3384 	    "read_portmult_reg: loop count: %d",
3385 	    loop_count);
3386 
3387 	CLEAR_BIT(si_portp->siport_pending_tags, slot);
3388 
3389 	/* Now inspect the port LRAM for the modified FIS. */
3390 	prb_word_ptr = (uint32_t *)(void *)prb;
3391 	for (i = 0; i < (sizeof (si_prb_t)/4); i++) {
3392 		prb_word_ptr[i] = ddi_get32(si_ctlp->sictl_port_acc_handle,
3393 		    (uint32_t *)(PORT_LRAM(si_ctlp, port, slot)+i*4));
3394 	}
3395 
3396 	if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
3397 	    si_check_port_handles(si_portp) != DDI_SUCCESS) {
3398 		ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3399 		    DDI_SERVICE_UNAFFECTED);
3400 		return (SI_FAILURE);
3401 	}
3402 
3403 	if (((GET_FIS_COMMAND(prb->prb_fis) & 0x1) != 0) ||
3404 	    (GET_FIS_FEATURES(prb->prb_fis) != 0)) {
3405 		/* command failed. */
3406 		return (SI_FAILURE);
3407 	}
3408 
3409 	/* command succeeded. */
3410 	*regval = (GET_FIS_SECTOR_COUNT(prb->prb_fis) & 0xff) |
3411 	    ((GET_FIS_SECTOR(prb->prb_fis) << 8)  & 0xff00) |
3412 	    ((GET_FIS_CYL_LOW(prb->prb_fis) << 16)  & 0xff0000) |
3413 	    ((GET_FIS_CYL_HI(prb->prb_fis) << 24)  & 0xff000000);
3414 
3415 	return (SI_SUCCESS);
3416 }
3417 
3418 /*
3419  * Write a port multiplier register.
3420  *
3421  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
3422  * before calling us.
3423  */
3424 static int
3425 si_write_portmult_reg(
3426 	si_ctl_state_t *si_ctlp,
3427 	si_port_state_t *si_portp,
3428 	int port,
3429 	int pmport,
3430 	int regnum,
3431 	uint32_t regval)
3432 {
3433 	int slot;
3434 	si_prb_t *prb;
3435 	uint32_t *prb_word_ptr;
3436 	uint32_t slot_status;
3437 	int i;
3438 	int loop_count = 0;
3439 
3440 	_NOTE(ASSUMING_PROTECTED(si_portp))
3441 
3442 	SIDBG4(SIDBG_ENTRY, si_ctlp,
3443 	    "si_write_portmult_reg: port: %x, pmport: %x,"
3444 	    "regnum: %x, regval: %x",
3445 	    port, pmport, regnum, regval);
3446 
3447 	slot = si_claim_free_slot(si_ctlp, si_portp, port);
3448 	if (slot == SI_FAILURE) {
3449 		return (SI_FAILURE);
3450 	}
3451 
3452 	prb =  &(si_portp->siport_prbpool[slot]);
3453 	bzero((void *)prb, sizeof (si_prb_t));
3454 
3455 	/* Now fill the prb. */
3456 	SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
3457 	SET_FIS_PMP(prb->prb_fis, PORTMULT_CONTROL_PORT);
3458 	SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
3459 
3460 	SET_FIS_COMMAND(prb->prb_fis, SATAC_WRITE_PM_REG);
3461 	SET_FIS_DEV_HEAD(prb->prb_fis, pmport);
3462 	SET_FIS_FEATURES(prb->prb_fis, regnum);
3463 
3464 	SET_FIS_SECTOR_COUNT(prb->prb_fis, regval & 0xff);
3465 	SET_FIS_SECTOR(prb->prb_fis, (regval >> 8) & 0xff);
3466 	SET_FIS_CYL_LOW(prb->prb_fis, (regval >> 16) & 0xff);
3467 	SET_FIS_CYL_HI(prb->prb_fis, (regval >> 24)  & 0xff);
3468 
3469 	/* no real data transfer is involved. */
3470 	SET_SGE_TRM(prb->prb_sge0);
3471 
3472 #if SI_DEBUG
3473 	if (si_debug_flags & SIDBG_DUMP_PRB) {
3474 		int *ptr;
3475 		int j;
3476 
3477 		ptr = (int *)(void *)prb;
3478 		cmn_err(CE_WARN, "read_port_mult_reg, prb: ");
3479 		for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
3480 			cmn_err(CE_WARN, "%x ", ptr[j]);
3481 		}
3482 
3483 	}
3484 #endif /* SI_DEBUG */
3485 
3486 	/* Deliver PRB */
3487 	POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
3488 
3489 	/* Loop till the command is finished. */
3490 	do {
3491 		slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3492 		    (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
3493 
3494 		SIDBG1(SIDBG_POLL_LOOP, si_ctlp,
3495 		    "looping write_pmp slot_status: 0x%x",
3496 		    slot_status);
3497 
3498 		if (loop_count++ > SI_POLLRATE_SLOTSTATUS) {
3499 			/* We are effectively timing out after 0.5 sec. */
3500 			break;
3501 		}
3502 
3503 		/* Wait for 10 millisec */
3504 #ifndef __lock_lint
3505 		delay(SI_10MS_TICKS);
3506 #endif /* __lock_lint */
3507 
3508 	} while (slot_status & SI_SLOT_MASK & (0x1 << slot));
3509 
3510 	SIDBG1(SIDBG_POLL_LOOP, si_ctlp,
3511 	    "write_portmult_reg: loop count: %d",
3512 	    loop_count);
3513 
3514 	CLEAR_BIT(si_portp->siport_pending_tags, slot);
3515 
3516 	/* Now inspect the port LRAM for the modified FIS. */
3517 	prb_word_ptr = (uint32_t *)(void *)prb;
3518 	for (i = 0; i < (sizeof (si_prb_t)/4); i++) {
3519 		prb_word_ptr[i] = ddi_get32(si_ctlp->sictl_port_acc_handle,
3520 		    (uint32_t *)(PORT_LRAM(si_ctlp, port, slot)+i*4));
3521 	}
3522 
3523 	if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
3524 	    si_check_port_handles(si_portp) != DDI_SUCCESS) {
3525 		ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3526 		    DDI_SERVICE_UNAFFECTED);
3527 		return (SI_FAILURE);
3528 	}
3529 
3530 	if (((GET_FIS_COMMAND(prb->prb_fis) & 0x1) != 0) ||
3531 	    (GET_FIS_FEATURES(prb->prb_fis) != 0)) {
3532 		/* command failed */
3533 		return (SI_FAILURE);
3534 	}
3535 
3536 	/* command succeeded */
3537 	return (SI_SUCCESS);
3538 }
3539 
3540 
3541 /*
3542  * Set the auto sense data for ATAPI devices.
3543  *
3544  * Note: Currently the sense data is simulated; this code will be enhanced
3545  * in second phase to fetch the real sense data from the atapi device.
3546  */
3547 static void
3548 si_set_sense_data(sata_pkt_t *satapkt, int reason)
3549 {
3550 	struct scsi_extended_sense *sense;
3551 
3552 	sense = (struct scsi_extended_sense *)
3553 	    satapkt->satapkt_cmd.satacmd_rqsense;
3554 	bzero(sense, sizeof (struct scsi_extended_sense));
3555 	sense->es_valid = 1;		/* Valid sense */
3556 	sense->es_class = 7;		/* Response code 0x70 - current err */
3557 	sense->es_key = 0;
3558 	sense->es_info_1 = 0;
3559 	sense->es_info_2 = 0;
3560 	sense->es_info_3 = 0;
3561 	sense->es_info_4 = 0;
3562 	sense->es_add_len = 6;		/* Additional length */
3563 	sense->es_cmd_info[0] = 0;
3564 	sense->es_cmd_info[1] = 0;
3565 	sense->es_cmd_info[2] = 0;
3566 	sense->es_cmd_info[3] = 0;
3567 	sense->es_add_code = 0;
3568 	sense->es_qual_code = 0;
3569 
3570 	if ((reason == SATA_PKT_DEV_ERROR) || (reason == SATA_PKT_TIMEOUT)) {
3571 		sense->es_key = KEY_HARDWARE_ERROR;
3572 	}
3573 }
3574 
3575 
3576 /*
3577  * Interrupt service handler. We loop through each of the ports to find
3578  * if the interrupt belongs to any of them.
3579  *
3580  * Bulk of the interrupt handling is actually done out of subroutines
3581  * like si_intr_command_complete() etc.
3582  */
3583 /*ARGSUSED*/
3584 static uint_t
3585 si_intr(caddr_t arg1, caddr_t arg2)
3586 {
3587 	si_ctl_state_t *si_ctlp = (si_ctl_state_t *)(void *)arg1;
3588 	si_port_state_t *si_portp;
3589 	uint32_t global_intr_status;
3590 	uint32_t mask, port_intr_status;
3591 	int port;
3592 
3593 	global_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
3594 	    (uint32_t *)GLOBAL_INTERRUPT_STATUS(si_ctlp));
3595 
3596 	SIDBG1(SIDBG_INTR|SIDBG_ENTRY, si_ctlp,
3597 	    "si_intr: global_int_status: 0x%x",
3598 	    global_intr_status);
3599 
3600 	if (si_check_acc_handle(si_ctlp->sictl_global_acc_handle) !=
3601 	    DDI_SUCCESS) {
3602 		ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3603 		    DDI_SERVICE_UNAFFECTED);
3604 		return (DDI_INTR_UNCLAIMED);
3605 	}
3606 
3607 	if (!(global_intr_status & SI31xx_INTR_PORT_MASK)) {
3608 		/* Sorry, the interrupt is not ours. */
3609 		return (DDI_INTR_UNCLAIMED);
3610 	}
3611 
3612 	/* Loop for all the ports. */
3613 	for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
3614 
3615 		mask = 0x1 << port;
3616 		if (!(global_intr_status & mask)) {
3617 			continue;
3618 		}
3619 
3620 		mutex_enter(&si_ctlp->sictl_mutex);
3621 		si_portp = si_ctlp->sictl_ports[port];
3622 		mutex_exit(&si_ctlp->sictl_mutex);
3623 
3624 		port_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
3625 		    (uint32_t *)PORT_INTERRUPT_STATUS(si_ctlp, port));
3626 
3627 		SIDBG2(SIDBG_VERBOSE, si_ctlp,
3628 		    "s_intr: port_intr_status: 0x%x, port: %x",
3629 		    port_intr_status,
3630 		    port);
3631 
3632 		if (port_intr_status & INTR_COMMAND_COMPLETE) {
3633 			(void) si_intr_command_complete(si_ctlp, si_portp,
3634 			    port);
3635 
3636 			mutex_enter(&si_portp->siport_mutex);
3637 			if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
3638 			    si_check_port_handles(si_portp) != DDI_SUCCESS) {
3639 				mutex_exit(&si_portp->siport_mutex);
3640 				ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3641 				    DDI_SERVICE_UNAFFECTED);
3642 				(void) si_initialize_port_wait_till_ready(
3643 				    si_ctlp, port);
3644 			} else {
3645 				mutex_exit(&si_portp->siport_mutex);
3646 			}
3647 		} else {
3648 			/* Clear the interrupts */
3649 			ddi_put32(si_ctlp->sictl_port_acc_handle,
3650 			    (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp, port)),
3651 			    port_intr_status & INTR_MASK);
3652 		}
3653 
3654 		/*
3655 		 * Note that we did not clear the interrupt for command
3656 		 * completion interrupt. Reading of slot_status takes care
3657 		 * of clearing the interrupt for command completion case.
3658 		 */
3659 
3660 		if (port_intr_status & INTR_COMMAND_ERROR) {
3661 			(void) si_intr_command_error(si_ctlp, si_portp, port);
3662 		}
3663 
3664 		if (port_intr_status & INTR_PORT_READY) {
3665 			(void) si_intr_port_ready(si_ctlp, si_portp, port);
3666 		}
3667 
3668 		if (port_intr_status & INTR_POWER_CHANGE) {
3669 			(void) si_intr_pwr_change(si_ctlp, si_portp, port);
3670 		}
3671 
3672 		if (port_intr_status & INTR_PHYRDY_CHANGE) {
3673 			(void) si_intr_phy_ready_change(si_ctlp, si_portp,
3674 			    port);
3675 		}
3676 
3677 		if (port_intr_status & INTR_COMWAKE_RECEIVED) {
3678 			(void) si_intr_comwake_rcvd(si_ctlp, si_portp,
3679 			    port);
3680 		}
3681 
3682 		if (port_intr_status & INTR_UNRECOG_FIS) {
3683 			(void) si_intr_unrecognised_fis(si_ctlp, si_portp,
3684 			    port);
3685 		}
3686 
3687 		if (port_intr_status & INTR_DEV_XCHANGED) {
3688 			(void) si_intr_dev_xchanged(si_ctlp, si_portp, port);
3689 		}
3690 
3691 		if (port_intr_status & INTR_8B10B_DECODE_ERROR) {
3692 			(void) si_intr_decode_err_threshold(si_ctlp, si_portp,
3693 			    port);
3694 		}
3695 
3696 		if (port_intr_status & INTR_CRC_ERROR) {
3697 			(void) si_intr_crc_err_threshold(si_ctlp, si_portp,
3698 			    port);
3699 		}
3700 
3701 		if (port_intr_status & INTR_HANDSHAKE_ERROR) {
3702 			(void) si_intr_handshake_err_threshold(si_ctlp,
3703 			    si_portp, port);
3704 		}
3705 
3706 		if (port_intr_status & INTR_SETDEVBITS_NOTIFY) {
3707 			(void) si_intr_set_devbits_notify(si_ctlp, si_portp,
3708 			    port);
3709 		}
3710 	}
3711 
3712 	return (DDI_INTR_CLAIMED);
3713 }
3714 
3715 /*
3716  * Interrupt which indicates that one or more commands have successfully
3717  * completed.
3718  *
3719  * Since we disabled W1C (write-one-to-clear) previously, mere reading
3720  * of slot_status register clears the interrupt. There is no need to
3721  * explicitly clear the interrupt.
3722  */
3723 static int
3724 si_intr_command_complete(
3725 	si_ctl_state_t *si_ctlp,
3726 	si_port_state_t *si_portp,
3727 	int port)
3728 {
3729 
3730 	uint32_t slot_status;
3731 	uint32_t finished_tags;
3732 	int finished_slot;
3733 	sata_pkt_t *satapkt;
3734 
3735 	SIDBG0(SIDBG_ENTRY|SIDBG_INTR, si_ctlp,
3736 	    "si_intr_command_complete enter");
3737 
3738 	mutex_enter(&si_portp->siport_mutex);
3739 
3740 	slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3741 	    (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
3742 
3743 	if (!si_portp->siport_pending_tags) {
3744 		/*
3745 		 * Spurious interrupt. Nothing to be done.
3746 		 * The interrupt was cleared when slot_status was read.
3747 		 */
3748 		mutex_exit(&si_portp->siport_mutex);
3749 		return (SI_SUCCESS);
3750 	}
3751 
3752 	SIDBG2(SIDBG_VERBOSE, si_ctlp, "si3124: si_intr_command_complete: "
3753 	    "pending_tags: %x, slot_status: %x",
3754 	    si_portp->siport_pending_tags,
3755 	    slot_status);
3756 
3757 	finished_tags =  si_portp->siport_pending_tags &
3758 	    ~slot_status & SI_SLOT_MASK;
3759 	while (finished_tags) {
3760 
3761 		finished_slot = ddi_ffs(finished_tags) - 1;
3762 		if (finished_slot == -1) {
3763 			break;
3764 		}
3765 
3766 		satapkt = si_portp->siport_slot_pkts[finished_slot];
3767 
3768 		if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
3769 			si_copy_out_regs(&satapkt->satapkt_cmd, si_ctlp, port,
3770 			    finished_slot);
3771 		}
3772 
3773 		CLEAR_BIT(si_portp->siport_pending_tags, finished_slot);
3774 		CLEAR_BIT(finished_tags, finished_slot);
3775 		SENDUP_PACKET(si_portp, satapkt, SATA_PKT_COMPLETED);
3776 	}
3777 
3778 	SIDBG2(SIDBG_PKTCOMP, si_ctlp,
3779 	    "command_complete done: pend_tags: 0x%x, slot_status: 0x%x",
3780 	    si_portp->siport_pending_tags,
3781 	    slot_status);
3782 
3783 	/*
3784 	 * tidbit: no need to clear the interrupt since reading of
3785 	 * slot_status automatically clears the interrupt in the case
3786 	 * of a successful command completion.
3787 	 */
3788 
3789 	mutex_exit(&si_portp->siport_mutex);
3790 
3791 	return (SI_SUCCESS);
3792 }
3793 
3794 /*
3795  * Interrupt which indicates that a command did not complete successfully.
3796  *
3797  * The port halts whenever a command error interrupt is received.
3798  * The only way to restart it is to reset or reinitialize the port
3799  * but such an operation throws away all the pending commands on
3800  * the port.
3801  *
3802  * We reset the device and mop the commands on the port.
3803  */
3804 static int
3805 si_intr_command_error(
3806 	si_ctl_state_t *si_ctlp,
3807 	si_port_state_t *si_portp,
3808 	int port)
3809 {
3810 	uint32_t command_error, slot_status;
3811 	uint32_t failed_tags;
3812 
3813 	command_error = ddi_get32(si_ctlp->sictl_port_acc_handle,
3814 	    (uint32_t *)(PORT_COMMAND_ERROR(si_ctlp, port)));
3815 
3816 	SIDBG1(SIDBG_INTR|SIDBG_ENTRY, si_ctlp,
3817 	    "si_intr_command_error: command_error: 0x%x",
3818 	    command_error);
3819 
3820 	mutex_enter(&si_portp->siport_mutex);
3821 
3822 	/*
3823 	 * Remember the slot_status since any of the recovery handler
3824 	 * can blow it away with reset operation.
3825 	 */
3826 	slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3827 	    (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
3828 
3829 	si_log_error_message(si_ctlp, port, command_error);
3830 
3831 	switch (command_error) {
3832 
3833 	case CMD_ERR_DEVICEERRROR:
3834 		si_error_recovery_DEVICEERROR(si_ctlp, si_portp, port);
3835 		break;
3836 
3837 	case CMD_ERR_SDBERROR:
3838 		si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR, "SBD error");
3839 		si_error_recovery_SDBERROR(si_ctlp, si_portp, port);
3840 		ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3841 		    DDI_SERVICE_UNAFFECTED);
3842 		break;
3843 
3844 	case CMD_ERR_DATAFISERROR:
3845 		si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR,
3846 		    "Data FIS error");
3847 		si_error_recovery_DATAFISERROR(si_ctlp, si_portp, port);
3848 		ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3849 		    DDI_SERVICE_UNAFFECTED);
3850 		break;
3851 
3852 	case CMD_ERR_SENDFISERROR:
3853 		si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR,
3854 		    "Send FIS error");
3855 		si_error_recovery_SENDFISERROR(si_ctlp, si_portp, port);
3856 		ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3857 		    DDI_SERVICE_UNAFFECTED);
3858 		break;
3859 
3860 	default:
3861 		si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR,
3862 		    "Unknown error");
3863 		si_error_recovery_default(si_ctlp, si_portp, port);
3864 		ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3865 		    DDI_SERVICE_UNAFFECTED);
3866 		break;
3867 
3868 	}
3869 
3870 	/*
3871 	 * Compute the failed_tags by adding up the error tags.
3872 	 *
3873 	 * The siport_err_tags_SDBERROR and siport_err_tags_nonSDBERROR
3874 	 * were filled in by the si_error_recovery_* routines.
3875 	 */
3876 	failed_tags = si_portp->siport_pending_tags &
3877 	    (si_portp->siport_err_tags_SDBERROR |
3878 	    si_portp->siport_err_tags_nonSDBERROR);
3879 
3880 	SIDBG3(SIDBG_ERRS|SIDBG_INTR, si_ctlp, "si_intr_command_error: "
3881 	    "err_tags_SDBERROR: 0x%x, "
3882 	    "err_tags_nonSDBERRROR: 0x%x, "
3883 	    "failed_tags: 0x%x",
3884 	    si_portp->siport_err_tags_SDBERROR,
3885 	    si_portp->siport_err_tags_nonSDBERROR,
3886 	    failed_tags);
3887 
3888 	SIDBG2(SIDBG_ERRS|SIDBG_INTR, si_ctlp, "si3124: si_intr_command_error: "
3889 	    "slot_status:0x%x, pending_tags: 0x%x",
3890 	    slot_status,
3891 	    si_portp->siport_pending_tags);
3892 
3893 	si_portp->mopping_in_progress++;
3894 
3895 	si_mop_commands(si_ctlp,
3896 	    si_portp,
3897 	    port,
3898 	    slot_status,
3899 	    failed_tags,
3900 	    0, 	/* timedout_tags */
3901 	    0, 	/* aborting_tags */
3902 	    0); 	/* reset_tags */
3903 
3904 	ASSERT(si_portp->siport_pending_tags == 0);
3905 
3906 	si_portp->siport_err_tags_SDBERROR = 0;
3907 	si_portp->siport_err_tags_nonSDBERROR = 0;
3908 
3909 	mutex_exit(&si_portp->siport_mutex);
3910 
3911 	return (SI_SUCCESS);
3912 }
3913 
3914 /*
3915  * There is a subtle difference between errors on a normal port and
3916  * a port-mult port. When an error happens on a normal port, the port
3917  * is halted effectively until the port is reset or initialized.
3918  * However, in port-mult port errors, port does not get halted since
3919  * other non-error devices behind the port multiplier can still
3920  * continue to operate. So we wait till all the commands are drained
3921  * instead of resetting it right away.
3922  *
3923  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
3924  * before calling us.
3925  */
3926 static void
3927 si_recover_portmult_errors(
3928 	si_ctl_state_t *si_ctlp,
3929 	si_port_state_t *si_portp,
3930 	int port)
3931 {
3932 	uint32_t command_error, slot_status, port_status;
3933 	int failed_slot;
3934 	int loop_count = 0;
3935 
3936 	_NOTE(ASSUMING_PROTECTED(si_portp))
3937 
3938 	SIDBG1(SIDBG_ERRS|SIDBG_ENTRY, si_ctlp,
3939 	    "si_recover_portmult_errors: port: 0x%x",
3940 	    port);
3941 
3942 	/* Resume the port */
3943 	ddi_put32(si_ctlp->sictl_port_acc_handle,
3944 	    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
3945 	    PORT_CONTROL_SET_BITS_RESUME);
3946 
3947 	port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3948 	    (uint32_t *)PORT_STATUS(si_ctlp, port));
3949 
3950 	failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
3951 	command_error = ddi_get32(si_ctlp->sictl_port_acc_handle,
3952 	    (uint32_t *)(PORT_COMMAND_ERROR(si_ctlp, port)));
3953 
3954 	if (command_error ==  CMD_ERR_SDBERROR) {
3955 		si_portp->siport_err_tags_SDBERROR |= (0x1 << failed_slot);
3956 	} else {
3957 		si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
3958 	}
3959 
3960 	/* Now we drain the pending commands. */
3961 	do {
3962 		slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3963 		    (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
3964 
3965 		/*
3966 		 * Since we have not yet returned DDI_INTR_CLAIMED,
3967 		 * our interrupt handler is guaranteed not to be called again.
3968 		 * So we need to check IS_ATTENTION_RAISED() for further
3969 		 * decisions.
3970 		 *
3971 		 * This is a too big a delay for an interrupt context.
3972 		 * But this is supposed to be a rare condition.
3973 		 */
3974 
3975 		if (IS_ATTENTION_RAISED(slot_status)) {
3976 			/* Resume again */
3977 			ddi_put32(si_ctlp->sictl_port_acc_handle,
3978 			    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
3979 			    PORT_CONTROL_SET_BITS_RESUME);
3980 
3981 			port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3982 			    (uint32_t *)PORT_STATUS(si_ctlp, port));
3983 			failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
3984 			command_error = ddi_get32(
3985 			    si_ctlp->sictl_port_acc_handle,
3986 			    (uint32_t *)(PORT_COMMAND_ERROR(si_ctlp,
3987 			    port)));
3988 			if (command_error ==  CMD_ERR_SDBERROR) {
3989 				si_portp->siport_err_tags_SDBERROR |=
3990 				    (0x1 << failed_slot);
3991 			} else {
3992 				si_portp->siport_err_tags_nonSDBERROR |=
3993 				    (0x1 << failed_slot);
3994 			}
3995 		}
3996 
3997 		if (loop_count++ > SI_POLLRATE_RECOVERPORTMULT) {
3998 			/* We are effectively timing out after 10 sec. */
3999 			break;
4000 		}
4001 
4002 		/* Wait for 10 millisec */
4003 #ifndef __lock_lint
4004 		delay(SI_10MS_TICKS);
4005 #endif /* __lock_lint */
4006 
4007 	} while (slot_status & SI_SLOT_MASK);
4008 
4009 	/*
4010 	 * The above loop can be improved for 3132 since we could obtain the
4011 	 * Port Multiplier Context of the device in error. Then we could
4012 	 * do a better job in filtering out commands for the device in error.
4013 	 * The loop could finish much earlier with such a logic.
4014 	 */
4015 
4016 	/* Clear the RESUME bit. */
4017 	ddi_put32(si_ctlp->sictl_port_acc_handle,
4018 	    (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
4019 	    PORT_CONTROL_CLEAR_BITS_RESUME);
4020 
4021 }
4022 
4023 /*
4024  * If we are connected to port multiplier, drain the non-failed devices.
4025  * Otherwise, we initialize the port (which effectively fails all the
4026  * pending commands in the hope that sd would retry them later).
4027  *
4028  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4029  * before calling us.
4030  */
4031 static void
4032 si_error_recovery_DEVICEERROR(
4033 	si_ctl_state_t *si_ctlp,
4034 	si_port_state_t *si_portp,
4035 	int port)
4036 {
4037 	uint32_t port_status;
4038 	int failed_slot;
4039 
4040 	_NOTE(ASSUMING_PROTECTED(si_portp))
4041 
4042 	SIDBG1(SIDBG_ERRS|SIDBG_ENTRY, si_ctlp,
4043 	    "si_error_recovery_DEVICEERROR: port: 0x%x",
4044 	    port);
4045 
4046 	if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
4047 		si_recover_portmult_errors(si_ctlp, si_portp, port);
4048 	} else {
4049 		port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4050 		    (uint32_t *)PORT_STATUS(si_ctlp, port));
4051 		failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4052 		si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4053 	}
4054 
4055 	/* In either case (port-mult or not), we reinitialize the port. */
4056 	(void) si_initialize_port_wait_till_ready(si_ctlp, port);
4057 }
4058 
4059 /*
4060  * Handle exactly like DEVICEERROR. Remember the tags with SDBERROR
4061  * to perform read_log_ext on them later. SDBERROR means that the
4062  * error was for an NCQ command.
4063  *
4064  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4065  * before calling us.
4066  */
4067 static void
4068 si_error_recovery_SDBERROR(
4069 	si_ctl_state_t *si_ctlp,
4070 	si_port_state_t *si_portp,
4071 	int port)
4072 {
4073 	uint32_t port_status;
4074 	int failed_slot;
4075 
4076 	_NOTE(ASSUMING_PROTECTED(si_portp))
4077 
4078 	SIDBG1(SIDBG_ERRS|SIDBG_ENTRY, si_ctlp,
4079 	    "si3124: si_error_recovery_SDBERROR: port: 0x%x",
4080 	    port);
4081 
4082 	if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
4083 		si_recover_portmult_errors(si_ctlp, si_portp, port);
4084 	} else {
4085 		port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4086 		    (uint32_t *)PORT_STATUS(si_ctlp, port));
4087 		failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4088 		si_portp->siport_err_tags_SDBERROR |= (0x1 << failed_slot);
4089 	}
4090 
4091 	/* In either case (port-mult or not), we reinitialize the port. */
4092 	(void) si_initialize_port_wait_till_ready(si_ctlp, port);
4093 }
4094 
4095 /*
4096  * Handle exactly like DEVICEERROR except resetting the port if there was
4097  * an NCQ command on the port.
4098  *
4099  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4100  * before calling us.
4101  */
4102 static void
4103 si_error_recovery_DATAFISERROR(
4104 	si_ctl_state_t *si_ctlp,
4105 	si_port_state_t *si_portp,
4106 	int port)
4107 {
4108 	uint32_t port_status;
4109 	int failed_slot;
4110 
4111 	_NOTE(ASSUMING_PROTECTED(si_portp))
4112 
4113 	SIDBG1(SIDBG_ERRS|SIDBG_ENTRY, si_ctlp,
4114 	    "si3124: si_error_recovery_DATAFISERROR: port: 0x%x",
4115 	    port);
4116 
4117 	/* reset device if we were waiting for any ncq commands. */
4118 	if (si_portp->siport_pending_ncq_count) {
4119 		port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4120 		    (uint32_t *)PORT_STATUS(si_ctlp, port));
4121 		failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4122 		si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4123 		(void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
4124 		    SI_DEVICE_RESET);
4125 		return;
4126 	}
4127 
4128 	/*
4129 	 * If we don't have any ncq commands pending, the rest of
4130 	 * the process is similar to the one for DEVICEERROR.
4131 	 */
4132 	si_error_recovery_DEVICEERROR(si_ctlp, si_portp, port);
4133 }
4134 
4135 /*
4136  * We handle just like DEVICERROR except that we reset the device instead
4137  * of initializing the port.
4138  *
4139  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4140  * before calling us.
4141  */
4142 static void
4143 si_error_recovery_SENDFISERROR(
4144 	si_ctl_state_t *si_ctlp,
4145 	si_port_state_t *si_portp,
4146 	int port)
4147 {
4148 	uint32_t port_status;
4149 	int failed_slot;
4150 
4151 	_NOTE(ASSUMING_PROTECTED(si_portp))
4152 
4153 	SIDBG1(SIDBG_ERRS|SIDBG_ENTRY, si_ctlp,
4154 	    "si3124: si_error_recovery_SENDFISERROR: port: 0x%x",
4155 	    port);
4156 
4157 	if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
4158 		si_recover_portmult_errors(si_ctlp, si_portp, port);
4159 	} else {
4160 		port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4161 		    (uint32_t *)PORT_STATUS(si_ctlp, port));
4162 		failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4163 		si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4164 		(void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
4165 		    SI_DEVICE_RESET);
4166 	}
4167 }
4168 
4169 /*
4170  * The default behavior for all other errors is to reset the device.
4171  *
4172  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4173  * before calling us.
4174  */
4175 static void
4176 si_error_recovery_default(
4177 	si_ctl_state_t *si_ctlp,
4178 	si_port_state_t *si_portp,
4179 	int port)
4180 {
4181 	uint32_t port_status;
4182 	int failed_slot;
4183 
4184 	_NOTE(ASSUMING_PROTECTED(si_portp))
4185 
4186 	SIDBG1(SIDBG_ERRS|SIDBG_ENTRY, si_ctlp,
4187 	    "si3124: si_error_recovery_default: port: 0x%x",
4188 	    port);
4189 
4190 	port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4191 	    (uint32_t *)PORT_STATUS(si_ctlp, port));
4192 	failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4193 	si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4194 
4195 	(void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
4196 	    SI_DEVICE_RESET);
4197 }
4198 
4199 /*
4200  * Read Log Ext with PAGE 10 to retrieve the error for an NCQ command.
4201  *
4202  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4203  * before calling us.
4204  */
4205 static uint8_t
4206 si_read_log_ext(si_ctl_state_t *si_ctlp, si_port_state_t *si_portp, int port)
4207 {
4208 	int slot;
4209 	si_prb_t *prb;
4210 	int i;
4211 	uint32_t slot_status;
4212 	int loop_count = 0;
4213 	uint32_t *prb_word_ptr;
4214 	uint8_t error;
4215 
4216 	_NOTE(ASSUMING_PROTECTED(si_portp))
4217 
4218 	SIDBG1(SIDBG_ENTRY|SIDBG_ERRS, si_ctlp,
4219 	    "si_read_log_ext: port: %x", port);
4220 
4221 	slot = si_claim_free_slot(si_ctlp, si_portp, port);
4222 	if (slot == SI_FAILURE) {
4223 		return (0);
4224 	}
4225 
4226 	prb =  &(si_portp->siport_prbpool[slot]);
4227 	bzero((void *)prb, sizeof (si_prb_t));
4228 
4229 	/* Now fill the prb */
4230 	SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
4231 	SET_FIS_PMP(prb->prb_fis, PORTMULT_CONTROL_PORT);
4232 	SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
4233 	SET_FIS_COMMAND(prb->prb_fis, SATAC_READ_LOG_EXT);
4234 	SET_FIS_SECTOR(prb->prb_fis, SATA_LOG_PAGE_10);
4235 
4236 	/* no real data transfer is involved */
4237 	SET_SGE_TRM(prb->prb_sge0);
4238 
4239 #if SI_DEBUG
4240 	if (si_debug_flags & SIDBG_DUMP_PRB) {
4241 		int *ptr;
4242 		int j;
4243 
4244 		ptr = (int *)(void *)prb;
4245 		cmn_err(CE_WARN, "read_port_mult_reg, prb: ");
4246 		for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
4247 			cmn_err(CE_WARN, "%x ", ptr[j]);
4248 		}
4249 
4250 	}
4251 #endif /* SI_DEBUG */
4252 
4253 	/* Deliver PRB */
4254 	POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
4255 
4256 	/* Loop till the command is finished. */
4257 	do {
4258 		slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4259 		    (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
4260 
4261 		SIDBG1(SIDBG_POLL_LOOP, si_ctlp,
4262 		    "looping read_log_ext slot_status: 0x%x",
4263 		    slot_status);
4264 
4265 		if (loop_count++ > SI_POLLRATE_SLOTSTATUS) {
4266 			/* We are effectively timing out after 0.5 sec. */
4267 			break;
4268 		}
4269 
4270 		/* Wait for 10 millisec */
4271 #ifndef __lock_lint
4272 		delay(SI_10MS_TICKS);
4273 #endif /* __lock_lint */
4274 
4275 	} while (slot_status & SI_SLOT_MASK & (0x1 << slot));
4276 
4277 	if (slot_status & SI_SLOT_MASK & (0x1 << slot)) {
4278 		/*
4279 		 * If we fail with the READ LOG EXT command, we need to
4280 		 * initialize the port to clear the slot_status register.
4281 		 * We don't need to worry about any other valid commands
4282 		 * being thrown away because we are already in recovery
4283 		 * mode and READ LOG EXT is the only pending command.
4284 		 */
4285 		(void) si_initialize_port_wait_till_ready(si_ctlp, port);
4286 	}
4287 
4288 	SIDBG1(SIDBG_POLL_LOOP, si_ctlp,
4289 	    "read_portmult_reg: loop count: %d",
4290 	    loop_count);
4291 
4292 	/*
4293 	 * The LRAM contains the the modified FIS.
4294 	 * Read the modified FIS to obtain the Error.
4295 	 */
4296 	prb_word_ptr = (uint32_t *)(void *)prb;
4297 	for (i = 0; i < (sizeof (si_prb_t)/4); i++) {
4298 		prb_word_ptr[i] = ddi_get32(si_ctlp->sictl_port_acc_handle,
4299 		    (uint32_t *)(PORT_LRAM(si_ctlp, port, slot)+i*4));
4300 	}
4301 
4302 	if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
4303 	    si_check_port_handles(si_portp) != DDI_SUCCESS) {
4304 		ddi_fm_service_impact(si_ctlp->sictl_devinfop,
4305 		    DDI_SERVICE_UNAFFECTED);
4306 		return (0);
4307 	}
4308 
4309 	error = GET_FIS_FEATURES(prb->prb_fis);
4310 
4311 	CLEAR_BIT(si_portp->siport_pending_tags, slot);
4312 
4313 	return (error);
4314 
4315 }
4316 
4317 /*
4318  * Dump the error message to the log.
4319  */
4320 static void
4321 si_log_error_message(si_ctl_state_t *si_ctlp, int port, uint32_t command_error)
4322 {
4323 #if SI_DEBUG
4324 #ifndef __lock_lint
4325 	_NOTE(ARGUNUSED(si_ctlp))
4326 	_NOTE(ARGUNUSED(port))
4327 #endif  /* __lock_lint */
4328 
4329 	char *errstr;
4330 
4331 	switch (command_error) {
4332 
4333 	case CMD_ERR_DEVICEERRROR:
4334 		errstr = "Standard Error: Error bit set in register - device"
4335 		    " to host FIS";
4336 		break;
4337 
4338 	case CMD_ERR_SDBERROR:
4339 		errstr = "NCQ Error: Error bit set in register - device"
4340 		    " to host FIS";
4341 		break;
4342 
4343 	case CMD_ERR_DATAFISERROR:
4344 		errstr = "Error in data FIS not detected by device";
4345 		break;
4346 
4347 	case CMD_ERR_SENDFISERROR:
4348 		errstr = "Initial command FIS transmission failed";
4349 		break;
4350 
4351 	case CMD_ERR_INCONSISTENTSTATE:
4352 		errstr = "Inconsistency in protocol";
4353 		break;
4354 
4355 	case CMD_ERR_DIRECTIONERROR:
4356 		errstr = "DMA direction flag does not match the command";
4357 		break;
4358 
4359 	case CMD_ERR_UNDERRUNERROR:
4360 		errstr = "Run out of scatter gather entries while writing data";
4361 		break;
4362 
4363 	case CMD_ERR_OVERRUNERROR:
4364 		errstr = "Run out of scatter gather entries while reading data";
4365 		break;
4366 
4367 	case CMD_ERR_PACKETPROTOCOLERROR:
4368 		errstr = "Packet protocol error";
4369 		break;
4370 
4371 	case CMD_ERR_PLDSGTERRORBOUNDARY:
4372 		errstr = "Scatter/gather table not on quadword boundary";
4373 		break;
4374 
4375 	case CMD_ERR_PLDSGTERRORTARETABORT:
4376 		errstr = "PCI(X) Target abort while fetching scatter/gather"
4377 		    " table";
4378 		break;
4379 
4380 	case CMD_ERR_PLDSGTERRORMASTERABORT:
4381 		errstr = "PCI(X) Master abort while fetching scatter/gather"
4382 		    " table";
4383 		break;
4384 
4385 	case CMD_ERR_PLDSGTERRORPCIERR:
4386 		errstr = "PCI(X) parity error while fetching scatter/gather"
4387 		    " table";
4388 		break;
4389 
4390 	case CMD_ERR_PLDCMDERRORBOUNDARY:
4391 		errstr = "PRB not on quadword boundary";
4392 		break;
4393 
4394 	case CMD_ERR_PLDCMDERRORTARGETABORT:
4395 		errstr = "PCI(X) Target abort while fetching PRB";
4396 		break;
4397 
4398 	case CMD_ERR_PLDCMDERRORMASTERABORT:
4399 		errstr = "PCI(X) Master abort while fetching PRB";
4400 		break;
4401 
4402 	case CMD_ERR_PLDCMDERORPCIERR:
4403 		errstr = "PCI(X) parity error while fetching PRB";
4404 		break;
4405 
4406 	case CMD_ERR_PSDERRORTARGETABORT:
4407 		errstr = "PCI(X) Target abort during data transfer";
4408 		break;
4409 
4410 	case CMD_ERR_PSDERRORMASTERABORT:
4411 		errstr = "PCI(X) Master abort during data transfer";
4412 		break;
4413 
4414 	case CMD_ERR_PSDERRORPCIERR:
4415 		errstr = "PCI(X) parity error during data transfer";
4416 		break;
4417 
4418 	case CMD_ERR_SENDSERVICEERROR:
4419 		errstr = "FIS received while sending service FIS in"
4420 		    " legacy queuing operation";
4421 		break;
4422 
4423 	default:
4424 		errstr = "Unknown Error";
4425 		break;
4426 
4427 	}
4428 
4429 	SIDBG2(SIDBG_ERRS, si_ctlp,
4430 	    "command error: port: 0x%x, error: %s",
4431 	    port,
4432 	    errstr);
4433 #else
4434 #ifndef __lock_lint
4435 	_NOTE(ARGUNUSED(si_ctlp))
4436 	_NOTE(ARGUNUSED(port))
4437 	_NOTE(ARGUNUSED(command_error))
4438 #endif  /* __lock_lint */
4439 
4440 #endif	/* SI_DEBUG */
4441 }
4442 
4443 
4444 /*
4445  * Interrupt which indicates that the Port Ready state has changed
4446  * from zero to one.
4447  *
4448  * We are not interested in this interrupt; we just log a debug message.
4449  */
4450 /*ARGSUSED*/
4451 static int
4452 si_intr_port_ready(
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_ready");
4458 	return (SI_SUCCESS);
4459 }
4460 
4461 /*
4462  * Interrupt which indicates that the port power management state
4463  * has been modified.
4464  *
4465  * We are not interested in this interrupt; we just log a debug message.
4466  */
4467 /*ARGSUSED*/
4468 static int
4469 si_intr_pwr_change(
4470 	si_ctl_state_t *si_ctlp,
4471 	si_port_state_t *si_portp,
4472 	int port)
4473 {
4474 	SIDBG0(SIDBG_INTR|SIDBG_ENTRY, si_ctlp, "si_intr_pwr_change");
4475 	return (SI_SUCCESS);
4476 }
4477 
4478 /*
4479  * Interrupt which indicates that the PHY state has changed either from
4480  * Not-Ready to Ready or from Ready to Not-Ready.
4481  */
4482 static int
4483 si_intr_phy_ready_change(
4484 	si_ctl_state_t *si_ctlp,
4485 	si_port_state_t *si_portp,
4486 	int port)
4487 {
4488 	sata_device_t sdevice;
4489 	uint32_t SStatus = 0; /* No dev present & PHY not established. */
4490 	int dev_exists_now = 0;
4491 	int dev_existed_previously = 0;
4492 
4493 	SIDBG0(SIDBG_INTR|SIDBG_ENTRY, si_ctlp, "si_intr_phy_rdy_change");
4494 
4495 	mutex_enter(&si_ctlp->sictl_mutex);
4496 	if ((si_ctlp->sictl_sata_hba_tran == NULL) || (si_portp == NULL)) {
4497 		/* the whole controller setup is not yet done. */
4498 		mutex_exit(&si_ctlp->sictl_mutex);
4499 		return (SI_SUCCESS);
4500 	}
4501 
4502 	mutex_exit(&si_ctlp->sictl_mutex);
4503 
4504 	mutex_enter(&si_portp->siport_mutex);
4505 
4506 	/* SStatus tells the presence of device. */
4507 	SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
4508 	    (uint32_t *)PORT_SSTATUS(si_ctlp, port));
4509 	dev_exists_now =
4510 	    (SSTATUS_GET_DET(SStatus) == SSTATUS_DET_DEVPRESENT_PHYONLINE);
4511 
4512 	if (si_portp->siport_port_type != PORT_TYPE_NODEV) {
4513 		dev_existed_previously = 1;
4514 	}
4515 
4516 	bzero((void *)&sdevice, sizeof (sata_device_t));
4517 
4518 	sdevice.satadev_addr.cport = (uint8_t)port;
4519 	sdevice.satadev_addr.pmport = PORTMULT_CONTROL_PORT;
4520 
4521 	/* we don't have a way of determining the exact port-mult port. */
4522 	if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
4523 		sdevice.satadev_addr.qual = SATA_ADDR_PMPORT;
4524 	} else {
4525 		sdevice.satadev_addr.qual = SATA_ADDR_CPORT;
4526 	}
4527 
4528 	sdevice.satadev_state = SATA_STATE_READY; /* port state */
4529 
4530 	if (dev_exists_now) {
4531 		if (dev_existed_previously) {
4532 
4533 			/* Things are fine now. The loss was temporary. */
4534 			SIDBG0(SIDBG_INTR, NULL,
4535 			    "phyrdy: doing BOTH EVENTS TOGETHER");
4536 			if (si_portp->siport_active) {
4537 				SIDBG0(SIDBG_EVENT, si_ctlp,
4538 				    "sending event: LINK_LOST & "
4539 				    "LINK_ESTABLISHED");
4540 
4541 				sata_hba_event_notify(
4542 				    si_ctlp->sictl_sata_hba_tran->\
4543 				    sata_tran_hba_dip,
4544 				    &sdevice,
4545 				    SATA_EVNT_LINK_LOST|
4546 				    SATA_EVNT_LINK_ESTABLISHED);
4547 			}
4548 
4549 		} else {
4550 
4551 			/* A new device has been detected. */
4552 			mutex_exit(&si_portp->siport_mutex);
4553 			si_find_dev_signature(si_ctlp, si_portp, port,
4554 			    PORTMULT_CONTROL_PORT);
4555 			mutex_enter(&si_portp->siport_mutex);
4556 			SIDBG0(SIDBG_INTR, NULL, "phyrdy: doing ATTACH event");
4557 			if (si_portp->siport_active) {
4558 				SIDBG0(SIDBG_EVENT, si_ctlp,
4559 				    "sending event up: LINK_ESTABLISHED");
4560 
4561 				sata_hba_event_notify(
4562 				    si_ctlp->sictl_sata_hba_tran->\
4563 				    sata_tran_hba_dip,
4564 				    &sdevice,
4565 				    SATA_EVNT_LINK_ESTABLISHED);
4566 			}
4567 
4568 		}
4569 	} else { /* No device exists now */
4570 
4571 		if (dev_existed_previously) {
4572 
4573 			/* An existing device is lost. */
4574 			if (si_portp->siport_active) {
4575 				SIDBG0(SIDBG_EVENT, si_ctlp,
4576 				    "sending event up: LINK_LOST");
4577 
4578 				sata_hba_event_notify(
4579 				    si_ctlp->sictl_sata_hba_tran->
4580 				    sata_tran_hba_dip,
4581 				    &sdevice,
4582 				    SATA_EVNT_LINK_LOST);
4583 			}
4584 			si_portp->siport_port_type = PORT_TYPE_NODEV;
4585 
4586 		}
4587 #if SI_DEBUG
4588 		else {
4589 
4590 			/* spurious interrupt */
4591 			SIDBG0(SIDBG_INTR, NULL,
4592 			    "spurious phy ready interrupt");
4593 		}
4594 #endif	/* SI_DEBUG */
4595 	}
4596 
4597 	mutex_exit(&si_portp->siport_mutex);
4598 	return (SI_SUCCESS);
4599 }
4600 
4601 
4602 /*
4603  * Interrupt which indicates that a COMWAKE OOB signal has been decoded
4604  * on the receiver.
4605  *
4606  * We are not interested in this interrupt; we just log a debug message.
4607  */
4608 /*ARGSUSED*/
4609 static int
4610 si_intr_comwake_rcvd(
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_commwake_rcvd");
4616 	return (SI_SUCCESS);
4617 }
4618 
4619 /*
4620  * Interrupt which indicates that the F-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_unrecognised_fis(
4628 	si_ctl_state_t *si_ctlp,
4629 	si_port_state_t *si_portp,
4630 	int port)
4631 {
4632 	SIDBG0(SIDBG_INTR|SIDBG_ENTRY, si_ctlp, "si_intr_unrecognised_fis");
4633 	return (SI_SUCCESS);
4634 }
4635 
4636 /*
4637  * Interrupt which indicates that the X-bit has been set in SError
4638  * Diag field.
4639  *
4640  * We are not interested in this interrupt; we just log a debug message.
4641  */
4642 /*ARGSUSED*/
4643 static int
4644 si_intr_dev_xchanged(
4645 	si_ctl_state_t *si_ctlp,
4646 	si_port_state_t *si_portp,
4647 	int port)
4648 {
4649 
4650 	SIDBG0(SIDBG_INTR|SIDBG_ENTRY, si_ctlp, "si_intr_dev_xchanged");
4651 	return (SI_SUCCESS);
4652 }
4653 
4654 /*
4655  * Interrupt which indicates that the 8b/10b Decode Error counter has
4656  * exceeded the 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_decode_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_err_threshold");
4668 	return (SI_SUCCESS);
4669 }
4670 
4671 /*
4672  * Interrupt which indicates that the CRC Error counter has exceeded the
4673  * 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_crc_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, "si_intr_crc_threshold");
4685 	return (SI_SUCCESS);
4686 }
4687 
4688 /*
4689  * Interrupt which indicates that the Handshake Error counter has
4690  * exceeded the programmed non-zero threshold value.
4691  *
4692  * We are not interested in this interrupt; we just log a debug message.
4693  */
4694 /*ARGSUSED*/
4695 static int
4696 si_intr_handshake_err_threshold(
4697 	si_ctl_state_t *si_ctlp,
4698 	si_port_state_t *si_portp,
4699 	int port)
4700 {
4701 	SIDBG0(SIDBG_INTR|SIDBG_ENTRY, si_ctlp,
4702 	    "si_intr_handshake_err_threshold");
4703 	return (SI_SUCCESS);
4704 }
4705 
4706 /*
4707  * Interrupt which indicates that a "Set Device Bits" FIS has been
4708  * received with N-bit set in the control field.
4709  *
4710  * We are not interested in this interrupt; we just log a debug message.
4711  */
4712 /*ARGSUSED*/
4713 static int
4714 si_intr_set_devbits_notify(
4715 	si_ctl_state_t *si_ctlp,
4716 	si_port_state_t *si_portp,
4717 	int port)
4718 {
4719 	SIDBG0(SIDBG_INTR|SIDBG_ENTRY, si_ctlp, "si_intr_set_devbits_notify");
4720 	return (SI_SUCCESS);
4721 }
4722 
4723 
4724 /*
4725  * Enable the interrupts for a particular port.
4726  *
4727  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4728  * before calling us.
4729  */
4730 static void
4731 si_enable_port_interrupts(si_ctl_state_t *si_ctlp, int port)
4732 {
4733 	uint32_t mask;
4734 
4735 	/* get the current settings first. */
4736 	mask = ddi_get32(si_ctlp->sictl_global_acc_handle,
4737 	    (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp));
4738 
4739 	SIDBG1(SIDBG_INIT|SIDBG_ENTRY, si_ctlp,
4740 	    "si_enable_port_interrupts: current mask: 0x%x",
4741 	    mask);
4742 
4743 	/* enable the bit for current port. */
4744 	SET_BIT(mask, port);
4745 
4746 	/* now use this mask to enable the interrupt. */
4747 	ddi_put32(si_ctlp->sictl_global_acc_handle,
4748 	    (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp),
4749 	    mask);
4750 }
4751 
4752 /*
4753  * Enable interrupts for all the ports.
4754  */
4755 static void
4756 si_enable_all_interrupts(si_ctl_state_t *si_ctlp)
4757 {
4758 	int port;
4759 
4760 	for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
4761 		si_enable_port_interrupts(si_ctlp, port);
4762 	}
4763 }
4764 
4765 /*
4766  * Disable interrupts for a particular port.
4767  *
4768  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4769  * before calling us.
4770  */
4771 static void
4772 si_disable_port_interrupts(si_ctl_state_t *si_ctlp, int port)
4773 {
4774 	uint32_t mask;
4775 
4776 	/* get the current settings first. */
4777 	mask = ddi_get32(si_ctlp->sictl_global_acc_handle,
4778 	    (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp));
4779 
4780 	/* clear the bit for current port. */
4781 	CLEAR_BIT(mask, port);
4782 
4783 	/* now use this mask to disable the interrupt. */
4784 	ddi_put32(si_ctlp->sictl_global_acc_handle,
4785 	    (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp),
4786 	    mask);
4787 
4788 }
4789 
4790 /*
4791  * Disable interrupts for all the ports.
4792  */
4793 static void
4794 si_disable_all_interrupts(si_ctl_state_t *si_ctlp)
4795 {
4796 	int port;
4797 
4798 	for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
4799 		si_disable_port_interrupts(si_ctlp, port);
4800 	}
4801 }
4802 
4803 /*
4804  * Fetches the latest sstatus, scontrol, serror, sactive registers
4805  * and stuffs them into sata_device_t structure.
4806  */
4807 static void
4808 fill_dev_sregisters(si_ctl_state_t *si_ctlp, int port, sata_device_t *satadev)
4809 {
4810 	satadev->satadev_scr.sstatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
4811 	    (uint32_t *)(PORT_SSTATUS(si_ctlp, port)));
4812 	satadev->satadev_scr.serror = ddi_get32(si_ctlp->sictl_port_acc_handle,
4813 	    (uint32_t *)(PORT_SERROR(si_ctlp, port)));
4814 	satadev->satadev_scr.sactive = ddi_get32(si_ctlp->sictl_port_acc_handle,
4815 	    (uint32_t *)(PORT_SACTIVE(si_ctlp, port)));
4816 	satadev->satadev_scr.scontrol =
4817 	    ddi_get32(si_ctlp->sictl_port_acc_handle,
4818 	    (uint32_t *)(PORT_SCONTROL(si_ctlp, port)));
4819 
4820 }
4821 
4822 /*
4823  * si_add_legacy_intrs() handles INTx and legacy interrupts.
4824  */
4825 static int
4826 si_add_legacy_intrs(si_ctl_state_t *si_ctlp)
4827 {
4828 	dev_info_t	*devinfo = si_ctlp->sictl_devinfop;
4829 	int		actual, count = 0;
4830 	int		x, y, rc, inum = 0;
4831 
4832 	SIDBG0(SIDBG_ENTRY, si_ctlp, "si_add_legacy_intrs");
4833 
4834 	/* get number of interrupts. */
4835 	rc = ddi_intr_get_nintrs(devinfo, DDI_INTR_TYPE_FIXED, &count);
4836 	if ((rc != DDI_SUCCESS) || (count == 0)) {
4837 		SIDBG2(SIDBG_INTR|SIDBG_INIT, si_ctlp,
4838 		    "ddi_intr_get_nintrs() failed, "
4839 		    "rc %d count %d\n", rc, count);
4840 		return (DDI_FAILURE);
4841 	}
4842 
4843 	/* Allocate an array of interrupt handles. */
4844 	si_ctlp->sictl_intr_size = count * sizeof (ddi_intr_handle_t);
4845 	si_ctlp->sictl_htable = kmem_zalloc(si_ctlp->sictl_intr_size, KM_SLEEP);
4846 
4847 	/* call ddi_intr_alloc(). */
4848 	rc = ddi_intr_alloc(devinfo, si_ctlp->sictl_htable, DDI_INTR_TYPE_FIXED,
4849 	    inum, count, &actual, DDI_INTR_ALLOC_STRICT);
4850 
4851 	if ((rc != DDI_SUCCESS) || (actual == 0)) {
4852 		SIDBG1(SIDBG_INTR|SIDBG_INIT, si_ctlp,
4853 		    "ddi_intr_alloc() failed, rc %d\n", rc);
4854 		kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
4855 		return (DDI_FAILURE);
4856 	}
4857 
4858 	if (actual < count) {
4859 		SIDBG2(SIDBG_INTR|SIDBG_INIT, si_ctlp,
4860 		    "Requested: %d, Received: %d", count, actual);
4861 
4862 		for (x = 0; x < actual; x++) {
4863 			(void) ddi_intr_free(si_ctlp->sictl_htable[x]);
4864 		}
4865 
4866 		kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
4867 		return (DDI_FAILURE);
4868 	}
4869 
4870 	si_ctlp->sictl_intr_cnt = actual;
4871 
4872 	/* Get intr priority. */
4873 	if (ddi_intr_get_pri(si_ctlp->sictl_htable[0],
4874 	    &si_ctlp->sictl_intr_pri) != DDI_SUCCESS) {
4875 		SIDBG0(SIDBG_INTR|SIDBG_INIT, si_ctlp,
4876 		    "ddi_intr_get_pri() failed");
4877 
4878 		for (x = 0; x < actual; x++) {
4879 			(void) ddi_intr_free(si_ctlp->sictl_htable[x]);
4880 		}
4881 
4882 		kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
4883 		return (DDI_FAILURE);
4884 	}
4885 
4886 	/* Test for high level mutex. */
4887 	if (si_ctlp->sictl_intr_pri >= ddi_intr_get_hilevel_pri()) {
4888 		SIDBG0(SIDBG_INTR|SIDBG_INIT, si_ctlp,
4889 		    "si_add_legacy_intrs: Hi level intr not supported");
4890 
4891 		for (x = 0; x < actual; x++) {
4892 			(void) ddi_intr_free(si_ctlp->sictl_htable[x]);
4893 		}
4894 
4895 		kmem_free(si_ctlp->sictl_htable, sizeof (ddi_intr_handle_t));
4896 
4897 		return (DDI_FAILURE);
4898 	}
4899 
4900 	/* Call ddi_intr_add_handler(). */
4901 	for (x = 0; x < actual; x++) {
4902 		if (ddi_intr_add_handler(si_ctlp->sictl_htable[x], si_intr,
4903 		    (caddr_t)si_ctlp, NULL) != DDI_SUCCESS) {
4904 			SIDBG0(SIDBG_INTR|SIDBG_INIT, si_ctlp,
4905 			    "ddi_intr_add_handler() failed");
4906 
4907 			for (y = 0; y < actual; y++) {
4908 				(void) ddi_intr_free(si_ctlp->sictl_htable[y]);
4909 			}
4910 
4911 			kmem_free(si_ctlp->sictl_htable,
4912 			    si_ctlp->sictl_intr_size);
4913 			return (DDI_FAILURE);
4914 		}
4915 	}
4916 
4917 	/* Call ddi_intr_enable() for legacy interrupts. */
4918 	for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
4919 		(void) ddi_intr_enable(si_ctlp->sictl_htable[x]);
4920 	}
4921 
4922 	return (DDI_SUCCESS);
4923 }
4924 
4925 /*
4926  * si_add_msictl_intrs() handles MSI interrupts.
4927  */
4928 static int
4929 si_add_msi_intrs(si_ctl_state_t *si_ctlp)
4930 {
4931 	dev_info_t	*devinfo = si_ctlp->sictl_devinfop;
4932 	int		count, avail, actual;
4933 	int		x, y, rc, inum = 0;
4934 
4935 	SIDBG0(SIDBG_ENTRY|SIDBG_INIT, si_ctlp, "si_add_msi_intrs");
4936 
4937 	/* get number of interrupts. */
4938 	rc = ddi_intr_get_nintrs(devinfo, DDI_INTR_TYPE_MSI, &count);
4939 	if ((rc != DDI_SUCCESS) || (count == 0)) {
4940 		SIDBG2(SIDBG_INIT, si_ctlp,
4941 		    "ddi_intr_get_nintrs() failed, "
4942 		    "rc %d count %d\n", rc, count);
4943 		return (DDI_FAILURE);
4944 	}
4945 
4946 	/* get number of available interrupts. */
4947 	rc = ddi_intr_get_navail(devinfo, DDI_INTR_TYPE_MSI, &avail);
4948 	if ((rc != DDI_SUCCESS) || (avail == 0)) {
4949 		SIDBG2(SIDBG_INIT, si_ctlp,
4950 		    "ddi_intr_get_navail() failed, "
4951 		    "rc %d avail %d\n", rc, avail);
4952 		return (DDI_FAILURE);
4953 	}
4954 
4955 #if SI_DEBUG
4956 	if (avail < count) {
4957 		SIDBG2(SIDBG_INIT, si_ctlp,
4958 		    "ddi_intr_get_nvail returned %d, navail() returned %d",
4959 		    count, avail);
4960 	}
4961 #endif	/* SI_DEBUG */
4962 
4963 	/* Allocate an array of interrupt handles. */
4964 	si_ctlp->sictl_intr_size = count * sizeof (ddi_intr_handle_t);
4965 	si_ctlp->sictl_htable = kmem_alloc(si_ctlp->sictl_intr_size, KM_SLEEP);
4966 
4967 	/* call ddi_intr_alloc(). */
4968 	rc = ddi_intr_alloc(devinfo, si_ctlp->sictl_htable, DDI_INTR_TYPE_MSI,
4969 	    inum, count, &actual, DDI_INTR_ALLOC_NORMAL);
4970 
4971 	if ((rc != DDI_SUCCESS) || (actual == 0)) {
4972 		SIDBG1(SIDBG_INIT, si_ctlp,
4973 		    "ddi_intr_alloc() failed, rc %d\n", rc);
4974 		kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
4975 		return (DDI_FAILURE);
4976 	}
4977 
4978 #if SI_DEBUG
4979 	/* use interrupt count returned */
4980 	if (actual < count) {
4981 		SIDBG2(SIDBG_INIT, si_ctlp,
4982 		    "Requested: %d, Received: %d", count, actual);
4983 	}
4984 #endif	/* SI_DEBUG */
4985 
4986 	si_ctlp->sictl_intr_cnt = actual;
4987 
4988 	/*
4989 	 * Get priority for first msi, assume remaining are all the same.
4990 	 */
4991 	if (ddi_intr_get_pri(si_ctlp->sictl_htable[0],
4992 	    &si_ctlp->sictl_intr_pri) != DDI_SUCCESS) {
4993 		SIDBG0(SIDBG_INIT, si_ctlp, "ddi_intr_get_pri() failed");
4994 
4995 		/* Free already allocated intr. */
4996 		for (y = 0; y < actual; y++) {
4997 			(void) ddi_intr_free(si_ctlp->sictl_htable[y]);
4998 		}
4999 
5000 		kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
5001 		return (DDI_FAILURE);
5002 	}
5003 
5004 	/* Test for high level mutex. */
5005 	if (si_ctlp->sictl_intr_pri >= ddi_intr_get_hilevel_pri()) {
5006 		SIDBG0(SIDBG_INIT, si_ctlp,
5007 		    "si_add_msi_intrs: Hi level intr not supported");
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, sizeof (ddi_intr_handle_t));
5015 
5016 		return (DDI_FAILURE);
5017 	}
5018 
5019 	/* Call ddi_intr_add_handler(). */
5020 	for (x = 0; x < actual; x++) {
5021 		if (ddi_intr_add_handler(si_ctlp->sictl_htable[x], si_intr,
5022 		    (caddr_t)si_ctlp, NULL) != DDI_SUCCESS) {
5023 			SIDBG0(SIDBG_INIT, si_ctlp,
5024 			    "ddi_intr_add_handler() failed");
5025 
5026 			/* Free already allocated intr. */
5027 			for (y = 0; y < actual; y++) {
5028 				(void) ddi_intr_free(si_ctlp->sictl_htable[y]);
5029 			}
5030 
5031 			kmem_free(si_ctlp->sictl_htable,
5032 			    si_ctlp->sictl_intr_size);
5033 			return (DDI_FAILURE);
5034 		}
5035 	}
5036 
5037 	(void) ddi_intr_get_cap(si_ctlp->sictl_htable[0],
5038 	    &si_ctlp->sictl_intr_cap);
5039 
5040 	if (si_ctlp->sictl_intr_cap & DDI_INTR_FLAG_BLOCK) {
5041 		/* Call ddi_intr_block_enable() for MSI. */
5042 		(void) ddi_intr_block_enable(si_ctlp->sictl_htable,
5043 		    si_ctlp->sictl_intr_cnt);
5044 	} else {
5045 		/* Call ddi_intr_enable() for MSI non block enable. */
5046 		for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
5047 			(void) ddi_intr_enable(si_ctlp->sictl_htable[x]);
5048 		}
5049 	}
5050 
5051 	return (DDI_SUCCESS);
5052 }
5053 
5054 /*
5055  * Removes the registered interrupts irrespective of whether they
5056  * were legacy or MSI.
5057  */
5058 static void
5059 si_rem_intrs(si_ctl_state_t *si_ctlp)
5060 {
5061 	int x;
5062 
5063 	SIDBG0(SIDBG_ENTRY, si_ctlp, "si_rem_intrs entered");
5064 
5065 	/* Disable all interrupts. */
5066 	if ((si_ctlp->sictl_intr_type == DDI_INTR_TYPE_MSI) &&
5067 	    (si_ctlp->sictl_intr_cap & DDI_INTR_FLAG_BLOCK)) {
5068 		/* Call ddi_intr_block_disable(). */
5069 		(void) ddi_intr_block_disable(si_ctlp->sictl_htable,
5070 		    si_ctlp->sictl_intr_cnt);
5071 	} else {
5072 		for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
5073 			(void) ddi_intr_disable(si_ctlp->sictl_htable[x]);
5074 		}
5075 	}
5076 
5077 	/* Call ddi_intr_remove_handler(). */
5078 	for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
5079 		(void) ddi_intr_remove_handler(si_ctlp->sictl_htable[x]);
5080 		(void) ddi_intr_free(si_ctlp->sictl_htable[x]);
5081 	}
5082 
5083 	kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
5084 }
5085 
5086 /*
5087  * Resets either the port or the device connected to the port based on
5088  * the flag variable.
5089  *
5090  * The reset effectively throws away all the pending commands. So, the caller
5091  * has to make provision to handle the pending commands.
5092  *
5093  * After the reset, we wait till the port is ready again.
5094  *
5095  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
5096  * before calling us.
5097  *
5098  * Note: Not port-mult aware.
5099  */
5100 static int
5101 si_reset_dport_wait_till_ready(
5102 	si_ctl_state_t *si_ctlp,
5103 	si_port_state_t *si_portp,
5104 	int port,
5105 	int flag)
5106 {
5107 	uint32_t port_status;
5108 	int loop_count = 0;
5109 	sata_device_t sdevice;
5110 	uint32_t SStatus;
5111 	uint32_t SControl;
5112 	uint32_t port_intr_status;
5113 
5114 	_NOTE(ASSUMING_PROTECTED(si_portp))
5115 
5116 	if (flag == SI_PORT_RESET) {
5117 		ddi_put32(si_ctlp->sictl_port_acc_handle,
5118 		    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
5119 		    PORT_CONTROL_SET_BITS_PORT_RESET);
5120 
5121 		/* Port reset is not self clearing. So clear it now. */
5122 		ddi_put32(si_ctlp->sictl_port_acc_handle,
5123 		    (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
5124 		    PORT_CONTROL_CLEAR_BITS_PORT_RESET);
5125 	} else {
5126 		/* Reset the device. */
5127 		ddi_put32(si_ctlp->sictl_port_acc_handle,
5128 		    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
5129 		    PORT_CONTROL_SET_BITS_DEV_RESET);
5130 
5131 		/*
5132 		 * tidbit: this bit is self clearing; so there is no need
5133 		 * for manual clear as we did for port reset.
5134 		 */
5135 	}
5136 
5137 	/* Set the reset in progress flag */
5138 	if (!(flag & SI_RESET_NO_EVENTS_UP)) {
5139 		si_portp->siport_reset_in_progress = 1;
5140 	}
5141 
5142 
5143 	/*
5144 	 * Every reset needs a PHY initialization.
5145 	 *
5146 	 * The way to initialize the PHY is to write a 1 and then
5147 	 * a 0 to DET field of SControl register.
5148 	 */
5149 
5150 	/* Fetch the current SControl before writing the DET part with 1. */
5151 	SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
5152 	    (uint32_t *)PORT_SCONTROL(si_ctlp, port));
5153 	SCONTROL_SET_DET(SControl, SCONTROL_DET_COMRESET);
5154 	ddi_put32(si_ctlp->sictl_port_acc_handle,
5155 	    (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
5156 	    SControl);
5157 #ifndef __lock_lint
5158 	delay(SI_10MS_TICKS); /* give time for COMRESET to percolate */
5159 #endif /* __lock_lint */
5160 
5161 	/* Now fetch the SControl again and rewrite the DET part with 0 */
5162 	SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
5163 	    (uint32_t *)PORT_SCONTROL(si_ctlp, port));
5164 	SCONTROL_SET_DET(SControl, SCONTROL_DET_NOACTION);
5165 	ddi_put32(si_ctlp->sictl_port_acc_handle,
5166 	    (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
5167 	    SControl);
5168 
5169 	/*
5170 	 * PHY may be initialized by now. Check the DET field of SStatus
5171 	 * to determine if there is a device present.
5172 	 *
5173 	 * The DET field is valid only if IPM field indicates that
5174 	 * the interface is in active state.
5175 	 */
5176 
5177 	loop_count = 0;
5178 	do {
5179 		SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
5180 		    (uint32_t *)PORT_SSTATUS(si_ctlp, port));
5181 
5182 		if (SSTATUS_GET_IPM(SStatus) !=
5183 		    SSTATUS_IPM_INTERFACE_ACTIVE) {
5184 			/*
5185 			 * If the interface is not active, the DET field
5186 			 * is considered not accurate. So we want to
5187 			 * continue looping.
5188 			 */
5189 			SSTATUS_SET_DET(SStatus, SSTATUS_DET_NODEV_NOPHY);
5190 		}
5191 
5192 		if (loop_count++ > SI_POLLRATE_SSTATUS) {
5193 			/* We are effectively timing out after 0.1 sec. */
5194 			break;
5195 		}
5196 
5197 		/* Wait for 10 millisec */
5198 #ifndef __lock_lint
5199 		delay(SI_10MS_TICKS);
5200 #endif /* __lock_lint */
5201 
5202 	} while (SSTATUS_GET_DET(SStatus) != SSTATUS_DET_DEVPRESENT_PHYONLINE);
5203 
5204 	SIDBG2(SIDBG_POLL_LOOP, si_ctlp,
5205 	    "si_reset_dport_wait_till_ready: loop count: %d, \
5206 		SStatus: 0x%x",
5207 	    loop_count,
5208 	    SStatus);
5209 
5210 	/* Now check for port readiness. */
5211 	loop_count = 0;
5212 	do {
5213 		port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
5214 		    (uint32_t *)PORT_STATUS(si_ctlp, port));
5215 
5216 		if (loop_count++ > SI_POLLRATE_PORTREADY) {
5217 			/* We are effectively timing out after 0.5 sec. */
5218 			break;
5219 		}
5220 
5221 		/* Wait for 10 millisec */
5222 #ifndef __lock_lint
5223 		delay(SI_10MS_TICKS);
5224 #endif /* __lock_lint */
5225 
5226 	} while (!(port_status & PORT_STATUS_BITS_PORT_READY));
5227 
5228 	SIDBG3(SIDBG_POLL_LOOP, si_ctlp,
5229 	    "si_reset_dport_wait_till_ready: loop count: %d, \
5230 		port_status: 0x%x, SStatus: 0x%x",
5231 	    loop_count,
5232 	    port_status,
5233 	    SStatus);
5234 
5235 	/* Indicate to the framework that a reset has happened. */
5236 	if (!(flag & SI_RESET_NO_EVENTS_UP)) {
5237 
5238 		bzero((void *)&sdevice, sizeof (sata_device_t));
5239 
5240 		sdevice.satadev_addr.cport = (uint8_t)port;
5241 		sdevice.satadev_addr.pmport = PORTMULT_CONTROL_PORT;
5242 
5243 		if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
5244 			sdevice.satadev_addr.qual = SATA_ADDR_DPMPORT;
5245 		} else {
5246 			sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
5247 		}
5248 		sdevice.satadev_state = SATA_DSTATE_RESET |
5249 		    SATA_DSTATE_PWR_ACTIVE;
5250 		if (si_ctlp->sictl_sata_hba_tran) {
5251 			sata_hba_event_notify(
5252 			    si_ctlp->sictl_sata_hba_tran->sata_tran_hba_dip,
5253 			    &sdevice,
5254 			    SATA_EVNT_DEVICE_RESET);
5255 		}
5256 
5257 		SIDBG0(SIDBG_EVENT, si_ctlp,
5258 		    "sending event up: SATA_EVNT_RESET");
5259 	}
5260 
5261 	if ((SSTATUS_GET_IPM(SStatus) == SSTATUS_IPM_INTERFACE_ACTIVE) &&
5262 	    (SSTATUS_GET_DET(SStatus) ==
5263 	    SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
5264 		/* The interface is active and the device is present */
5265 		if (!(port_status & PORT_STATUS_BITS_PORT_READY)) {
5266 			/* But the port is is not ready for some reason */
5267 			SIDBG0(SIDBG_POLL_LOOP, si_ctlp,
5268 			    "si_reset_dport_wait_till_ready failed");
5269 			return (SI_FAILURE);
5270 		}
5271 	}
5272 
5273 
5274 	/*
5275 	 * For some reason, we are losing the interrupt enablement after
5276 	 * any reset condition. So restore them back now.
5277 	 */
5278 
5279 	SIDBG1(SIDBG_INIT, si_ctlp,
5280 	    "current interrupt enable set: 0x%x",
5281 	    ddi_get32(si_ctlp->sictl_port_acc_handle,
5282 	    (uint32_t *)PORT_INTERRUPT_ENABLE_SET(si_ctlp, port)));
5283 
5284 	ddi_put32(si_ctlp->sictl_port_acc_handle,
5285 	    (uint32_t *)PORT_INTERRUPT_ENABLE_SET(si_ctlp, port),
5286 	    (INTR_COMMAND_COMPLETE |
5287 	    INTR_COMMAND_ERROR |
5288 	    INTR_PORT_READY |
5289 	    INTR_POWER_CHANGE |
5290 	    INTR_PHYRDY_CHANGE |
5291 	    INTR_COMWAKE_RECEIVED |
5292 	    INTR_UNRECOG_FIS |
5293 	    INTR_DEV_XCHANGED |
5294 	    INTR_SETDEVBITS_NOTIFY));
5295 
5296 	si_enable_port_interrupts(si_ctlp, port);
5297 
5298 	/*
5299 	 * make sure interrupts are cleared
5300 	 */
5301 	port_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
5302 	    (uint32_t *)PORT_INTERRUPT_STATUS(si_ctlp, port));
5303 
5304 	ddi_put32(si_ctlp->sictl_port_acc_handle,
5305 	    (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp,
5306 	    port)),
5307 	    port_intr_status & INTR_MASK);
5308 
5309 
5310 	SIDBG0(SIDBG_POLL_LOOP, si_ctlp,
5311 	    "si_reset_dport_wait_till_ready returning success");
5312 
5313 	return (SI_SUCCESS);
5314 }
5315 
5316 /*
5317  * Initializes the port.
5318  *
5319  * Initialization effectively throws away all the pending commands on
5320  * the port. So, the caller  has to make provision to handle the pending
5321  * commands.
5322  *
5323  * After the port initialization, we wait till the port is ready again.
5324  *
5325  * WARNING, WARNING: The caller is expected to obtain the siport_mutex
5326  * before calling us.
5327  */
5328 static int
5329 si_initialize_port_wait_till_ready(si_ctl_state_t *si_ctlp, int port)
5330 {
5331 	uint32_t port_status;
5332 	int loop_count = 0;
5333 	uint32_t SStatus;
5334 
5335 	/* Initialize the port. */
5336 	ddi_put32(si_ctlp->sictl_port_acc_handle,
5337 	    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
5338 	    PORT_CONTROL_SET_BITS_PORT_INITIALIZE);
5339 
5340 	/* Wait until Port Ready */
5341 	loop_count = 0;
5342 	do {
5343 		port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
5344 		    (uint32_t *)PORT_STATUS(si_ctlp, port));
5345 
5346 		if (loop_count++ > SI_POLLRATE_PORTREADY) {
5347 			SIDBG1(SIDBG_INTR, si_ctlp,
5348 			    "si_initialize_port_wait is timing out: "
5349 			    "port_status: %x",
5350 			    port_status);
5351 			/* We are effectively timing out after 0.5 sec. */
5352 			break;
5353 		}
5354 
5355 		/* Wait for 10 millisec */
5356 #ifndef __lock_lint
5357 		delay(SI_10MS_TICKS);
5358 #endif /* __lock_lint */
5359 
5360 	} while (!(port_status & PORT_STATUS_BITS_PORT_READY));
5361 
5362 	SIDBG1(SIDBG_POLL_LOOP, si_ctlp,
5363 	    "si_initialize_port_wait_till_ready: loop count: %d",
5364 	    loop_count);
5365 
5366 	SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
5367 	    (uint32_t *)PORT_SSTATUS(si_ctlp, port));
5368 
5369 	if ((SSTATUS_GET_IPM(SStatus) == SSTATUS_IPM_INTERFACE_ACTIVE) &&
5370 	    (SSTATUS_GET_DET(SStatus) ==
5371 	    SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
5372 		/* The interface is active and the device is present */
5373 		if (!(port_status & PORT_STATUS_BITS_PORT_READY)) {
5374 			/* But the port is is not ready for some reason */
5375 			return (SI_FAILURE);
5376 		}
5377 	}
5378 
5379 	return (SI_SUCCESS);
5380 }
5381 
5382 
5383 /*
5384  * si_watchdog_handler() calls us if it detects that there are some
5385  * commands which timed out. We recalculate the timed out commands once
5386  * again since some of them may have finished recently.
5387  */
5388 static void
5389 si_timeout_pkts(
5390 	si_ctl_state_t *si_ctlp,
5391 	si_port_state_t *si_portp,
5392 	int port,
5393 	uint32_t timedout_tags)
5394 {
5395 	uint32_t slot_status;
5396 	uint32_t finished_tags;
5397 
5398 	SIDBG0(SIDBG_TIMEOUT|SIDBG_ENTRY, si_ctlp, "si_timeout_pkts entry");
5399 
5400 	mutex_enter(&si_portp->siport_mutex);
5401 	slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
5402 	    (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
5403 
5404 	si_portp->mopping_in_progress++;
5405 
5406 	/*
5407 	 * Initialize the controller. The only way to timeout the commands
5408 	 * is to reset or initialize the controller. We mop commands after
5409 	 * the initialization.
5410 	 */
5411 	(void) si_initialize_port_wait_till_ready(si_ctlp, port);
5412 
5413 	/*
5414 	 * Recompute the timedout tags since some of them may have finished
5415 	 * meanwhile.
5416 	 */
5417 	finished_tags =  si_portp->siport_pending_tags &
5418 	    ~slot_status & SI_SLOT_MASK;
5419 	timedout_tags &= ~finished_tags;
5420 
5421 	SIDBG2(SIDBG_TIMEOUT, si_ctlp,
5422 	    "si_timeout_pkts: finished: %x, timeout: %x",
5423 	    finished_tags,
5424 	    timedout_tags);
5425 
5426 	si_mop_commands(si_ctlp,
5427 	    si_portp,
5428 	    port,
5429 	    slot_status,
5430 	    0, /* failed_tags */
5431 	    timedout_tags,
5432 	    0, /* aborting_tags */
5433 	    0);  /* reset_tags */
5434 
5435 	mutex_exit(&si_portp->siport_mutex);
5436 }
5437 
5438 
5439 
5440 /*
5441  * Watchdog handler kicks in every 5 seconds to timeout any commands pending
5442  * for long time.
5443  */
5444 static void
5445 si_watchdog_handler(si_ctl_state_t *si_ctlp)
5446 {
5447 	uint32_t pending_tags = 0;
5448 	uint32_t timedout_tags = 0;
5449 	si_port_state_t *si_portp;
5450 	int port;
5451 	int tmpslot;
5452 	sata_pkt_t *satapkt;
5453 
5454 	/* max number of cycles this packet should survive */
5455 	int max_life_cycles;
5456 
5457 	/* how many cycles this packet survived so far */
5458 	int watched_cycles;
5459 
5460 	mutex_enter(&si_ctlp->sictl_mutex);
5461 	SIDBG0(SIDBG_TIMEOUT|SIDBG_ENTRY, si_ctlp,
5462 	    "si_watchdog_handler entered");
5463 
5464 	for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
5465 
5466 		si_portp = si_ctlp->sictl_ports[port];
5467 		if (si_portp == NULL) {
5468 			continue;
5469 		}
5470 
5471 		mutex_enter(&si_portp->siport_mutex);
5472 
5473 		if (si_portp->siport_port_type == PORT_TYPE_NODEV) {
5474 			mutex_exit(&si_portp->siport_mutex);
5475 			continue;
5476 		}
5477 
5478 		/* Skip the check for those ports in error recovery */
5479 		if (si_portp->mopping_in_progress > 0) {
5480 			SIDBG1(SIDBG_INFO, si_ctlp,
5481 			    "si_watchdog_handler: port %d mopping "
5482 			    "in progress, so just return", port);
5483 			mutex_exit(&si_portp->siport_mutex);
5484 			continue;
5485 		}
5486 
5487 		pending_tags =  si_portp->siport_pending_tags;
5488 		timedout_tags = 0;
5489 		while (pending_tags) {
5490 			tmpslot = ddi_ffs(pending_tags) - 1;
5491 			if (tmpslot == -1) {
5492 				break;
5493 			}
5494 			satapkt = si_portp->siport_slot_pkts[tmpslot];
5495 
5496 			if ((satapkt != NULL) && satapkt->satapkt_time) {
5497 
5498 				/*
5499 				 * We are overloading satapkt_hba_driver_private
5500 				 * with watched_cycle count.
5501 				 *
5502 				 * If a packet has survived for more than it's
5503 				 * max life cycles, it is a candidate for time
5504 				 * out.
5505 				 */
5506 				watched_cycles = (int)(intptr_t)
5507 				    satapkt->satapkt_hba_driver_private;
5508 				watched_cycles++;
5509 				max_life_cycles = (satapkt->satapkt_time +
5510 				    si_watchdog_timeout - 1) /
5511 				    si_watchdog_timeout;
5512 				if (watched_cycles > max_life_cycles) {
5513 					timedout_tags |= (0x1 << tmpslot);
5514 					SIDBG1(SIDBG_TIMEOUT|SIDBG_VERBOSE,
5515 					    si_ctlp,
5516 					    "watchdog: timedout_tags: 0x%x",
5517 					    timedout_tags);
5518 				}
5519 				satapkt->satapkt_hba_driver_private =
5520 				    (void *)(intptr_t)watched_cycles;
5521 			}
5522 
5523 			CLEAR_BIT(pending_tags, tmpslot);
5524 		}
5525 
5526 		if (timedout_tags) {
5527 			mutex_exit(&si_portp->siport_mutex);
5528 			mutex_exit(&si_ctlp->sictl_mutex);
5529 			si_timeout_pkts(si_ctlp, si_portp, port, timedout_tags);
5530 			mutex_enter(&si_ctlp->sictl_mutex);
5531 			mutex_enter(&si_portp->siport_mutex);
5532 		}
5533 
5534 		mutex_exit(&si_portp->siport_mutex);
5535 	}
5536 
5537 	/* Reinstall the watchdog timeout handler. */
5538 	if (!(si_ctlp->sictl_flags & SI_NO_TIMEOUTS)) {
5539 		si_ctlp->sictl_timeout_id =
5540 		    timeout((void (*)(void *))si_watchdog_handler,
5541 		    (caddr_t)si_ctlp, si_watchdog_tick);
5542 	}
5543 	mutex_exit(&si_ctlp->sictl_mutex);
5544 }
5545 
5546 /*
5547  * FMA Functions
5548  */
5549 
5550 /*
5551  * The IO fault service error handling callback function
5552  */
5553 /*ARGSUSED*/
5554 static int
5555 si_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
5556 {
5557 	/*
5558 	 * as the driver can always deal with an error in any dma or
5559 	 * access handle, we can just return the fme_status value.
5560 	 */
5561 	pci_ereport_post(dip, err, NULL);
5562 	return (err->fme_status);
5563 }
5564 
5565 /*
5566  * si_fm_init - initialize fma capabilities and register with IO
5567  *              fault services.
5568  */
5569 static void
5570 si_fm_init(si_ctl_state_t *si_ctlp)
5571 {
5572 	/*
5573 	 * Need to change iblock to priority for new MSI intr
5574 	 */
5575 	ddi_iblock_cookie_t fm_ibc;
5576 
5577 	/* Only register with IO Fault Services if we have some capability */
5578 	if (si_ctlp->fm_capabilities) {
5579 		/* Adjust access and dma attributes for FMA */
5580 		accattr.devacc_attr_access = DDI_FLAGERR_ACC;
5581 		prb_sgt_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
5582 		buffer_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
5583 
5584 		/*
5585 		 * Register capabilities with IO Fault Services.
5586 		 * fm_capabilities will be updated to indicate
5587 		 * capabilities actually supported (not requested.)
5588 		 */
5589 		ddi_fm_init(si_ctlp->sictl_devinfop, &si_ctlp->fm_capabilities,
5590 		    &fm_ibc);
5591 
5592 		if (si_ctlp->fm_capabilities == DDI_FM_NOT_CAPABLE)
5593 			cmn_err(CE_WARN, "si_fm_init: ddi_fm_init fail");
5594 
5595 		/*
5596 		 * Initialize pci ereport capabilities if ereport
5597 		 * capable (should always be.)
5598 		 */
5599 		if (DDI_FM_EREPORT_CAP(si_ctlp->fm_capabilities) ||
5600 		    DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
5601 			pci_ereport_setup(si_ctlp->sictl_devinfop);
5602 		}
5603 
5604 		/*
5605 		 * Register error callback if error callback capable.
5606 		 */
5607 		if (DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
5608 			ddi_fm_handler_register(si_ctlp->sictl_devinfop,
5609 			    si_fm_error_cb, (void *) si_ctlp);
5610 		}
5611 	}
5612 }
5613 
5614 /*
5615  * si_fm_fini - Releases fma capabilities and un-registers with IO
5616  *              fault services.
5617  */
5618 static void
5619 si_fm_fini(si_ctl_state_t *si_ctlp)
5620 {
5621 	/* Only unregister FMA capabilities if registered */
5622 	if (si_ctlp->fm_capabilities) {
5623 		/*
5624 		 * Un-register error callback if error callback capable.
5625 		 */
5626 		if (DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
5627 			ddi_fm_handler_unregister(si_ctlp->sictl_devinfop);
5628 		}
5629 
5630 		/*
5631 		 * Release any resources allocated by pci_ereport_setup()
5632 		 */
5633 		if (DDI_FM_EREPORT_CAP(si_ctlp->fm_capabilities) ||
5634 		    DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
5635 			pci_ereport_teardown(si_ctlp->sictl_devinfop);
5636 		}
5637 
5638 		/* Unregister from IO Fault Services */
5639 		ddi_fm_fini(si_ctlp->sictl_devinfop);
5640 
5641 		/* Adjust access and dma attributes for FMA */
5642 		accattr.devacc_attr_access = DDI_DEFAULT_ACC;
5643 		prb_sgt_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
5644 		buffer_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
5645 	}
5646 }
5647 
5648 static int
5649 si_check_acc_handle(ddi_acc_handle_t handle)
5650 {
5651 	ddi_fm_error_t de;
5652 
5653 	ASSERT(handle != NULL);
5654 	ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION);
5655 	return (de.fme_status);
5656 }
5657 
5658 static int
5659 si_check_dma_handle(ddi_dma_handle_t handle)
5660 {
5661 	ddi_fm_error_t de;
5662 
5663 	ASSERT(handle != NULL);
5664 	ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION);
5665 	return (de.fme_status);
5666 }
5667 
5668 static int
5669 si_check_ctl_handles(si_ctl_state_t *si_ctlp)
5670 {
5671 	if ((si_check_acc_handle(si_ctlp->sictl_pci_conf_handle)
5672 	    != DDI_SUCCESS) ||
5673 	    (si_check_acc_handle(si_ctlp->sictl_global_acc_handle)
5674 	    != DDI_SUCCESS) ||
5675 	    (si_check_acc_handle(si_ctlp->sictl_port_acc_handle)
5676 	    != DDI_SUCCESS)) {
5677 		return (DDI_FAILURE);
5678 	}
5679 
5680 	return (DDI_SUCCESS);
5681 }
5682 
5683 /*
5684  * WARNING: The caller is expected to obtain the siport_mutex
5685  * before calling us.
5686  */
5687 static int
5688 si_check_port_handles(si_port_state_t *si_portp)
5689 {
5690 	if ((si_check_dma_handle(si_portp->siport_prbpool_dma_handle)
5691 	    != DDI_SUCCESS) ||
5692 	    (si_check_acc_handle(si_portp->siport_prbpool_acc_handle)
5693 	    != DDI_SUCCESS) ||
5694 	    (si_check_dma_handle(si_portp->siport_sgbpool_dma_handle)
5695 	    != DDI_SUCCESS) ||
5696 	    (si_check_acc_handle(si_portp->siport_sgbpool_acc_handle)
5697 	    != DDI_SUCCESS)) {
5698 		return (DDI_FAILURE);
5699 	}
5700 
5701 	return (DDI_SUCCESS);
5702 }
5703 
5704 static void
5705 si_fm_ereport(si_ctl_state_t *si_ctlp, char *detail, char *payload)
5706 {
5707 	uint64_t ena;
5708 	char buf[FM_MAX_CLASS];
5709 
5710 	(void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
5711 	ena = fm_ena_generate(0, FM_ENA_FMT1);
5712 
5713 	if (DDI_FM_EREPORT_CAP(si_ctlp->fm_capabilities)) {
5714 		ddi_fm_ereport_post(si_ctlp->sictl_devinfop, buf, ena,
5715 		    DDI_NOSLEEP,
5716 		    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERSION,
5717 		    "detailed_err_type", DATA_TYPE_STRING, payload,
5718 		    NULL);
5719 	}
5720 }
5721 
5722 #if SI_DEBUG
5723 /*
5724  * Logs the message.
5725  */
5726 static void
5727 si_log(si_ctl_state_t *si_ctlp, uint_t level, char *fmt, ...)
5728 {
5729 	va_list ap;
5730 
5731 	mutex_enter(&si_log_mutex);
5732 
5733 	va_start(ap, fmt);
5734 	if (si_ctlp) {
5735 		(void) sprintf(si_log_buf, "%s-[%d]:",
5736 		    ddi_get_name(si_ctlp->sictl_devinfop),
5737 		    ddi_get_instance(si_ctlp->sictl_devinfop));
5738 	} else {
5739 		(void) sprintf(si_log_buf, "si3124:");
5740 	}
5741 	(void) vsprintf(si_log_buf, fmt, ap);
5742 	va_end(ap);
5743 
5744 	cmn_err(level, "%s", si_log_buf);
5745 
5746 	mutex_exit(&si_log_mutex);
5747 
5748 }
5749 #endif	/* SI_DEBUG */
5750 
5751 static void
5752 si_copy_out_regs(sata_cmd_t *scmd, si_ctl_state_t *si_ctlp, uint8_t port,
5753 	uint8_t slot)
5754 {
5755 	uint32_t *fis_word_ptr;
5756 	si_prb_t *prb;
5757 	int i;
5758 
5759 	/*
5760 	 * The LRAM contains the the modified FIS after command completion, so
5761 	 * first copy it back to the in-core PRB pool.  To save read cycles,
5762 	 * just copy over the FIS portion of the PRB pool.
5763 	 */
5764 	prb =  &si_ctlp->sictl_ports[port]->siport_prbpool[slot];
5765 
5766 	fis_word_ptr = (uint32_t *)(void *)(&prb->prb_fis);
5767 
5768 	for (i = 0; i < (sizeof (fis_reg_h2d_t)/4); i++) {
5769 		fis_word_ptr[i] = ddi_get32(
5770 		    si_ctlp->sictl_port_acc_handle,
5771 		    (uint32_t *)(PORT_LRAM(si_ctlp, port,
5772 		    slot) + i * 4 + 0x08));
5773 	}
5774 
5775 	/*
5776 	 * always get the status register
5777 	 */
5778 	scmd->satacmd_status_reg = GET_FIS_COMMAND(prb->prb_fis);
5779 
5780 	DTRACE_PROBE1(satacmd_status_reg, int, scmd->satacmd_status_reg);
5781 
5782 	if (scmd->satacmd_flags.sata_copy_out_sec_count_msb) {
5783 		scmd->satacmd_sec_count_msb =
5784 		    GET_FIS_SECTOR_COUNT_EXP(prb->prb_fis);
5785 		SIDBG1(SIDBG_VERBOSE, NULL,
5786 		    "copyout satacmd_sec_count_msb %x\n",
5787 		    scmd->satacmd_sec_count_msb);
5788 	}
5789 
5790 	if (scmd->satacmd_flags.sata_copy_out_lba_low_msb) {
5791 		scmd->satacmd_lba_low_msb = GET_FIS_SECTOR_EXP(prb->prb_fis);
5792 		SIDBG1(SIDBG_VERBOSE, NULL, "copyout satacmd_lba_low_msb %x\n",
5793 		    scmd->satacmd_lba_low_msb);
5794 	}
5795 
5796 	if (scmd->satacmd_flags.sata_copy_out_lba_mid_msb) {
5797 		scmd->satacmd_lba_mid_msb = GET_FIS_CYL_LOW_EXP(prb->prb_fis);
5798 		SIDBG1(SIDBG_VERBOSE, NULL, "copyout satacmd_lba_mid_msb %x\n",
5799 		    scmd->satacmd_lba_mid_msb);
5800 	}
5801 
5802 	if (scmd->satacmd_flags.sata_copy_out_lba_high_msb) {
5803 		scmd->satacmd_lba_high_msb = GET_FIS_CYL_HI_EXP(prb->prb_fis);
5804 		SIDBG1(SIDBG_VERBOSE, NULL, "copyout satacmd_lba_high_msb %x\n",
5805 		    scmd->satacmd_lba_high_msb);
5806 	}
5807 
5808 	if (scmd->satacmd_flags.sata_copy_out_sec_count_lsb) {
5809 		scmd->satacmd_sec_count_lsb =
5810 		    GET_FIS_SECTOR_COUNT(prb->prb_fis);
5811 		SIDBG1(SIDBG_VERBOSE, NULL,
5812 		    "copyout satacmd_sec_count_lsb %x\n",
5813 		    scmd->satacmd_sec_count_lsb);
5814 	}
5815 
5816 	if (scmd->satacmd_flags.sata_copy_out_lba_low_lsb) {
5817 		scmd->satacmd_lba_low_lsb = GET_FIS_SECTOR(prb->prb_fis);
5818 		SIDBG1(SIDBG_VERBOSE, NULL, "copyout satacmd_lba_low_lsb %x\n",
5819 		    scmd->satacmd_lba_low_lsb);
5820 	}
5821 
5822 	if (scmd->satacmd_flags.sata_copy_out_lba_mid_lsb) {
5823 		scmd->satacmd_lba_mid_lsb = GET_FIS_CYL_LOW(prb->prb_fis);
5824 		SIDBG1(SIDBG_VERBOSE, NULL, "copyout satacmd_lba_mid_lsb %x\n",
5825 		    scmd->satacmd_lba_mid_lsb);
5826 	}
5827 
5828 	if (scmd->satacmd_flags.sata_copy_out_lba_high_lsb) {
5829 		scmd->satacmd_lba_high_lsb = GET_FIS_CYL_HI(prb->prb_fis);
5830 		SIDBG1(SIDBG_VERBOSE, NULL, "copyout satacmd_lba_high_lsb %x\n",
5831 		    scmd->satacmd_lba_high_lsb);
5832 	}
5833 
5834 	if (scmd->satacmd_flags.sata_copy_out_device_reg) {
5835 		scmd->satacmd_device_reg = GET_FIS_DEV_HEAD(prb->prb_fis);
5836 		SIDBG1(SIDBG_VERBOSE, NULL, "copyout satacmd_device_reg %x\n",
5837 		    scmd->satacmd_device_reg);
5838 	}
5839 
5840 	if (scmd->satacmd_flags.sata_copy_out_error_reg) {
5841 		scmd->satacmd_error_reg = GET_FIS_FEATURES(prb->prb_fis);
5842 		SIDBG1(SIDBG_VERBOSE, NULL, "copyout satacmd_error_reg %x\n",
5843 		    scmd->satacmd_error_reg);
5844 	}
5845 }
5846 
5847 /*
5848  * This function clear the special port by send the PORT RESET
5849  * After reset was sent, all commands running on the port
5850  * is aborted
5851  */
5852 static int
5853 si_clear_port(si_ctl_state_t *si_ctlp, int port)
5854 {
5855 
5856 	if (si_ctlp == NULL)
5857 		return (SI_FAILURE);
5858 	/*
5859 	 * reset this port so that all existing command
5860 	 * is clear
5861 	 */
5862 	ddi_put32(si_ctlp->sictl_port_acc_handle,
5863 	    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
5864 	    PORT_CONTROL_SET_BITS_PORT_RESET);
5865 
5866 	/* Port reset is not self clearing. So clear it now. */
5867 	ddi_put32(si_ctlp->sictl_port_acc_handle,
5868 	    (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
5869 	    PORT_CONTROL_CLEAR_BITS_PORT_RESET);
5870 	return (SI_SUCCESS);
5871 }
5872 
5873 /*
5874  * quiesce(9E) entry point.
5875  * This function is called when the system is single-threaded at high
5876  * PIL with preemption disabled. Therefore, this function must not be
5877  * blocked.
5878  *
5879  * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
5880  * DDI_FAILURE indicates an error condition and should almost never happen.
5881  */
5882 static int
5883 si_quiesce(dev_info_t *dip)
5884 {
5885 	si_ctl_state_t *si_ctlp;
5886 	int instance;
5887 	int port;
5888 
5889 	SIDBG0(SIDBG_INIT|SIDBG_ENTRY, NULL, "si_quiesce enter");
5890 	instance = ddi_get_instance(dip);
5891 	si_ctlp = ddi_get_soft_state(si_statep, instance);
5892 	if (si_ctlp == NULL)
5893 		return (DDI_FAILURE);
5894 
5895 	/*
5896 	 * Disable all the interrupts before quiesce
5897 	 */
5898 
5899 	for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
5900 		si_disable_port_interrupts(si_ctlp, port);
5901 		(void) si_clear_port(si_ctlp, port);
5902 	}
5903 
5904 	return (DDI_SUCCESS);
5905 }
5906