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