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