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