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