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