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