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