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