Print this page
10091 smatch fixes for ahci.c
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/sata/adapters/ahci/ahci.c
+++ new/usr/src/uts/common/io/sata/adapters/ahci/ahci.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
25 25 * Copyright (c) 2018, Joyent, Inc.
26 26 * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
27 27 */
28 28
29 29 /*
30 30 * AHCI (Advanced Host Controller Interface) SATA HBA Driver
31 31 *
32 32 * Power Management Support
33 33 * ------------------------
34 34 *
35 35 * At the moment, the ahci driver only implements suspend/resume to
36 36 * support Suspend to RAM on X86 feature. Device power management isn't
37 37 * implemented, link power management is disabled, and hot plug isn't
38 38 * allowed during the period from suspend to resume.
39 39 *
40 40 * For s/r support, the ahci driver only need to implement DDI_SUSPEND
41 41 * and DDI_RESUME entries, and don't need to take care of new requests
42 42 * sent down after suspend because the target driver (sd) has already
43 43 * handled these conditions, and blocked these requests. For the detailed
44 44 * information, please check with sdopen, sdclose and sdioctl routines.
45 45 *
46 46 *
47 47 * Enclosure Management Support
48 48 * ----------------------------
49 49 *
50 50 * The ahci driver has basic support for AHCI Enclosure Management (EM)
51 51 * services. The AHCI specification provides an area in the primary ahci BAR for
52 52 * posting data to send out to the enclosure management and provides a register
53 53 * that provides both information and control about this. While the
54 54 * specification allows for multiple forms of enclosure management, the only
55 55 * supported, and commonly found form, is the AHCI specified LED format. The LED
56 56 * format is often implemented as a one-way communication mechanism. Software
57 57 * can write out what it cares about into the aforementioned data buffer and
58 58 * then we wait for the transmission to be sent.
59 59 *
60 60 * This has some drawbacks. It means that we cannot know whether or not it has
61 61 * succeeded. This means we cannot ask hardware what it thinks the LEDs are
62 62 * set to. There's also the added unfortunate reality that firmware on the
63 63 * microcontroller driving this will often not show the LEDs if no drive is
64 64 * present and that actions taken may potentially cause this to get out of sync
65 65 * with what we expect it to be. For example, the specification does not
66 66 * describe what should happen if a drive is removed from the enclosure while
67 67 * this is set and what should happen when it returns. We can only infer that it
68 68 * should be the same.
69 69 *
70 70 * Because only a single command can be sent at any time and we don't want to
71 71 * interfere with controller I/O, we create a taskq dedicated to this that has a
72 72 * single thread. Both resets (which occur on attach and resume) and normal
73 73 * changes to the LED state will be driven through this taskq. Because the taskq
74 74 * has a single thread, this guarantees serial processing.
75 75 *
76 76 * Each userland-submitted task (basically not resets) has a reference counted
77 77 * task structure. This allows the thread that called it to be cancelled and
78 78 * have the system clean itself up. The user thread in ioctl blocks on a CV that
79 79 * can receive signals as it waits for completion. Note, there is no guarantee
80 80 * provided by the kernel that the first thread to enter the kernel will be the
81 81 * first one to change state.
82 82 */
83 83
84 84 #include <sys/note.h>
85 85 #include <sys/scsi/scsi.h>
86 86 #include <sys/pci.h>
87 87 #include <sys/disp.h>
88 88 #include <sys/sata/sata_hba.h>
89 89 #include <sys/sata/adapters/ahci/ahcireg.h>
90 90 #include <sys/sata/adapters/ahci/ahcivar.h>
91 91
92 92 /*
93 93 * FMA header files
94 94 */
95 95 #include <sys/ddifm.h>
96 96 #include <sys/fm/protocol.h>
97 97 #include <sys/fm/util.h>
98 98 #include <sys/fm/io/ddi.h>
99 99
100 100 /*
101 101 * EM Control header files
102 102 */
103 103 #include <sys/types.h>
104 104 #include <sys/file.h>
105 105 #include <sys/errno.h>
106 106 #include <sys/open.h>
107 107 #include <sys/cred.h>
108 108 #include <sys/ddi.h>
109 109 #include <sys/sunddi.h>
110 110
111 111 /*
112 112 * This is the string displayed by modinfo, etc.
113 113 */
114 114 static char ahci_ident[] = "ahci driver";
115 115
116 116 /*
117 117 * Function prototypes for driver entry points
118 118 */
119 119 static int ahci_attach(dev_info_t *, ddi_attach_cmd_t);
120 120 static int ahci_detach(dev_info_t *, ddi_detach_cmd_t);
121 121 static int ahci_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
122 122 static int ahci_quiesce(dev_info_t *);
123 123
124 124 /*
125 125 * Function prototypes for SATA Framework interfaces
126 126 */
127 127 static int ahci_register_sata_hba_tran(ahci_ctl_t *, uint32_t);
128 128 static int ahci_unregister_sata_hba_tran(ahci_ctl_t *);
129 129
130 130 static int ahci_tran_probe_port(dev_info_t *, sata_device_t *);
131 131 static int ahci_tran_start(dev_info_t *, sata_pkt_t *spkt);
132 132 static int ahci_tran_abort(dev_info_t *, sata_pkt_t *, int);
133 133 static int ahci_tran_reset_dport(dev_info_t *, sata_device_t *);
134 134 static int ahci_tran_hotplug_port_activate(dev_info_t *, sata_device_t *);
135 135 static int ahci_tran_hotplug_port_deactivate(dev_info_t *, sata_device_t *);
136 136 #if defined(__lock_lint)
137 137 static int ahci_selftest(dev_info_t *, sata_device_t *);
138 138 #endif
139 139
140 140 /*
141 141 * FMA Prototypes
142 142 */
143 143 static void ahci_fm_init(ahci_ctl_t *);
144 144 static void ahci_fm_fini(ahci_ctl_t *);
145 145 static int ahci_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void*);
146 146 int ahci_check_acc_handle(ddi_acc_handle_t);
147 147 int ahci_check_dma_handle(ddi_dma_handle_t);
148 148 void ahci_fm_ereport(ahci_ctl_t *, char *);
149 149 static int ahci_check_all_handle(ahci_ctl_t *);
150 150 static int ahci_check_ctl_handle(ahci_ctl_t *);
151 151 static int ahci_check_port_handle(ahci_ctl_t *, int);
152 152 static int ahci_check_slot_handle(ahci_port_t *, int);
153 153
154 154 /*
155 155 * Local function prototypes
156 156 */
157 157 static int ahci_setup_port_base_addresses(ahci_ctl_t *, ahci_port_t *);
158 158 static int ahci_alloc_ports_state(ahci_ctl_t *);
159 159 static void ahci_dealloc_ports_state(ahci_ctl_t *);
160 160 static int ahci_alloc_port_state(ahci_ctl_t *, uint8_t);
161 161 static void ahci_dealloc_port_state(ahci_ctl_t *, uint8_t);
162 162 static int ahci_alloc_rcvd_fis(ahci_ctl_t *, ahci_port_t *);
163 163 static void ahci_dealloc_rcvd_fis(ahci_port_t *);
164 164 static int ahci_alloc_cmd_list(ahci_ctl_t *, ahci_port_t *);
165 165 static void ahci_dealloc_cmd_list(ahci_ctl_t *, ahci_port_t *);
166 166 static int ahci_alloc_cmd_tables(ahci_ctl_t *, ahci_port_t *);
167 167 static void ahci_dealloc_cmd_tables(ahci_ctl_t *, ahci_port_t *);
168 168 static void ahci_alloc_pmult(ahci_ctl_t *, ahci_port_t *);
169 169 static void ahci_dealloc_pmult(ahci_ctl_t *, ahci_port_t *);
170 170
171 171 static int ahci_initialize_controller(ahci_ctl_t *);
172 172 static void ahci_uninitialize_controller(ahci_ctl_t *);
173 173 static int ahci_initialize_port(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
174 174 static int ahci_config_space_init(ahci_ctl_t *);
175 175 static void ahci_staggered_spin_up(ahci_ctl_t *, uint8_t);
176 176
177 177 static void ahci_drain_ports_taskq(ahci_ctl_t *);
178 178 static int ahci_rdwr_pmult(ahci_ctl_t *, ahci_addr_t *, uint8_t, uint32_t *,
179 179 uint8_t);
180 180 static int ahci_read_pmult(ahci_ctl_t *, ahci_addr_t *, uint8_t, uint32_t *);
181 181 static int ahci_write_pmult(ahci_ctl_t *, ahci_addr_t *, uint8_t, uint32_t);
182 182 static int ahci_update_pmult_pscr(ahci_ctl_t *, ahci_addr_t *,
183 183 sata_device_t *);
184 184 static int ahci_update_pmult_gscr(ahci_ctl_t *, ahci_addr_t *,
185 185 sata_pmult_gscr_t *);
186 186 static int ahci_initialize_pmult(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *,
187 187 sata_device_t *);
188 188 static int ahci_initialize_pmport(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
189 189 static int ahci_probe_pmult(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
190 190 static int ahci_probe_pmport(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *,
191 191 sata_device_t *);
192 192
193 193 static void ahci_disable_interface_pm(ahci_ctl_t *, uint8_t);
194 194 static int ahci_start_port(ahci_ctl_t *, ahci_port_t *, uint8_t);
195 195 static void ahci_find_dev_signature(ahci_ctl_t *, ahci_port_t *,
196 196 ahci_addr_t *);
197 197 static void ahci_update_sata_registers(ahci_ctl_t *, uint8_t, sata_device_t *);
198 198 static int ahci_deliver_satapkt(ahci_ctl_t *, ahci_port_t *,
199 199 ahci_addr_t *, sata_pkt_t *);
200 200 static int ahci_do_sync_start(ahci_ctl_t *, ahci_port_t *,
201 201 ahci_addr_t *, sata_pkt_t *);
202 202 static int ahci_claim_free_slot(ahci_ctl_t *, ahci_port_t *,
203 203 ahci_addr_t *, int);
204 204 static void ahci_copy_err_cnxt(sata_cmd_t *, ahci_fis_d2h_register_t *);
205 205 static void ahci_copy_ncq_err_page(sata_cmd_t *,
206 206 struct sata_ncq_error_recovery_page *);
207 207 static void ahci_copy_out_regs(sata_cmd_t *, ahci_fis_d2h_register_t *);
208 208 static void ahci_add_doneq(ahci_port_t *, sata_pkt_t *, int);
209 209 static void ahci_flush_doneq(ahci_port_t *);
210 210
211 211 static int ahci_software_reset(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
212 212 static int ahci_hba_reset(ahci_ctl_t *);
213 213 static int ahci_port_reset(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
214 214 static int ahci_pmport_reset(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
215 215 static void ahci_reject_all_abort_pkts(ahci_ctl_t *, ahci_port_t *, uint8_t);
216 216 static int ahci_reset_device_reject_pkts(ahci_ctl_t *, ahci_port_t *,
217 217 ahci_addr_t *);
218 218 static int ahci_reset_pmdevice_reject_pkts(ahci_ctl_t *, ahci_port_t *,
219 219 ahci_addr_t *);
220 220 static int ahci_reset_port_reject_pkts(ahci_ctl_t *, ahci_port_t *,
221 221 ahci_addr_t *);
222 222 static int ahci_reset_hba_reject_pkts(ahci_ctl_t *);
223 223 static int ahci_put_port_into_notrunning_state(ahci_ctl_t *, ahci_port_t *,
224 224 uint8_t);
225 225 static int ahci_restart_port_wait_till_ready(ahci_ctl_t *, ahci_port_t *,
226 226 uint8_t, int, int *);
227 227 static void ahci_mop_commands(ahci_ctl_t *, ahci_port_t *, uint32_t,
228 228 uint32_t, uint32_t, uint32_t, uint32_t);
229 229 static uint32_t ahci_get_rdlogext_data(ahci_ctl_t *, ahci_port_t *, uint8_t);
230 230 static void ahci_get_rqsense_data(ahci_ctl_t *, ahci_port_t *,
231 231 uint8_t, sata_pkt_t *);
232 232 static void ahci_fatal_error_recovery_handler(ahci_ctl_t *, ahci_port_t *,
233 233 ahci_addr_t *, uint32_t);
234 234 static void ahci_pmult_error_recovery_handler(ahci_ctl_t *, ahci_port_t *,
235 235 uint8_t, uint32_t);
236 236 static void ahci_timeout_pkts(ahci_ctl_t *, ahci_port_t *,
237 237 uint8_t, uint32_t);
238 238 static void ahci_events_handler(void *);
239 239 static void ahci_watchdog_handler(ahci_ctl_t *);
240 240
241 241 static uint_t ahci_intr(caddr_t, caddr_t);
242 242 static void ahci_port_intr(ahci_ctl_t *, ahci_port_t *, uint8_t);
243 243 static int ahci_add_intrs(ahci_ctl_t *, int);
244 244 static void ahci_rem_intrs(ahci_ctl_t *);
245 245 static void ahci_enable_all_intrs(ahci_ctl_t *);
246 246 static void ahci_disable_all_intrs(ahci_ctl_t *);
247 247 static void ahci_enable_port_intrs(ahci_ctl_t *, uint8_t);
248 248 static void ahci_disable_port_intrs(ahci_ctl_t *, uint8_t);
249 249
250 250 static int ahci_intr_cmd_cmplt(ahci_ctl_t *, ahci_port_t *, uint8_t);
251 251 static int ahci_intr_set_device_bits(ahci_ctl_t *, ahci_port_t *, uint8_t);
252 252 static int ahci_intr_ncq_events(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
253 253 static int ahci_intr_pmult_sntf_events(ahci_ctl_t *, ahci_port_t *, uint8_t);
254 254 static int ahci_intr_port_connect_change(ahci_ctl_t *, ahci_port_t *, uint8_t);
255 255 static int ahci_intr_device_mechanical_presence_status(ahci_ctl_t *,
256 256 ahci_port_t *, uint8_t);
257 257 static int ahci_intr_phyrdy_change(ahci_ctl_t *, ahci_port_t *, uint8_t);
258 258 static int ahci_intr_non_fatal_error(ahci_ctl_t *, ahci_port_t *,
259 259 uint8_t, uint32_t);
260 260 static int ahci_intr_fatal_error(ahci_ctl_t *, ahci_port_t *,
261 261 uint8_t, uint32_t);
262 262 static int ahci_intr_cold_port_detect(ahci_ctl_t *, ahci_port_t *, uint8_t);
263 263
264 264 static void ahci_get_ahci_addr(ahci_ctl_t *, sata_device_t *, ahci_addr_t *);
265 265 static int ahci_get_num_implemented_ports(uint32_t);
266 266 static void ahci_log_fatal_error_message(ahci_ctl_t *, uint8_t, uint32_t);
267 267 static void ahci_dump_commands(ahci_ctl_t *, uint8_t, uint32_t);
268 268 static void ahci_log_serror_message(ahci_ctl_t *, uint8_t, uint32_t, int);
269 269 #if AHCI_DEBUG
270 270 static void ahci_log(ahci_ctl_t *, uint_t, char *, ...);
271 271 #endif
272 272
273 273 static boolean_t ahci_em_init(ahci_ctl_t *);
274 274 static void ahci_em_fini(ahci_ctl_t *);
275 275 static void ahci_em_suspend(ahci_ctl_t *);
276 276 static void ahci_em_resume(ahci_ctl_t *);
277 277 static int ahci_em_ioctl(dev_info_t *, int, intptr_t);
278 278
279 279
280 280 /*
281 281 * DMA attributes for the data buffer
282 282 *
283 283 * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
284 284 * does not support 64-bit addressing
285 285 */
286 286 static ddi_dma_attr_t buffer_dma_attr = {
287 287 DMA_ATTR_V0, /* dma_attr_version */
288 288 0x0ull, /* dma_attr_addr_lo: lowest bus address */
289 289 0xffffffffffffffffull, /* dma_attr_addr_hi: highest bus address */
290 290 0x3fffffull, /* dma_attr_count_max i.e. for one cookie */
291 291 0x2ull, /* dma_attr_align: word aligned */
292 292 1, /* dma_attr_burstsizes */
293 293 1, /* dma_attr_minxfer */
294 294 0xffffffffull, /* dma_attr_maxxfer i.e. includes all cookies */
295 295 0xffffffffull, /* dma_attr_seg */
296 296 AHCI_PRDT_NUMBER, /* dma_attr_sgllen */
297 297 512, /* dma_attr_granular */
298 298 0, /* dma_attr_flags */
299 299 };
300 300
301 301 /*
302 302 * DMA attributes for the rcvd FIS
303 303 *
304 304 * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
305 305 * does not support 64-bit addressing
306 306 */
307 307 static ddi_dma_attr_t rcvd_fis_dma_attr = {
308 308 DMA_ATTR_V0, /* dma_attr_version */
309 309 0x0ull, /* dma_attr_addr_lo: lowest bus address */
310 310 0xffffffffffffffffull, /* dma_attr_addr_hi: highest bus address */
311 311 0xffffffffull, /* dma_attr_count_max i.e. for one cookie */
312 312 0x100ull, /* dma_attr_align: 256-byte aligned */
313 313 1, /* dma_attr_burstsizes */
314 314 1, /* dma_attr_minxfer */
315 315 0xffffffffull, /* dma_attr_maxxfer i.e. includes all cookies */
316 316 0xffffffffull, /* dma_attr_seg */
317 317 1, /* dma_attr_sgllen */
318 318 1, /* dma_attr_granular */
319 319 0, /* dma_attr_flags */
320 320 };
321 321
322 322 /*
323 323 * DMA attributes for the command list
324 324 *
325 325 * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
326 326 * does not support 64-bit addressing
327 327 */
328 328 static ddi_dma_attr_t cmd_list_dma_attr = {
329 329 DMA_ATTR_V0, /* dma_attr_version */
330 330 0x0ull, /* dma_attr_addr_lo: lowest bus address */
331 331 0xffffffffffffffffull, /* dma_attr_addr_hi: highest bus address */
332 332 0xffffffffull, /* dma_attr_count_max i.e. for one cookie */
333 333 0x400ull, /* dma_attr_align: 1K-byte aligned */
334 334 1, /* dma_attr_burstsizes */
335 335 1, /* dma_attr_minxfer */
336 336 0xffffffffull, /* dma_attr_maxxfer i.e. includes all cookies */
337 337 0xffffffffull, /* dma_attr_seg */
338 338 1, /* dma_attr_sgllen */
339 339 1, /* dma_attr_granular */
340 340 0, /* dma_attr_flags */
341 341 };
342 342
343 343 /*
344 344 * DMA attributes for cmd tables
345 345 *
346 346 * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
347 347 * does not support 64-bit addressing
348 348 */
349 349 static ddi_dma_attr_t cmd_table_dma_attr = {
350 350 DMA_ATTR_V0, /* dma_attr_version */
351 351 0x0ull, /* dma_attr_addr_lo: lowest bus address */
352 352 0xffffffffffffffffull, /* dma_attr_addr_hi: highest bus address */
353 353 0xffffffffull, /* dma_attr_count_max i.e. for one cookie */
354 354 0x80ull, /* dma_attr_align: 128-byte aligned */
355 355 1, /* dma_attr_burstsizes */
356 356 1, /* dma_attr_minxfer */
357 357 0xffffffffull, /* dma_attr_maxxfer i.e. includes all cookies */
358 358 0xffffffffull, /* dma_attr_seg */
359 359 1, /* dma_attr_sgllen */
360 360 1, /* dma_attr_granular */
361 361 0, /* dma_attr_flags */
362 362 };
363 363
364 364
365 365 /* Device access attributes */
366 366 static ddi_device_acc_attr_t accattr = {
367 367 DDI_DEVICE_ATTR_V1,
368 368 DDI_STRUCTURE_LE_ACC,
369 369 DDI_STRICTORDER_ACC,
370 370 DDI_DEFAULT_ACC
371 371 };
372 372
373 373 static struct dev_ops ahcictl_dev_ops = {
374 374 DEVO_REV, /* devo_rev */
375 375 0, /* refcnt */
376 376 ahci_getinfo, /* info */
377 377 nulldev, /* identify */
378 378 nulldev, /* probe */
379 379 ahci_attach, /* attach */
380 380 ahci_detach, /* detach */
381 381 nodev, /* no reset */
382 382 NULL, /* driver operations */
383 383 NULL, /* bus operations */
384 384 NULL, /* power */
385 385 ahci_quiesce, /* quiesce */
386 386 };
387 387
388 388 static sata_tran_hotplug_ops_t ahci_tran_hotplug_ops = {
389 389 SATA_TRAN_HOTPLUG_OPS_REV_1,
390 390 ahci_tran_hotplug_port_activate,
391 391 ahci_tran_hotplug_port_deactivate
392 392 };
393 393
394 394 extern struct mod_ops mod_driverops;
395 395
396 396 static struct modldrv modldrv = {
397 397 &mod_driverops, /* driverops */
398 398 ahci_ident, /* short description */
399 399 &ahcictl_dev_ops, /* driver ops */
400 400 };
401 401
402 402 static struct modlinkage modlinkage = {
403 403 MODREV_1,
404 404 &modldrv,
405 405 NULL
406 406 };
407 407
408 408 /* The following variables are watchdog handler related */
409 409 static clock_t ahci_watchdog_timeout = 5; /* 5 seconds */
410 410 static clock_t ahci_watchdog_tick;
411 411
412 412 /*
413 413 * This static variable indicates the size of command table,
414 414 * and it's changeable with prdt number, which ahci_dma_prdt_number
415 415 * indicates.
416 416 */
417 417 static size_t ahci_cmd_table_size;
418 418
419 419 /*
420 420 * The below global variables are tunable via /etc/system
421 421 *
422 422 * ahci_dma_prdt_number
423 423 * ahci_msi_enabled
424 424 * ahci_buf_64bit_dma
425 425 * ahci_commu_64bit_dma
426 426 */
427 427
428 428 /* The number of Physical Region Descriptor Table(PRDT) in Command Table */
429 429 int ahci_dma_prdt_number = AHCI_PRDT_NUMBER;
430 430
431 431 /* AHCI MSI is tunable */
432 432 boolean_t ahci_msi_enabled = B_TRUE;
433 433
434 434 /*
435 435 * 64-bit dma addressing for data buffer is tunable
436 436 *
437 437 * The variable controls only the below value:
438 438 * DBAU (upper 32-bits physical address of data block)
439 439 */
440 440 boolean_t ahci_buf_64bit_dma = B_TRUE;
441 441
442 442 /*
443 443 * 64-bit dma addressing for communication system descriptors is tunable
444 444 *
445 445 * The variable controls the below three values:
446 446 *
447 447 * PxCLBU (upper 32-bits for the command list base physical address)
448 448 * PxFBU (upper 32-bits for the received FIS base physical address)
449 449 * CTBAU (upper 32-bits of command table base)
450 450 */
451 451 boolean_t ahci_commu_64bit_dma = B_TRUE;
452 452
453 453 /*
454 454 * By default, 64-bit dma for data buffer will be disabled for AMD/ATI SB600
455 455 * chipset. If the users want to have a try with 64-bit dma, please change
456 456 * the below variable value to enable it.
457 457 */
458 458 boolean_t sb600_buf_64bit_dma_disable = B_TRUE;
459 459
460 460 /*
461 461 * By default, 64-bit dma for command buffer will be disabled for AMD/ATI
462 462 * SB600/700/710/750/800. If the users want to have a try with 64-bit dma,
463 463 * please change the below value to enable it.
464 464 */
465 465 boolean_t sbxxx_commu_64bit_dma_disable = B_TRUE;
466 466
467 467 /*
468 468 * These values control the default delay and default number of times to wait
469 469 * for an enclosure message to complete.
470 470 */
471 471 uint_t ahci_em_reset_delay_ms = 1;
472 472 uint_t ahci_em_reset_delay_count = 1000;
473 473 uint_t ahci_em_tx_delay_ms = 1;
474 474 uint_t ahci_em_tx_delay_count = 1000;
475 475
476 476
477 477 /*
478 478 * End of global tunable variable definition
479 479 */
480 480
481 481 #if AHCI_DEBUG
482 482 uint32_t ahci_debug_flags = 0;
483 483 #else
484 484 uint32_t ahci_debug_flags = (AHCIDBG_ERRS|AHCIDBG_TIMEOUT);
485 485 #endif
486 486
487 487
488 488 #if AHCI_DEBUG
489 489 /* The following is needed for ahci_log() */
490 490 static kmutex_t ahci_log_mutex;
491 491 static char ahci_log_buf[512];
492 492 #endif
493 493
494 494 /* Opaque state pointer initialized by ddi_soft_state_init() */
495 495 static void *ahci_statep = NULL;
496 496
497 497 /*
498 498 * ahci module initialization.
499 499 */
500 500 int
501 501 _init(void)
502 502 {
503 503 int ret;
504 504
505 505 ret = ddi_soft_state_init(&ahci_statep, sizeof (ahci_ctl_t), 0);
506 506 if (ret != 0) {
507 507 goto err_out;
508 508 }
509 509
510 510 #if AHCI_DEBUG
511 511 mutex_init(&ahci_log_mutex, NULL, MUTEX_DRIVER, NULL);
512 512 #endif
513 513
514 514 if ((ret = sata_hba_init(&modlinkage)) != 0) {
515 515 #if AHCI_DEBUG
516 516 mutex_destroy(&ahci_log_mutex);
517 517 #endif
518 518 ddi_soft_state_fini(&ahci_statep);
519 519 goto err_out;
520 520 }
521 521
522 522 /* watchdog tick */
523 523 ahci_watchdog_tick = drv_usectohz(
524 524 (clock_t)ahci_watchdog_timeout * 1000000);
525 525
526 526 ret = mod_install(&modlinkage);
527 527 if (ret != 0) {
528 528 sata_hba_fini(&modlinkage);
529 529 #if AHCI_DEBUG
530 530 mutex_destroy(&ahci_log_mutex);
531 531 #endif
532 532 ddi_soft_state_fini(&ahci_statep);
533 533 goto err_out;
534 534 }
535 535
536 536 return (ret);
537 537
538 538 err_out:
539 539 cmn_err(CE_WARN, "!ahci: Module init failed");
540 540 return (ret);
541 541 }
542 542
543 543 /*
544 544 * ahci module uninitialize.
545 545 */
546 546 int
547 547 _fini(void)
548 548 {
549 549 int ret;
550 550
551 551 ret = mod_remove(&modlinkage);
552 552 if (ret != 0) {
553 553 return (ret);
554 554 }
555 555
556 556 /* Remove the resources allocated in _init(). */
557 557 sata_hba_fini(&modlinkage);
558 558 #if AHCI_DEBUG
559 559 mutex_destroy(&ahci_log_mutex);
560 560 #endif
561 561 ddi_soft_state_fini(&ahci_statep);
562 562
563 563 return (ret);
564 564 }
565 565
566 566 /*
567 567 * _info entry point
568 568 */
569 569 int
570 570 _info(struct modinfo *modinfop)
571 571 {
572 572 return (mod_info(&modlinkage, modinfop));
573 573 }
574 574
575 575 /*
576 576 * The attach entry point for dev_ops.
577 577 */
578 578 static int
579 579 ahci_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
580 580 {
581 581 ahci_ctl_t *ahci_ctlp = NULL;
582 582 int instance = ddi_get_instance(dip);
583 583 int status;
584 584 int attach_state;
585 585 uint32_t cap_status, ahci_version;
586 586 uint32_t ghc_control;
587 587 int intr_types;
588 588 int i;
589 589 pci_regspec_t *regs;
590 590 int regs_length;
591 591 int rnumber;
592 592 #if AHCI_DEBUG
593 593 int speed;
594 594 #endif
595 595
596 596 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp, "ahci_attach enter",
597 597 NULL);
598 598
599 599 switch (cmd) {
600 600 case DDI_ATTACH:
601 601 break;
602 602
603 603 case DDI_RESUME:
604 604
605 605 /*
606 606 * During DDI_RESUME, the hardware state of the device
607 607 * (power may have been removed from the device) must be
608 608 * restored, allow pending requests to continue, and
609 609 * service new requests.
610 610 */
611 611 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
612 612 mutex_enter(&ahci_ctlp->ahcictl_mutex);
613 613
614 614 /*
615 615 * GHC.AE must be set to 1 before any other AHCI register
616 616 * is accessed
617 617 */
618 618 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
619 619 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
620 620 ghc_control |= AHCI_HBA_GHC_AE;
621 621 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
622 622 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
623 623
624 624 /* Restart watch thread */
625 625 if (ahci_ctlp->ahcictl_timeout_id == 0)
626 626 ahci_ctlp->ahcictl_timeout_id = timeout(
627 627 (void (*)(void *))ahci_watchdog_handler,
628 628 (caddr_t)ahci_ctlp, ahci_watchdog_tick);
629 629
630 630 mutex_exit(&ahci_ctlp->ahcictl_mutex);
631 631
632 632 /*
633 633 * Re-initialize the controller and enable the interrupts and
634 634 * restart all the ports.
635 635 *
636 636 * Note that so far we don't support hot-plug during
637 637 * suspend/resume.
638 638 */
639 639 if (ahci_initialize_controller(ahci_ctlp) != AHCI_SUCCESS) {
640 640 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PM, ahci_ctlp,
641 641 "Failed to initialize the controller "
642 642 "during DDI_RESUME", NULL);
643 643 return (DDI_FAILURE);
644 644 }
645 645
646 646 /*
647 647 * Reset the enclosure services.
648 648 */
649 649 ahci_em_resume(ahci_ctlp);
650 650
651 651 mutex_enter(&ahci_ctlp->ahcictl_mutex);
652 652 ahci_ctlp->ahcictl_flags &= ~AHCI_SUSPEND;
653 653 mutex_exit(&ahci_ctlp->ahcictl_mutex);
654 654
655 655 return (DDI_SUCCESS);
656 656
657 657 default:
658 658 return (DDI_FAILURE);
659 659 }
660 660
661 661 attach_state = AHCI_ATTACH_STATE_NONE;
662 662
663 663 /* Allocate soft state */
664 664 status = ddi_soft_state_zalloc(ahci_statep, instance);
665 665 if (status != DDI_SUCCESS) {
666 666 cmn_err(CE_WARN, "!ahci%d: Cannot allocate soft state",
667 667 instance);
668 668 goto err_out;
669 669 }
670 670
671 671 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
672 672 ahci_ctlp->ahcictl_flags |= AHCI_ATTACH;
673 673 ahci_ctlp->ahcictl_dip = dip;
674 674
675 675 /* Initialize the cport/port mapping */
676 676 for (i = 0; i < AHCI_MAX_PORTS; i++) {
677 677 ahci_ctlp->ahcictl_port_to_cport[i] = 0xff;
678 678 ahci_ctlp->ahcictl_cport_to_port[i] = 0xff;
679 679 }
680 680
681 681 attach_state |= AHCI_ATTACH_STATE_STATEP_ALLOC;
682 682
683 683 /* Initialize FMA properties */
684 684 ahci_fm_init(ahci_ctlp);
685 685
686 686 attach_state |= AHCI_ATTACH_STATE_FMA;
687 687
688 688 /*
689 689 * Now map the AHCI base address; which includes global
690 690 * registers and port control registers
691 691 *
692 692 * According to the spec, the AHCI Base Address is BAR5,
693 693 * but BAR0-BAR4 are optional, so we need to check which
694 694 * rnumber is used for BAR5.
695 695 */
696 696
697 697 /*
698 698 * search through DDI "reg" property for the AHCI register set
699 699 */
700 700 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
701 701 DDI_PROP_DONTPASS, "reg", (int **)®s,
702 702 (uint_t *)®s_length) != DDI_PROP_SUCCESS) {
703 703 cmn_err(CE_WARN, "!ahci%d: Cannot lookup reg property",
704 704 instance);
705 705 goto err_out;
706 706 }
707 707
708 708 /* AHCI Base Address is located at 0x24 offset */
709 709 for (rnumber = 0; rnumber < regs_length; ++rnumber) {
710 710 if ((regs[rnumber].pci_phys_hi & PCI_REG_REG_M)
711 711 == AHCI_PCI_RNUM)
712 712 break;
713 713 }
714 714
715 715 ddi_prop_free(regs);
716 716
717 717 if (rnumber == regs_length) {
718 718 cmn_err(CE_WARN, "!ahci%d: Cannot find AHCI register set",
719 719 instance);
720 720 goto err_out;
721 721 }
722 722
723 723 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "rnumber = %d", rnumber);
724 724
725 725 status = ddi_regs_map_setup(dip,
726 726 rnumber,
727 727 (caddr_t *)&ahci_ctlp->ahcictl_ahci_addr,
728 728 0,
729 729 0,
730 730 &accattr,
731 731 &ahci_ctlp->ahcictl_ahci_acc_handle);
732 732 if (status != DDI_SUCCESS) {
733 733 cmn_err(CE_WARN, "!ahci%d: Cannot map register space",
734 734 instance);
735 735 goto err_out;
736 736 }
737 737
738 738 attach_state |= AHCI_ATTACH_STATE_REG_MAP;
739 739
740 740 /*
741 741 * GHC.AE must be set to 1 before any other AHCI register
742 742 * is accessed
743 743 */
744 744 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
745 745 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
746 746 ghc_control |= AHCI_HBA_GHC_AE;
747 747 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
748 748 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
749 749
750 750 /* Get the AHCI version information */
751 751 ahci_version = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
752 752 (uint32_t *)AHCI_GLOBAL_VS(ahci_ctlp));
753 753
754 754 cmn_err(CE_NOTE, "!ahci%d: hba AHCI version = %x.%x", instance,
755 755 (ahci_version & 0xffff0000) >> 16,
756 756 ((ahci_version & 0x0000ff00) >> 4 |
757 757 (ahci_version & 0x000000ff)));
758 758
759 759 /* We don't support controllers whose versions are lower than 1.0 */
760 760 if (!(ahci_version & 0xffff0000)) {
761 761 cmn_err(CE_WARN, "ahci%d: Don't support AHCI HBA with lower "
762 762 "than version 1.0", instance);
763 763 goto err_out;
764 764 }
765 765
766 766 /* Get the HBA capabilities information */
767 767 cap_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
768 768 (uint32_t *)AHCI_GLOBAL_CAP(ahci_ctlp));
769 769
770 770 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba capabilities = 0x%x",
771 771 cap_status);
772 772
773 773 /* CAP2 (HBA Capabilities Extended) is available since AHCI spec 1.2 */
774 774 if (ahci_version >= 0x00010200) {
775 775 uint32_t cap2_status;
776 776
777 777 /* Get the HBA capabilities extended information */
778 778 cap2_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
779 779 (uint32_t *)AHCI_GLOBAL_CAP2(ahci_ctlp));
780 780
781 781 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
782 782 "hba capabilities extended = 0x%x", cap2_status);
783 783 }
784 784
785 785 if (cap_status & AHCI_HBA_CAP_EMS) {
786 786 ahci_ctlp->ahcictl_cap |= AHCI_CAP_EMS;
787 787 ahci_ctlp->ahcictl_em_loc =
788 788 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
789 789 (uint32_t *)AHCI_GLOBAL_EM_LOC(ahci_ctlp));
790 790 ahci_ctlp->ahcictl_em_ctl =
791 791 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
792 792 (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp));
793 793 }
794 794
795 795 #if AHCI_DEBUG
796 796 /* Get the interface speed supported by the HBA */
797 797 speed = (cap_status & AHCI_HBA_CAP_ISS) >> AHCI_HBA_CAP_ISS_SHIFT;
798 798 if (speed == 0x01) {
799 799 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
800 800 "hba interface speed support: Gen 1 (1.5Gbps)", NULL);
801 801 } else if (speed == 0x10) {
802 802 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
803 803 "hba interface speed support: Gen 2 (3 Gbps)", NULL);
804 804 } else if (speed == 0x11) {
805 805 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
806 806 "hba interface speed support: Gen 3 (6 Gbps)", NULL);
807 807 }
808 808 #endif
809 809
810 810 /* Get the number of command slots supported by the HBA */
811 811 ahci_ctlp->ahcictl_num_cmd_slots =
812 812 ((cap_status & AHCI_HBA_CAP_NCS) >>
813 813 AHCI_HBA_CAP_NCS_SHIFT) + 1;
814 814
815 815 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba number of cmd slots: %d",
816 816 ahci_ctlp->ahcictl_num_cmd_slots);
817 817
818 818 /* Get the bit map which indicates ports implemented by the HBA */
819 819 ahci_ctlp->ahcictl_ports_implemented =
820 820 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
821 821 (uint32_t *)AHCI_GLOBAL_PI(ahci_ctlp));
822 822
823 823 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba implementation of ports: 0x%x",
824 824 ahci_ctlp->ahcictl_ports_implemented);
825 825
826 826 /* Max port number implemented */
827 827 ahci_ctlp->ahcictl_num_ports =
828 828 ddi_fls(ahci_ctlp->ahcictl_ports_implemented);
829 829
830 830 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba number of ports: %d",
831 831 (cap_status & AHCI_HBA_CAP_NP) + 1);
832 832
833 833 /* Get the number of implemented ports by the HBA */
834 834 ahci_ctlp->ahcictl_num_implemented_ports =
835 835 ahci_get_num_implemented_ports(
836 836 ahci_ctlp->ahcictl_ports_implemented);
837 837
838 838 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
839 839 "hba number of implemented ports: %d",
840 840 ahci_ctlp->ahcictl_num_implemented_ports);
841 841
842 842 /* Check whether HBA supports 64bit DMA addressing */
843 843 if (!(cap_status & AHCI_HBA_CAP_S64A)) {
844 844 ahci_ctlp->ahcictl_cap |= AHCI_CAP_BUF_32BIT_DMA;
845 845 ahci_ctlp->ahcictl_cap |= AHCI_CAP_COMMU_32BIT_DMA;
846 846 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
847 847 "hba does not support 64-bit addressing", NULL);
848 848 }
849 849
850 850 /* Checking for the support of Port Multiplier */
851 851 if (cap_status & AHCI_HBA_CAP_SPM) {
852 852 ahci_ctlp->ahcictl_cap |= AHCI_CAP_PMULT_CBSS;
853 853 AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
854 854 "hba supports port multiplier (CBSS)", NULL);
855 855
856 856 /* Support FIS-based switching ? */
857 857 if (cap_status & AHCI_HBA_CAP_FBSS) {
858 858 ahci_ctlp->ahcictl_cap |= AHCI_CAP_PMULT_FBSS;
859 859 AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
860 860 "hba supports FIS-based switching (FBSS)", NULL);
861 861 }
862 862 }
863 863
864 864 /* Checking for Support Command List Override */
865 865 if (cap_status & AHCI_HBA_CAP_SCLO) {
866 866 ahci_ctlp->ahcictl_cap |= AHCI_CAP_SCLO;
867 867 AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
868 868 "hba supports command list override.", NULL);
869 869 }
870 870
871 871 /* Checking for Asynchronous Notification */
872 872 if (cap_status & AHCI_HBA_CAP_SSNTF) {
873 873 ahci_ctlp->ahcictl_cap |= AHCI_CAP_SNTF;
874 874 AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
875 875 "hba supports asynchronous notification.", NULL);
876 876 }
877 877
878 878 if (pci_config_setup(dip, &ahci_ctlp->ahcictl_pci_conf_handle)
879 879 != DDI_SUCCESS) {
880 880 cmn_err(CE_WARN, "!ahci%d: Cannot set up pci configure space",
881 881 instance);
882 882 goto err_out;
883 883 }
884 884
885 885 attach_state |= AHCI_ATTACH_STATE_PCICFG_SETUP;
886 886
887 887 /*
888 888 * Check the pci configuration space, and set caps. We also
889 889 * handle the hardware defect in this function.
890 890 *
891 891 * For example, force ATI SB600 to use 32-bit dma addressing
892 892 * since it doesn't support 64-bit dma though its CAP register
893 893 * declares it support.
894 894 */
895 895 if (ahci_config_space_init(ahci_ctlp) == AHCI_FAILURE) {
896 896 cmn_err(CE_WARN, "!ahci%d: ahci_config_space_init failed",
897 897 instance);
898 898 goto err_out;
899 899 }
900 900
901 901 /*
902 902 * Disable the whole controller interrupts before adding
903 903 * interrupt handlers(s).
904 904 */
905 905 ahci_disable_all_intrs(ahci_ctlp);
906 906
907 907 /* Get supported interrupt types */
908 908 if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) {
909 909 cmn_err(CE_WARN, "!ahci%d: ddi_intr_get_supported_types failed",
910 910 instance);
911 911 goto err_out;
912 912 }
913 913
914 914 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
915 915 "ddi_intr_get_supported_types() returned: 0x%x",
916 916 intr_types);
917 917
918 918 if (ahci_msi_enabled && (intr_types & DDI_INTR_TYPE_MSI)) {
919 919 /*
920 920 * Try MSI first, but fall back to FIXED if failed
921 921 */
922 922 if (ahci_add_intrs(ahci_ctlp, DDI_INTR_TYPE_MSI) ==
923 923 DDI_SUCCESS) {
924 924 ahci_ctlp->ahcictl_intr_type = DDI_INTR_TYPE_MSI;
925 925 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
926 926 "Using MSI interrupt type", NULL);
927 927 goto intr_done;
928 928 }
929 929
930 930 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
931 931 "MSI registration failed, "
932 932 "trying FIXED interrupts", NULL);
933 933 }
934 934
935 935 if (intr_types & DDI_INTR_TYPE_FIXED) {
936 936 if (ahci_add_intrs(ahci_ctlp, DDI_INTR_TYPE_FIXED) ==
937 937 DDI_SUCCESS) {
938 938 ahci_ctlp->ahcictl_intr_type = DDI_INTR_TYPE_FIXED;
939 939 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
940 940 "Using FIXED interrupt type", NULL);
941 941 goto intr_done;
942 942 }
943 943
944 944 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
945 945 "FIXED interrupt registration failed", NULL);
946 946 }
947 947
948 948 cmn_err(CE_WARN, "!ahci%d: Interrupt registration failed", instance);
949 949
950 950 goto err_out;
951 951
952 952 intr_done:
953 953
954 954 attach_state |= AHCI_ATTACH_STATE_INTR_ADDED;
955 955
956 956 /* Initialize the controller mutex */
957 957 mutex_init(&ahci_ctlp->ahcictl_mutex, NULL, MUTEX_DRIVER,
958 958 (void *)(uintptr_t)ahci_ctlp->ahcictl_intr_pri);
959 959
960 960 attach_state |= AHCI_ATTACH_STATE_MUTEX_INIT;
961 961
962 962 if (ahci_dma_prdt_number < AHCI_MIN_PRDT_NUMBER) {
963 963 ahci_dma_prdt_number = AHCI_MIN_PRDT_NUMBER;
964 964 } else if (ahci_dma_prdt_number > AHCI_MAX_PRDT_NUMBER) {
965 965 ahci_dma_prdt_number = AHCI_MAX_PRDT_NUMBER;
966 966 }
967 967
968 968 ahci_cmd_table_size = (sizeof (ahci_cmd_table_t) +
969 969 (ahci_dma_prdt_number - AHCI_PRDT_NUMBER) *
970 970 sizeof (ahci_prdt_item_t));
971 971
972 972 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
973 973 "ahci_attach: ahci_dma_prdt_number set by user is 0x%x,"
974 974 " ahci_cmd_table_size is 0x%x",
975 975 ahci_dma_prdt_number, ahci_cmd_table_size);
976 976
977 977 if (ahci_dma_prdt_number != AHCI_PRDT_NUMBER)
978 978 ahci_ctlp->ahcictl_buffer_dma_attr.dma_attr_sgllen =
979 979 ahci_dma_prdt_number;
980 980
981 981 ahci_ctlp->ahcictl_buffer_dma_attr = buffer_dma_attr;
982 982 ahci_ctlp->ahcictl_rcvd_fis_dma_attr = rcvd_fis_dma_attr;
983 983 ahci_ctlp->ahcictl_cmd_list_dma_attr = cmd_list_dma_attr;
984 984 ahci_ctlp->ahcictl_cmd_table_dma_attr = cmd_table_dma_attr;
985 985
986 986 /*
987 987 * enable 64bit dma for data buffer for SB600 if
988 988 * sb600_buf_64bit_dma_disable is B_FALSE
989 989 */
990 990 if ((ahci_buf_64bit_dma == B_FALSE) ||
991 991 ((ahci_ctlp->ahcictl_cap & AHCI_CAP_BUF_32BIT_DMA) &&
992 992 !(sb600_buf_64bit_dma_disable == B_FALSE &&
993 993 ahci_ctlp->ahcictl_venid == 0x1002 &&
994 994 ahci_ctlp->ahcictl_devid == 0x4380))) {
995 995 ahci_ctlp->ahcictl_buffer_dma_attr.dma_attr_addr_hi =
996 996 0xffffffffull;
997 997 }
998 998
999 999 /*
1000 1000 * enable 64bit dma for command buffer for SB600/700/710/800
1001 1001 * if sbxxx_commu_64bit_dma_disable is B_FALSE
1002 1002 */
1003 1003 if ((ahci_commu_64bit_dma == B_FALSE) ||
1004 1004 ((ahci_ctlp->ahcictl_cap & AHCI_CAP_COMMU_32BIT_DMA) &&
1005 1005 !(sbxxx_commu_64bit_dma_disable == B_FALSE &&
1006 1006 ahci_ctlp->ahcictl_venid == 0x1002 &&
1007 1007 (ahci_ctlp->ahcictl_devid == 0x4380 ||
1008 1008 ahci_ctlp->ahcictl_devid == 0x4391)))) {
1009 1009 ahci_ctlp->ahcictl_rcvd_fis_dma_attr.dma_attr_addr_hi =
1010 1010 0xffffffffull;
1011 1011 ahci_ctlp->ahcictl_cmd_list_dma_attr.dma_attr_addr_hi =
1012 1012 0xffffffffull;
1013 1013 ahci_ctlp->ahcictl_cmd_table_dma_attr.dma_attr_addr_hi =
1014 1014 0xffffffffull;
1015 1015 }
1016 1016
1017 1017 /* Allocate the ports structure */
1018 1018 status = ahci_alloc_ports_state(ahci_ctlp);
1019 1019 if (status != AHCI_SUCCESS) {
1020 1020 cmn_err(CE_WARN, "!ahci%d: Cannot allocate ports structure",
1021 1021 instance);
1022 1022 goto err_out;
1023 1023 }
1024 1024
1025 1025 attach_state |= AHCI_ATTACH_STATE_PORT_ALLOC;
1026 1026
1027 1027 /*
1028 1028 * Initialize the controller and ports.
1029 1029 */
1030 1030 status = ahci_initialize_controller(ahci_ctlp);
1031 1031 if (status != AHCI_SUCCESS) {
1032 1032 cmn_err(CE_WARN, "!ahci%d: HBA initialization failed",
1033 1033 instance);
1034 1034 goto err_out;
1035 1035 }
1036 1036
1037 1037 attach_state |= AHCI_ATTACH_STATE_HW_INIT;
1038 1038
1039 1039 /* Start one thread to check packet timeouts */
1040 1040 ahci_ctlp->ahcictl_timeout_id = timeout(
1041 1041 (void (*)(void *))ahci_watchdog_handler,
1042 1042 (caddr_t)ahci_ctlp, ahci_watchdog_tick);
1043 1043
1044 1044 attach_state |= AHCI_ATTACH_STATE_TIMEOUT_ENABLED;
1045 1045
1046 1046 if (!ahci_em_init(ahci_ctlp)) {
1047 1047 cmn_err(CE_WARN, "!ahci%d: failed to initialize enclosure "
1048 1048 "services", instance);
1049 1049 goto err_out;
1050 1050 }
1051 1051 attach_state |= AHCI_ATTACH_STATE_ENCLOSURE;
1052 1052
1053 1053 if (ahci_register_sata_hba_tran(ahci_ctlp, cap_status)) {
1054 1054 cmn_err(CE_WARN, "!ahci%d: sata hba tran registration failed",
1055 1055 instance);
1056 1056 goto err_out;
1057 1057 }
1058 1058
1059 1059 /* Check all handles at the end of the attach operation. */
1060 1060 if (ahci_check_all_handle(ahci_ctlp) != DDI_SUCCESS) {
1061 1061 cmn_err(CE_WARN, "!ahci%d: invalid dma/acc handles",
1062 1062 instance);
1063 1063 goto err_out;
1064 1064 }
1065 1065
1066 1066 ahci_ctlp->ahcictl_flags &= ~AHCI_ATTACH;
1067 1067
1068 1068 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "ahci_attach success!", NULL);
1069 1069
1070 1070 return (DDI_SUCCESS);
1071 1071
1072 1072 err_out:
1073 1073 /* FMA message */
1074 1074 ahci_fm_ereport(ahci_ctlp, DDI_FM_DEVICE_NO_RESPONSE);
1075 1075 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip, DDI_SERVICE_LOST);
1076 1076
1077 1077 if (attach_state & AHCI_ATTACH_STATE_ENCLOSURE) {
1078 1078 ahci_em_fini(ahci_ctlp);
1079 1079 }
1080 1080
1081 1081 if (attach_state & AHCI_ATTACH_STATE_TIMEOUT_ENABLED) {
1082 1082 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1083 1083 (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1084 1084 ahci_ctlp->ahcictl_timeout_id = 0;
1085 1085 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1086 1086 }
1087 1087
1088 1088 if (attach_state & AHCI_ATTACH_STATE_HW_INIT) {
1089 1089 ahci_uninitialize_controller(ahci_ctlp);
1090 1090 }
1091 1091
1092 1092 if (attach_state & AHCI_ATTACH_STATE_PORT_ALLOC) {
1093 1093 ahci_dealloc_ports_state(ahci_ctlp);
1094 1094 }
1095 1095
1096 1096 if (attach_state & AHCI_ATTACH_STATE_MUTEX_INIT) {
1097 1097 mutex_destroy(&ahci_ctlp->ahcictl_mutex);
1098 1098 }
1099 1099
1100 1100 if (attach_state & AHCI_ATTACH_STATE_INTR_ADDED) {
1101 1101 ahci_rem_intrs(ahci_ctlp);
1102 1102 }
1103 1103
1104 1104 if (attach_state & AHCI_ATTACH_STATE_PCICFG_SETUP) {
1105 1105 pci_config_teardown(&ahci_ctlp->ahcictl_pci_conf_handle);
1106 1106 }
1107 1107
1108 1108 if (attach_state & AHCI_ATTACH_STATE_REG_MAP) {
1109 1109 ddi_regs_map_free(&ahci_ctlp->ahcictl_ahci_acc_handle);
1110 1110 }
1111 1111
1112 1112 if (attach_state & AHCI_ATTACH_STATE_FMA) {
1113 1113 ahci_fm_fini(ahci_ctlp);
1114 1114 }
1115 1115
1116 1116 if (attach_state & AHCI_ATTACH_STATE_STATEP_ALLOC) {
1117 1117 ddi_soft_state_free(ahci_statep, instance);
1118 1118 }
1119 1119
1120 1120 return (DDI_FAILURE);
1121 1121 }
1122 1122
1123 1123 /*
1124 1124 * The detach entry point for dev_ops.
1125 1125 */
1126 1126 static int
1127 1127 ahci_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1128 1128 {
1129 1129 ahci_ctl_t *ahci_ctlp;
1130 1130 int instance;
1131 1131 int ret;
1132 1132
1133 1133 instance = ddi_get_instance(dip);
1134 1134 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
1135 1135
1136 1136 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_detach enter", NULL);
1137 1137
1138 1138 switch (cmd) {
1139 1139 case DDI_DETACH:
1140 1140
1141 1141 /* disable the interrupts for an uninterrupted detach */
1142 1142 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1143 1143 ahci_disable_all_intrs(ahci_ctlp);
1144 1144 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1145 1145
1146 1146 /* unregister from the sata framework. */
1147 1147 ret = ahci_unregister_sata_hba_tran(ahci_ctlp);
1148 1148 if (ret != AHCI_SUCCESS) {
1149 1149 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1150 1150 ahci_enable_all_intrs(ahci_ctlp);
1151 1151 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1152 1152 return (DDI_FAILURE);
1153 1153 }
1154 1154
1155 1155 ahci_em_fini(ahci_ctlp);
1156 1156
1157 1157 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1158 1158
1159 1159 /* stop the watchdog handler */
1160 1160 (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1161 1161 ahci_ctlp->ahcictl_timeout_id = 0;
1162 1162
1163 1163 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1164 1164
1165 1165 /* uninitialize the controller */
1166 1166 ahci_uninitialize_controller(ahci_ctlp);
1167 1167
1168 1168 /* remove the interrupts */
1169 1169 ahci_rem_intrs(ahci_ctlp);
1170 1170
1171 1171 /* deallocate the ports structures */
1172 1172 ahci_dealloc_ports_state(ahci_ctlp);
1173 1173
1174 1174 /* destroy mutex */
1175 1175 mutex_destroy(&ahci_ctlp->ahcictl_mutex);
1176 1176
1177 1177 /* teardown the pci config */
1178 1178 pci_config_teardown(&ahci_ctlp->ahcictl_pci_conf_handle);
1179 1179
1180 1180 /* remove the reg maps. */
1181 1181 ddi_regs_map_free(&ahci_ctlp->ahcictl_ahci_acc_handle);
1182 1182
1183 1183 /* release fma resource */
1184 1184 ahci_fm_fini(ahci_ctlp);
1185 1185
1186 1186 /* free the soft state. */
1187 1187 ddi_soft_state_free(ahci_statep, instance);
1188 1188
1189 1189 return (DDI_SUCCESS);
1190 1190
1191 1191 case DDI_SUSPEND:
1192 1192
1193 1193 /*
1194 1194 * The steps associated with suspension must include putting
1195 1195 * the underlying device into a quiescent state so that it
1196 1196 * will not generate interrupts or modify or access memory.
1197 1197 */
1198 1198 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1199 1199 if (ahci_ctlp->ahcictl_flags & AHCI_SUSPEND) {
1200 1200 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1201 1201 return (DDI_SUCCESS);
1202 1202 }
1203 1203
1204 1204 ahci_ctlp->ahcictl_flags |= AHCI_SUSPEND;
1205 1205
1206 1206 ahci_em_suspend(ahci_ctlp);
1207 1207
1208 1208 /* stop the watchdog handler */
1209 1209 if (ahci_ctlp->ahcictl_timeout_id) {
1210 1210 (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1211 1211 ahci_ctlp->ahcictl_timeout_id = 0;
1212 1212 }
1213 1213
1214 1214 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1215 1215
1216 1216 /*
1217 1217 * drain the taskq
1218 1218 */
1219 1219 ahci_drain_ports_taskq(ahci_ctlp);
1220 1220
1221 1221 /*
1222 1222 * Disable the interrupts and stop all the ports.
1223 1223 */
1224 1224 ahci_uninitialize_controller(ahci_ctlp);
1225 1225
1226 1226 return (DDI_SUCCESS);
1227 1227
1228 1228 default:
1229 1229 return (DDI_FAILURE);
1230 1230 }
1231 1231 }
1232 1232
1233 1233 /*
1234 1234 * The info entry point for dev_ops.
1235 1235 *
1236 1236 */
1237 1237 static int
1238 1238 ahci_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd,
1239 1239 void *arg, void **result)
1240 1240 {
1241 1241 #ifndef __lock_lint
1242 1242 _NOTE(ARGUNUSED(dip))
1243 1243 #endif /* __lock_lint */
1244 1244
1245 1245 ahci_ctl_t *ahci_ctlp;
1246 1246 int instance;
1247 1247 dev_t dev;
1248 1248
1249 1249 dev = (dev_t)arg;
1250 1250 instance = getminor(dev);
1251 1251
1252 1252 switch (infocmd) {
1253 1253 case DDI_INFO_DEVT2DEVINFO:
1254 1254 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
1255 1255 if (ahci_ctlp != NULL) {
1256 1256 *result = ahci_ctlp->ahcictl_dip;
1257 1257 return (DDI_SUCCESS);
1258 1258 } else {
1259 1259 *result = NULL;
1260 1260 return (DDI_FAILURE);
1261 1261 }
1262 1262 case DDI_INFO_DEVT2INSTANCE:
1263 1263 *(int *)result = instance;
1264 1264 break;
1265 1265 default:
1266 1266 break;
1267 1267 }
1268 1268
1269 1269 return (DDI_SUCCESS);
1270 1270 }
1271 1271
1272 1272 /*
1273 1273 * Registers the ahci with sata framework.
1274 1274 */
1275 1275 static int
1276 1276 ahci_register_sata_hba_tran(ahci_ctl_t *ahci_ctlp, uint32_t cap_status)
1277 1277 {
1278 1278 struct sata_hba_tran *sata_hba_tran;
1279 1279
1280 1280 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
1281 1281 "ahci_register_sata_hba_tran enter", NULL);
1282 1282
1283 1283 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1284 1284
1285 1285 /* Allocate memory for the sata_hba_tran */
1286 1286 sata_hba_tran = kmem_zalloc(sizeof (sata_hba_tran_t), KM_SLEEP);
1287 1287
1288 1288 sata_hba_tran->sata_tran_hba_rev = SATA_TRAN_HBA_REV;
1289 1289 sata_hba_tran->sata_tran_hba_dip = ahci_ctlp->ahcictl_dip;
1290 1290 sata_hba_tran->sata_tran_hba_dma_attr =
1291 1291 &ahci_ctlp->ahcictl_buffer_dma_attr;
1292 1292
1293 1293 /* Report the number of implemented ports */
1294 1294 sata_hba_tran->sata_tran_hba_num_cports =
1295 1295 ahci_ctlp->ahcictl_num_implemented_ports;
1296 1296
1297 1297 /* Support ATAPI device */
1298 1298 sata_hba_tran->sata_tran_hba_features_support = SATA_CTLF_ATAPI;
1299 1299
1300 1300 /* Get the data transfer capability for PIO command by the HBA */
1301 1301 if (cap_status & AHCI_HBA_CAP_PMD) {
1302 1302 ahci_ctlp->ahcictl_cap |= AHCI_CAP_PIO_MDRQ;
1303 1303 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "HBA supports multiple "
1304 1304 "DRQ block data transfer for PIO command protocol", NULL);
1305 1305 }
1306 1306
1307 1307 /*
1308 1308 * According to the AHCI spec, the ATA/ATAPI-7 queued feature set
1309 1309 * is not supported by AHCI (including the READ QUEUED (EXT), WRITE
1310 1310 * QUEUED (EXT), and SERVICE commands). Queued operations are
1311 1311 * supported in AHCI using the READ FPDMA QUEUED and WRITE FPDMA
1312 1312 * QUEUED commands when the HBA and device support native command
1313 1313 * queuing(NCQ).
1314 1314 *
1315 1315 * SATA_CTLF_NCQ will be set to sata_tran_hba_features_support if the
1316 1316 * CAP register of the HBA indicates NCQ is supported.
1317 1317 *
1318 1318 * SATA_CTLF_NCQ cannot be set if AHCI_CAP_NO_MCMDLIST_NONQUEUE is
1319 1319 * set because the previous register content of PxCI can be re-written
1320 1320 * in the register write.
1321 1321 */
1322 1322 if ((cap_status & AHCI_HBA_CAP_SNCQ) &&
1323 1323 !(ahci_ctlp->ahcictl_cap & AHCI_CAP_NO_MCMDLIST_NONQUEUE)) {
1324 1324 sata_hba_tran->sata_tran_hba_features_support |= SATA_CTLF_NCQ;
1325 1325 ahci_ctlp->ahcictl_cap |= AHCI_CAP_NCQ;
1326 1326 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "HBA supports Native "
1327 1327 "Command Queuing", NULL);
1328 1328 }
1329 1329
1330 1330 /* Support port multiplier? */
1331 1331 if (cap_status & AHCI_HBA_CAP_SPM) {
1332 1332 sata_hba_tran->sata_tran_hba_features_support |=
1333 1333 SATA_CTLF_PORT_MULTIPLIER;
1334 1334
1335 1335 /* Support FIS-based switching for port multiplier? */
1336 1336 if (cap_status & AHCI_HBA_CAP_FBSS) {
1337 1337 sata_hba_tran->sata_tran_hba_features_support |=
1338 1338 SATA_CTLF_PMULT_FBS;
1339 1339 }
1340 1340 }
1341 1341
1342 1342 /* Report the number of command slots */
1343 1343 sata_hba_tran->sata_tran_hba_qdepth = ahci_ctlp->ahcictl_num_cmd_slots;
1344 1344
1345 1345 sata_hba_tran->sata_tran_probe_port = ahci_tran_probe_port;
1346 1346 sata_hba_tran->sata_tran_start = ahci_tran_start;
1347 1347 sata_hba_tran->sata_tran_abort = ahci_tran_abort;
1348 1348 sata_hba_tran->sata_tran_reset_dport = ahci_tran_reset_dport;
1349 1349 sata_hba_tran->sata_tran_hotplug_ops = &ahci_tran_hotplug_ops;
1350 1350 #ifdef __lock_lint
1351 1351 sata_hba_tran->sata_tran_selftest = ahci_selftest;
1352 1352 #endif
1353 1353 /*
1354 1354 * When SATA framework adds support for pwrmgt the
1355 1355 * pwrmgt_ops needs to be updated
1356 1356 */
1357 1357 sata_hba_tran->sata_tran_pwrmgt_ops = NULL;
1358 1358 sata_hba_tran->sata_tran_ioctl = ahci_em_ioctl;
1359 1359
1360 1360 ahci_ctlp->ahcictl_sata_hba_tran = sata_hba_tran;
1361 1361
1362 1362 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1363 1363
1364 1364 /* Attach it to SATA framework */
1365 1365 if (sata_hba_attach(ahci_ctlp->ahcictl_dip, sata_hba_tran, DDI_ATTACH)
1366 1366 != DDI_SUCCESS) {
1367 1367 kmem_free((void *)sata_hba_tran, sizeof (sata_hba_tran_t));
1368 1368 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1369 1369 ahci_ctlp->ahcictl_sata_hba_tran = NULL;
1370 1370 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1371 1371 return (AHCI_FAILURE);
1372 1372 }
1373 1373
1374 1374 return (AHCI_SUCCESS);
1375 1375 }
1376 1376
1377 1377 /*
1378 1378 * Unregisters the ahci with sata framework.
1379 1379 */
1380 1380 static int
1381 1381 ahci_unregister_sata_hba_tran(ahci_ctl_t *ahci_ctlp)
1382 1382 {
1383 1383 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
1384 1384 "ahci_unregister_sata_hba_tran enter", NULL);
1385 1385
1386 1386 /* Detach from the SATA framework. */
1387 1387 if (sata_hba_detach(ahci_ctlp->ahcictl_dip, DDI_DETACH) !=
1388 1388 DDI_SUCCESS) {
1389 1389 return (AHCI_FAILURE);
1390 1390 }
1391 1391
1392 1392 /* Deallocate sata_hba_tran. */
1393 1393 kmem_free((void *)ahci_ctlp->ahcictl_sata_hba_tran,
1394 1394 sizeof (sata_hba_tran_t));
1395 1395
1396 1396 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1397 1397 ahci_ctlp->ahcictl_sata_hba_tran = NULL;
1398 1398 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1399 1399
1400 1400 return (AHCI_SUCCESS);
1401 1401 }
1402 1402
1403 1403 #define SET_PORTSTR(str, addrp) \
1404 1404 if (AHCI_ADDR_IS_PORT(addrp)) \
1405 1405 (void) sprintf((str), "%d", (addrp)->aa_port); \
1406 1406 else if (AHCI_ADDR_IS_PMULT(addrp)) \
1407 1407 (void) sprintf((str), "%d (pmult)", (addrp)->aa_port); \
1408 1408 else \
1409 1409 (void) sprintf((str), "%d:%d", (addrp)->aa_port, \
1410 1410 (addrp)->aa_pmport);
1411 1411
1412 1412 /*
1413 1413 * ahci_tran_probe_port is called by SATA framework. It returns port state,
1414 1414 * port status registers and an attached device type via sata_device
1415 1415 * structure.
1416 1416 *
1417 1417 * We return the cached information from a previous hardware probe. The
1418 1418 * actual hardware probing itself was done either from within
1419 1419 * ahci_initialize_controller() during the driver attach or from a phy
1420 1420 * ready change interrupt handler.
1421 1421 */
1422 1422 static int
1423 1423 ahci_tran_probe_port(dev_info_t *dip, sata_device_t *sd)
1424 1424 {
1425 1425 ahci_ctl_t *ahci_ctlp;
1426 1426 ahci_port_t *ahci_portp;
1427 1427 ahci_addr_t addr, pmult_addr;
1428 1428 uint8_t cport = sd->satadev_addr.cport;
1429 1429 char portstr[10];
1430 1430 uint8_t device_type;
1431 1431 uint32_t port_state;
1432 1432 uint8_t port;
1433 1433 int rval = SATA_SUCCESS, rval_init;
1434 1434
1435 1435 ahci_ctlp = ddi_get_soft_state(ahci_statep, ddi_get_instance(dip));
1436 1436 port = ahci_ctlp->ahcictl_cport_to_port[cport];
1437 1437
1438 1438 ahci_portp = ahci_ctlp->ahcictl_ports[port];
1439 1439
1440 1440 mutex_enter(&ahci_portp->ahciport_mutex);
1441 1441
1442 1442 ahci_get_ahci_addr(ahci_ctlp, sd, &addr);
1443 1443 ASSERT(AHCI_ADDR_IS_VALID(&addr));
1444 1444 SET_PORTSTR(portstr, &addr);
1445 1445
1446 1446 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
1447 1447 "ahci_tran_probe_port enter: port %s", portstr);
1448 1448
1449 1449 if ((AHCI_ADDR_IS_PMULT(&addr) || AHCI_ADDR_IS_PMPORT(&addr)) &&
1450 1450 (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT ||
1451 1451 ahci_portp->ahciport_pmult_info == NULL)) {
1452 1452 /* port mutliplier is removed. */
1453 1453 AHCIDBG(AHCIDBG_PMULT, ahci_ctlp,
1454 1454 "ahci_tran_probe_port: "
1455 1455 "pmult is removed from port %s", portstr);
1456 1456 mutex_exit(&ahci_portp->ahciport_mutex);
1457 1457 return (SATA_FAILURE);
1458 1458 }
1459 1459
1460 1460 /*
1461 1461 * The sata_device may refer to
1462 1462 * 1. A controller port.
1463 1463 * A controller port should be ready here.
1464 1464 * 2. A port multiplier.
1465 1465 * SATA_ADDR_PMULT_SPEC - if it is not initialized yet, initialize
1466 1466 * it and register the port multiplier to the framework.
1467 1467 * SATA_ADDR_PMULT - check the status of all its device ports.
1468 1468 * 3. A port multiplier port.
1469 1469 * If it has not been initialized, initialized it.
1470 1470 *
1471 1471 * A port multiplier or a port multiplier port may require some
1472 1472 * initialization because we cannot do these time-consuming jobs in an
1473 1473 * interrupt context.
1474 1474 */
1475 1475 if (sd->satadev_addr.qual & SATA_ADDR_PMULT_SPEC) {
1476 1476 AHCI_ADDR_SET_PMULT(&pmult_addr, port);
1477 1477 /* Initialize registers on a port multiplier */
1478 1478 rval_init = ahci_initialize_pmult(ahci_ctlp,
1479 1479 ahci_portp, &pmult_addr, sd);
1480 1480 if (rval_init != AHCI_SUCCESS) {
1481 1481 AHCIDBG(AHCIDBG_PMULT, ahci_ctlp,
1482 1482 "ahci_tran_probe_port: "
1483 1483 "pmult initialization failed.", NULL);
1484 1484 mutex_exit(&ahci_portp->ahciport_mutex);
1485 1485 return (SATA_FAILURE);
1486 1486 }
1487 1487 } else if (sd->satadev_addr.qual & SATA_ADDR_PMULT) {
1488 1488 /* Check pmports hotplug events */
1489 1489 (void) ahci_probe_pmult(ahci_ctlp, ahci_portp, &addr);
1490 1490 } else if (sd->satadev_addr.qual & (SATA_ADDR_PMPORT |
1491 1491 SATA_ADDR_DPMPORT)) {
1492 1492 if (ahci_probe_pmport(ahci_ctlp, ahci_portp,
1493 1493 &addr, sd) != AHCI_SUCCESS) {
1494 1494 rval = SATA_FAILURE;
1495 1495 goto out;
1496 1496 }
1497 1497 }
1498 1498
1499 1499 /* Update port state and device type */
1500 1500 port_state = AHCIPORT_GET_STATE(ahci_portp, &addr);
1501 1501
1502 1502 switch (port_state) {
1503 1503
1504 1504 case SATA_PSTATE_FAILED:
1505 1505 sd->satadev_state = SATA_PSTATE_FAILED;
1506 1506 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1507 1507 "ahci_tran_probe_port: port %s PORT FAILED", portstr);
1508 1508 goto out;
1509 1509
1510 1510 case SATA_PSTATE_SHUTDOWN:
1511 1511 sd->satadev_state = SATA_PSTATE_SHUTDOWN;
1512 1512 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1513 1513 "ahci_tran_probe_port: port %s PORT SHUTDOWN", portstr);
1514 1514 goto out;
1515 1515
1516 1516 case SATA_PSTATE_PWROFF:
1517 1517 sd->satadev_state = SATA_PSTATE_PWROFF;
1518 1518 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1519 1519 "ahci_tran_probe_port: port %s PORT PWROFF", portstr);
1520 1520 goto out;
1521 1521
1522 1522 case SATA_PSTATE_PWRON:
1523 1523 sd->satadev_state = SATA_PSTATE_PWRON;
1524 1524 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1525 1525 "ahci_tran_probe_port: port %s PORT PWRON", portstr);
1526 1526 break;
1527 1527
1528 1528 default:
1529 1529 sd->satadev_state = port_state;
1530 1530 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1531 1531 "ahci_tran_probe_port: port %s PORT NORMAL %x",
1532 1532 portstr, port_state);
1533 1533 break;
1534 1534 }
1535 1535
1536 1536 device_type = AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr);
1537 1537
1538 1538 switch (device_type) {
1539 1539
1540 1540 case SATA_DTYPE_ATADISK:
1541 1541 sd->satadev_type = SATA_DTYPE_ATADISK;
1542 1542 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1543 1543 "ahci_tran_probe_port: port %s DISK found", portstr);
1544 1544 break;
1545 1545
1546 1546 case SATA_DTYPE_ATAPI:
1547 1547 /*
1548 1548 * HBA driver only knows it's an ATAPI device, and don't know
1549 1549 * it's CD/DVD, tape or ATAPI disk because the ATAPI device
1550 1550 * type need to be determined by checking IDENTIFY PACKET
1551 1551 * DEVICE data
1552 1552 */
1553 1553 sd->satadev_type = SATA_DTYPE_ATAPI;
1554 1554 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1555 1555 "ahci_tran_probe_port: port %s ATAPI found", portstr);
1556 1556 break;
1557 1557
1558 1558 case SATA_DTYPE_PMULT:
1559 1559 ASSERT(AHCI_ADDR_IS_PORT(&addr) || AHCI_ADDR_IS_PMULT(&addr));
1560 1560 sd->satadev_type = SATA_DTYPE_PMULT;
1561 1561
1562 1562 /* Update the number of pmports. */
1563 1563 ASSERT(ahci_portp->ahciport_pmult_info != NULL);
1564 1564 sd->satadev_add_info = ahci_portp->
1565 1565 ahciport_pmult_info->ahcipmi_num_dev_ports;
1566 1566
1567 1567 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1568 1568 "ahci_tran_probe_port: port %s Port Multiplier found",
1569 1569 portstr);
1570 1570 break;
1571 1571
1572 1572 case SATA_DTYPE_UNKNOWN:
1573 1573 sd->satadev_type = SATA_DTYPE_UNKNOWN;
1574 1574 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1575 1575 "ahci_tran_probe_port: port %s Unknown device found",
1576 1576 portstr);
1577 1577 break;
1578 1578
1579 1579 default:
1580 1580 /* we don't support any other device types */
1581 1581 sd->satadev_type = SATA_DTYPE_NONE;
1582 1582 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1583 1583 "ahci_tran_probe_port: port %s No device found", portstr);
1584 1584 break;
1585 1585 }
1586 1586
1587 1587 out:
1588 1588 /* Register update only fails while probing a pmult/pmport */
1589 1589 if (AHCI_ADDR_IS_PORT(&addr) || AHCI_ADDR_IS_PMULT(&addr)) {
1590 1590 ahci_update_sata_registers(ahci_ctlp, port, sd);
1591 1591 } else if (AHCI_ADDR_IS_PMPORT(&addr)) {
1592 1592 if (port_state & SATA_STATE_READY)
1593 1593 if (ahci_update_pmult_pscr(ahci_ctlp,
1594 1594 &addr, sd) != AHCI_SUCCESS)
1595 1595 rval = SATA_FAILURE;
1596 1596 }
1597 1597
1598 1598 /* Check handles for the sata registers access */
1599 1599 if ((ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) ||
1600 1600 (ahci_check_port_handle(ahci_ctlp, port) != DDI_SUCCESS)) {
1601 1601 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
1602 1602 DDI_SERVICE_UNAFFECTED);
1603 1603 rval = SATA_FAILURE;
1604 1604 }
1605 1605
1606 1606 mutex_exit(&ahci_portp->ahciport_mutex);
1607 1607 return (rval);
1608 1608 }
1609 1609
1610 1610 /*
1611 1611 * There are four operation modes in sata framework:
1612 1612 * SATA_OPMODE_INTERRUPTS
1613 1613 * SATA_OPMODE_POLLING
1614 1614 * SATA_OPMODE_ASYNCH
1615 1615 * SATA_OPMODE_SYNCH
1616 1616 *
1617 1617 * Their combined meanings as following:
1618 1618 *
1619 1619 * SATA_OPMODE_SYNCH
1620 1620 * The command has to be completed before sata_tran_start functions returns.
1621 1621 * Either interrupts or polling could be used - it's up to the driver.
1622 1622 * Mode used currently for internal, sata-module initiated operations.
1623 1623 *
1624 1624 * SATA_OPMODE_SYNCH | SATA_OPMODE_INTERRUPTS
1625 1625 * It is the same as the one above.
1626 1626 *
1627 1627 * SATA_OPMODE_SYNCH | SATA_OPMODE_POLLING
1628 1628 * The command has to be completed before sata_tran_start function returns.
1629 1629 * No interrupt used, polling only. This should be the mode used for scsi
1630 1630 * packets with FLAG_NOINTR.
1631 1631 *
1632 1632 * SATA_OPMODE_ASYNCH | SATA_OPMODE_INTERRUPTS
1633 1633 * The command may be queued (callback function specified). Interrupts could
1634 1634 * be used. It's normal operation mode.
1635 1635 */
1636 1636 /*
1637 1637 * Called by sata framework to transport a sata packet down stream.
1638 1638 */
1639 1639 static int
1640 1640 ahci_tran_start(dev_info_t *dip, sata_pkt_t *spkt)
1641 1641 {
1642 1642 ahci_ctl_t *ahci_ctlp;
1643 1643 ahci_port_t *ahci_portp;
1644 1644 ahci_addr_t addr;
1645 1645 uint8_t cport = spkt->satapkt_device.satadev_addr.cport;
1646 1646 uint8_t port;
1647 1647 char portstr[10];
1648 1648
1649 1649 ahci_ctlp = ddi_get_soft_state(ahci_statep, ddi_get_instance(dip));
1650 1650 port = ahci_ctlp->ahcictl_cport_to_port[cport];
1651 1651
1652 1652 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
1653 1653 "ahci_tran_start enter: cport %d satapkt 0x%p",
1654 1654 cport, (void *)spkt);
1655 1655
1656 1656 ahci_portp = ahci_ctlp->ahcictl_ports[port];
1657 1657
1658 1658 mutex_enter(&ahci_portp->ahciport_mutex);
1659 1659 ahci_get_ahci_addr(ahci_ctlp, &spkt->satapkt_device, &addr);
1660 1660 SET_PORTSTR(portstr, &addr);
1661 1661
1662 1662 /* Sanity check */
1663 1663 if (AHCI_ADDR_IS_PMPORT(&addr)) {
1664 1664 if (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT ||
1665 1665 ahci_portp->ahciport_pmult_info == NULL) {
1666 1666
1667 1667 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1668 1668 spkt->satapkt_device.satadev_type = SATA_DTYPE_NONE;
1669 1669 spkt->satapkt_device.satadev_state = SATA_STATE_UNKNOWN;
1670 1670 ahci_update_sata_registers(ahci_ctlp, port,
1671 1671 &spkt->satapkt_device);
1672 1672 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1673 1673 "ahci_tran_start returning PORT_ERROR while "
1674 1674 "pmult removed: port: %s", portstr);
1675 1675 mutex_exit(&ahci_portp->ahciport_mutex);
1676 1676 return (SATA_TRAN_PORT_ERROR);
1677 1677 }
1678 1678
1679 1679 if (!(AHCIPORT_GET_STATE(ahci_portp, &addr) &
1680 1680 SATA_STATE_READY)) {
1681 1681 if (!ddi_in_panic() ||
1682 1682 ahci_initialize_pmport(ahci_ctlp,
1683 1683 ahci_portp, &addr) != AHCI_SUCCESS) {
1684 1684 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1685 1685 spkt->satapkt_device.satadev_type =
1686 1686 AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr);
1687 1687 spkt->satapkt_device.satadev_state =
1688 1688 AHCIPORT_GET_STATE(ahci_portp, &addr);
1689 1689 ahci_update_sata_registers(ahci_ctlp, port,
1690 1690 &spkt->satapkt_device);
1691 1691 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1692 1692 "ahci_tran_start returning PORT_ERROR "
1693 1693 "while sub-link is not initialized "
1694 1694 "at port: %s", portstr);
1695 1695 mutex_exit(&ahci_portp->ahciport_mutex);
1696 1696 return (SATA_TRAN_PORT_ERROR);
1697 1697 }
1698 1698 }
1699 1699 }
1700 1700
1701 1701 if (AHCIPORT_GET_STATE(ahci_portp, &addr) & SATA_PSTATE_FAILED ||
1702 1702 AHCIPORT_GET_STATE(ahci_portp, &addr) & SATA_PSTATE_SHUTDOWN||
1703 1703 AHCIPORT_GET_STATE(ahci_portp, &addr) & SATA_PSTATE_PWROFF) {
1704 1704 /*
1705 1705 * In case the target driver would send the packet before
1706 1706 * sata framework can have the opportunity to process those
1707 1707 * event reports.
1708 1708 */
1709 1709 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1710 1710 spkt->satapkt_device.satadev_state =
1711 1711 ahci_portp->ahciport_port_state;
1712 1712 ahci_update_sata_registers(ahci_ctlp, port,
1713 1713 &spkt->satapkt_device);
1714 1714 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1715 1715 "ahci_tran_start returning PORT_ERROR while "
1716 1716 "port in FAILED/SHUTDOWN/PWROFF state: "
1717 1717 "port: %s", portstr);
1718 1718 mutex_exit(&ahci_portp->ahciport_mutex);
1719 1719 return (SATA_TRAN_PORT_ERROR);
1720 1720 }
1721 1721
1722 1722 if (AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr) == SATA_DTYPE_NONE) {
1723 1723 /*
1724 1724 * ahci_intr_phyrdy_change() may have rendered it to
1725 1725 * SATA_DTYPE_NONE.
1726 1726 */
1727 1727 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1728 1728 spkt->satapkt_device.satadev_type = SATA_DTYPE_NONE;
1729 1729 spkt->satapkt_device.satadev_state =
1730 1730 ahci_portp->ahciport_port_state;
1731 1731 ahci_update_sata_registers(ahci_ctlp, port,
1732 1732 &spkt->satapkt_device);
1733 1733 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1734 1734 "ahci_tran_start returning PORT_ERROR while "
1735 1735 "no device attached: port: %s", portstr);
1736 1736 mutex_exit(&ahci_portp->ahciport_mutex);
1737 1737 return (SATA_TRAN_PORT_ERROR);
1738 1738 }
1739 1739
1740 1740 /* R/W PMULT command will occupy the whole HBA port */
1741 1741 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
1742 1742 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1743 1743 "ahci_tran_start returning BUSY while "
1744 1744 "executing READ/WRITE PORT-MULT command: "
1745 1745 "port: %s", portstr);
1746 1746 spkt->satapkt_reason = SATA_PKT_BUSY;
1747 1747 mutex_exit(&ahci_portp->ahciport_mutex);
1748 1748 return (SATA_TRAN_BUSY);
1749 1749 }
1750 1750
1751 1751 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_HOTPLUG) {
1752 1752 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1753 1753 "ahci_tran_start returning BUSY while "
1754 1754 "hot-plug in progress: port: %s", portstr);
1755 1755 spkt->satapkt_reason = SATA_PKT_BUSY;
1756 1756 mutex_exit(&ahci_portp->ahciport_mutex);
1757 1757 return (SATA_TRAN_BUSY);
1758 1758 }
1759 1759
1760 1760 /*
1761 1761 * SATA HBA driver should remember that a device was reset and it
1762 1762 * is supposed to reject any packets which do not specify either
1763 1763 * SATA_IGNORE_DEV_RESET_STATE or SATA_CLEAR_DEV_RESET_STATE.
1764 1764 *
1765 1765 * This is to prevent a race condition when a device was arbitrarily
1766 1766 * reset by the HBA driver (and lost it's setting) and a target
1767 1767 * driver sending some commands to a device before the sata framework
1768 1768 * has a chance to restore the device setting (such as cache enable/
1769 1769 * disable or other resettable stuff).
1770 1770 */
1771 1771 /*
1772 1772 * It is unnecessary to use specific flags to indicate
1773 1773 * reset_in_progress for a pmport. While mopping, all command will be
1774 1774 * mopped so that the entire HBA port is being dealt as a single
1775 1775 * object.
1776 1776 */
1777 1777 if (spkt->satapkt_cmd.satacmd_flags.sata_clear_dev_reset) {
1778 1778 ahci_portp->ahciport_reset_in_progress = 0;
1779 1779 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1780 1780 "ahci_tran_start [CLEAR] the "
1781 1781 "reset_in_progress for port: %d", port);
1782 1782 }
1783 1783
1784 1784 if (ahci_portp->ahciport_reset_in_progress &&
1785 1785 ! spkt->satapkt_cmd.satacmd_flags.sata_ignore_dev_reset &&
1786 1786 ! ddi_in_panic()) {
1787 1787 spkt->satapkt_reason = SATA_PKT_BUSY;
1788 1788 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1789 1789 "ahci_tran_start returning BUSY while "
1790 1790 "reset in progress: port: %d", port);
1791 1791 mutex_exit(&ahci_portp->ahciport_mutex);
1792 1792 return (SATA_TRAN_BUSY);
1793 1793 }
1794 1794
1795 1795 #ifdef AHCI_DEBUG
1796 1796 if (spkt->satapkt_cmd.satacmd_flags.sata_ignore_dev_reset) {
1797 1797 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1798 1798 "ahci_tran_start: packet 0x%p [PASSTHRU] at port %d",
1799 1799 spkt, port);
1800 1800 }
1801 1801 #endif
1802 1802
1803 1803 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
1804 1804 spkt->satapkt_reason = SATA_PKT_BUSY;
1805 1805 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1806 1806 "ahci_tran_start returning BUSY while "
1807 1807 "mopping in progress: port: %d", port);
1808 1808 mutex_exit(&ahci_portp->ahciport_mutex);
1809 1809 return (SATA_TRAN_BUSY);
1810 1810 }
1811 1811
1812 1812 if (ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) {
1813 1813 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
1814 1814 DDI_SERVICE_UNAFFECTED);
1815 1815 mutex_exit(&ahci_portp->ahciport_mutex);
1816 1816 return (SATA_TRAN_BUSY);
1817 1817 }
1818 1818
1819 1819 if (spkt->satapkt_op_mode &
1820 1820 (SATA_OPMODE_SYNCH | SATA_OPMODE_POLLING)) {
1821 1821 /*
1822 1822 * If a SYNC command to be executed in interrupt context,
1823 1823 * bounce it back to sata module.
1824 1824 */
1825 1825 if (!(spkt->satapkt_op_mode & SATA_OPMODE_POLLING) &&
1826 1826 servicing_interrupt()) {
1827 1827 spkt->satapkt_reason = SATA_PKT_BUSY;
1828 1828 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1829 1829 "ahci_tran_start returning BUSY while "
1830 1830 "sending SYNC mode under interrupt context: "
1831 1831 "port : %d", port);
1832 1832 mutex_exit(&ahci_portp->ahciport_mutex);
1833 1833 return (SATA_TRAN_BUSY);
1834 1834 }
1835 1835
1836 1836 /* We need to do the sync start now */
1837 1837 if (ahci_do_sync_start(ahci_ctlp, ahci_portp, &addr,
1838 1838 spkt) == AHCI_FAILURE) {
1839 1839 goto fail_out;
1840 1840 }
1841 1841 } else {
1842 1842 /* Async start, using interrupt */
1843 1843 if (ahci_deliver_satapkt(ahci_ctlp, ahci_portp, &addr, spkt)
1844 1844 == AHCI_FAILURE) {
1845 1845 spkt->satapkt_reason = SATA_PKT_QUEUE_FULL;
1846 1846 goto fail_out;
1847 1847 }
1848 1848 }
1849 1849
1850 1850 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "ahci_tran_start "
1851 1851 "sata tran accepted: port %s", portstr);
1852 1852
1853 1853 mutex_exit(&ahci_portp->ahciport_mutex);
1854 1854 return (SATA_TRAN_ACCEPTED);
1855 1855
1856 1856 fail_out:
1857 1857 /*
1858 1858 * Failed to deliver packet to the controller.
1859 1859 * Check if it's caused by invalid handles.
1860 1860 */
1861 1861 if (ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS ||
1862 1862 ahci_check_port_handle(ahci_ctlp, port) != DDI_SUCCESS) {
1863 1863 spkt->satapkt_device.satadev_type =
1864 1864 AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr);
1865 1865 spkt->satapkt_device.satadev_state =
1866 1866 AHCIPORT_GET_STATE(ahci_portp, &addr);
1867 1867 spkt->satapkt_reason = SATA_PKT_DEV_ERROR;
1868 1868 mutex_exit(&ahci_portp->ahciport_mutex);
1869 1869 return (SATA_TRAN_PORT_ERROR);
1870 1870 }
1871 1871
1872 1872 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_tran_start "
1873 1873 "return QUEUE_FULL: port %d", port);
1874 1874 mutex_exit(&ahci_portp->ahciport_mutex);
1875 1875 return (SATA_TRAN_QUEUE_FULL);
1876 1876 }
1877 1877
1878 1878 /*
1879 1879 * SATA_OPMODE_SYNCH flag is set
1880 1880 *
1881 1881 * If SATA_OPMODE_POLLING flag is set, then we must poll the command
1882 1882 * without interrupt, otherwise we can still use the interrupt.
1883 1883 */
1884 1884 static int
1885 1885 ahci_do_sync_start(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
1886 1886 ahci_addr_t *addrp, sata_pkt_t *spkt)
1887 1887 {
1888 1888 int pkt_timeout_ticks;
1889 1889 uint32_t timeout_tags;
1890 1890 int rval;
1891 1891 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
1892 1892 uint8_t port = addrp->aa_port;
1893 1893
1894 1894 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
1895 1895
1896 1896 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_do_sync_start enter: "
1897 1897 "port %d:%d spkt 0x%p", port, addrp->aa_pmport, spkt);
1898 1898
1899 1899 if (spkt->satapkt_op_mode & SATA_OPMODE_POLLING) {
1900 1900 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_POLLING;
1901 1901 if ((rval = ahci_deliver_satapkt(ahci_ctlp, ahci_portp,
1902 1902 addrp, spkt)) == AHCI_FAILURE) {
1903 1903 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_POLLING;
1904 1904 return (rval);
1905 1905 }
1906 1906
1907 1907 pkt_timeout_ticks =
1908 1908 drv_usectohz((clock_t)spkt->satapkt_time * 1000000);
1909 1909
1910 1910 while (spkt->satapkt_reason == SATA_PKT_BUSY) {
1911 1911 /* Simulate the interrupt */
1912 1912 mutex_exit(&ahci_portp->ahciport_mutex);
1913 1913 ahci_port_intr(ahci_ctlp, ahci_portp, port);
1914 1914 mutex_enter(&ahci_portp->ahciport_mutex);
1915 1915
1916 1916 if (spkt->satapkt_reason != SATA_PKT_BUSY)
1917 1917 break;
1918 1918
1919 1919 mutex_exit(&ahci_portp->ahciport_mutex);
1920 1920 drv_usecwait(AHCI_1MS_USECS);
1921 1921 mutex_enter(&ahci_portp->ahciport_mutex);
1922 1922
1923 1923 pkt_timeout_ticks -= AHCI_1MS_TICKS;
1924 1924 if (pkt_timeout_ticks < 0) {
1925 1925 cmn_err(CE_WARN, "!ahci%d: ahci_do_sync_start "
1926 1926 "port %d satapkt 0x%p timed out\n",
1927 1927 instance, port, (void *)spkt);
1928 1928 timeout_tags = (0x1 << rval);
1929 1929 mutex_exit(&ahci_portp->ahciport_mutex);
1930 1930 ahci_timeout_pkts(ahci_ctlp, ahci_portp,
1931 1931 port, timeout_tags);
1932 1932 mutex_enter(&ahci_portp->ahciport_mutex);
1933 1933 }
1934 1934 }
1935 1935
1936 1936 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_POLLING;
1937 1937 return (AHCI_SUCCESS);
1938 1938
1939 1939 } else {
1940 1940 if ((rval = ahci_deliver_satapkt(ahci_ctlp, ahci_portp,
1941 1941 addrp, spkt)) == AHCI_FAILURE)
1942 1942 return (rval);
1943 1943
1944 1944 #if AHCI_DEBUG
1945 1945 /*
1946 1946 * Note that the driver always uses the slot 0 to deliver
1947 1947 * REQUEST SENSE or READ LOG EXT command
1948 1948 */
1949 1949 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
1950 1950 ASSERT(rval == 0);
1951 1951 #endif
1952 1952
1953 1953 while (spkt->satapkt_reason == SATA_PKT_BUSY)
1954 1954 cv_wait(&ahci_portp->ahciport_cv,
1955 1955 &ahci_portp->ahciport_mutex);
1956 1956
1957 1957 return (AHCI_SUCCESS);
1958 1958 }
1959 1959 }
1960 1960
1961 1961 /*
1962 1962 * Searches for and claims a free command slot.
1963 1963 *
1964 1964 * Returns value:
1965 1965 *
1966 1966 * AHCI_FAILURE returned only if
1967 1967 * 1. No empty slot left
1968 1968 * 2. Non-queued command requested while queued command(s) is outstanding
1969 1969 * 3. Queued command requested while non-queued command(s) is outstanding
1970 1970 * 4. HBA doesn't support multiple-use of command list while already a
1971 1971 * non-queued command is oustanding
1972 1972 * 5. Queued command requested while some queued command(s) has been
1973 1973 * outstanding on a different port multiplier port. (AHCI spec 1.2,
1974 1974 * 9.1.2)
1975 1975 *
1976 1976 * claimed slot number returned if succeeded
1977 1977 *
1978 1978 * NOTE: it will always return slot 0 for following commands to simplify the
1979 1979 * algorithm.
1980 1980 * 1. REQUEST SENSE or READ LOG EXT command during error recovery process
1981 1981 * 2. READ/WRITE PORTMULT command
1982 1982 */
1983 1983 static int
1984 1984 ahci_claim_free_slot(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
1985 1985 ahci_addr_t *addrp, int command_type)
1986 1986 {
1987 1987 uint32_t port_cmd_issue;
1988 1988 uint32_t free_slots;
1989 1989 int slot;
1990 1990
1991 1991 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
1992 1992
1993 1993 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_claim_free_slot enter "
1994 1994 "ahciport_pending_tags = 0x%x "
1995 1995 "ahciport_pending_ncq_tags = 0x%x",
1996 1996 ahci_portp->ahciport_pending_tags,
1997 1997 ahci_portp->ahciport_pending_ncq_tags);
1998 1998
1999 1999 /*
2000 2000 * According to the AHCI spec, system software is responsible to
2001 2001 * ensure that queued and non-queued commands are not mixed in
2002 2002 * the command list.
2003 2003 */
2004 2004 if (command_type == AHCI_NON_NCQ_CMD) {
2005 2005 /* Non-NCQ command request */
2006 2006 if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2007 2007 AHCIDBG(AHCIDBG_INFO|AHCIDBG_NCQ, ahci_ctlp,
2008 2008 "ahci_claim_free_slot: there is still pending "
2009 2009 "queued command(s) in the command list, "
2010 2010 "so no available slot for the non-queued "
2011 2011 "command", NULL);
2012 2012 return (AHCI_FAILURE);
2013 2013 }
2014 2014 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
2015 2015 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
2016 2016 "ahci_claim_free_slot: there is still pending "
2017 2017 "read/write port-mult command(s) in command list, "
2018 2018 "so no available slot for the non-queued command",
2019 2019 NULL);
2020 2020 return (AHCI_FAILURE);
2021 2021 }
2022 2022 if ((ahci_ctlp->ahcictl_cap & AHCI_CAP_NO_MCMDLIST_NONQUEUE) &&
2023 2023 NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2024 2024 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2025 2025 "ahci_claim_free_slot: HBA cannot support multiple-"
2026 2026 "use of the command list for non-queued commands",
2027 2027 NULL);
2028 2028 return (AHCI_FAILURE);
2029 2029 }
2030 2030 free_slots = (~ahci_portp->ahciport_pending_tags) &
2031 2031 AHCI_SLOT_MASK(ahci_ctlp);
2032 2032 } else if (command_type == AHCI_NCQ_CMD) {
2033 2033 /* NCQ command request */
2034 2034 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2035 2035 AHCIDBG(AHCIDBG_INFO|AHCIDBG_NCQ, ahci_ctlp,
2036 2036 "ahci_claim_free_slot: there is still pending "
2037 2037 "non-queued command(s) in the command list, "
2038 2038 "so no available slot for the queued command",
2039 2039 NULL);
2040 2040 return (AHCI_FAILURE);
2041 2041 }
2042 2042
2043 2043 /*
2044 2044 * NCQ commands cannot be sent to different port multiplier
2045 2045 * ports in Command-Based Switching mode
2046 2046 */
2047 2047 /*
2048 2048 * NOTE: In Command-Based Switching mode, AHCI controller
2049 2049 * usually reports a 'Handshake Error' when multiple NCQ
2050 2050 * commands are outstanding simultaneously.
2051 2051 */
2052 2052 if (AHCIPORT_DEV_TYPE(ahci_portp, addrp) == SATA_DTYPE_PMULT) {
2053 2053 ASSERT(ahci_portp->ahciport_pmult_info != NULL);
2054 2054 if (!(ahci_ctlp->ahcictl_cap & AHCI_CAP_PMULT_FBSS) &&
2055 2055 NCQ_CMD_IN_PROGRESS(ahci_portp) &&
2056 2056 AHCIPORT_NCQ_PMPORT(ahci_portp) !=
2057 2057 addrp->aa_pmport) {
2058 2058 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2059 2059 "ahci_claim_free_slot: there is still "
2060 2060 "pending queued command(s) in the "
2061 2061 "command list for another Port Multiplier "
2062 2062 "port, so no available slot.", NULL);
2063 2063 return (AHCI_FAILURE);
2064 2064 }
2065 2065 }
2066 2066
2067 2067 free_slots = (~ahci_portp->ahciport_pending_ncq_tags) &
2068 2068 AHCI_NCQ_SLOT_MASK(ahci_portp);
2069 2069 } else if (command_type == AHCI_ERR_RETRI_CMD) {
2070 2070 /* Error retrieval command request */
2071 2071 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2072 2072 "ahci_claim_free_slot: slot 0 is allocated for REQUEST "
2073 2073 "SENSE or READ LOG EXT command", NULL);
2074 2074 slot = 0;
2075 2075 goto out;
2076 2076 } else if (command_type == AHCI_RDWR_PMULT_CMD) {
2077 2077 /*
2078 2078 * An extra check on PxCI. Sometimes PxCI bits may not be
2079 2079 * cleared during hot-plug or error recovery process.
2080 2080 */
2081 2081 port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2082 2082 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, addrp->aa_port));
2083 2083
2084 2084 if (port_cmd_issue != 0) {
2085 2085 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
2086 2086 "ahci_claim_free_slot: there is still pending "
2087 2087 "command(s) in command list (0x%x/0x%x, PxCI %x),"
2088 2088 "so no available slot for R/W PMULT command.",
2089 2089 NON_NCQ_CMD_IN_PROGRESS(ahci_portp),
2090 2090 NCQ_CMD_IN_PROGRESS(ahci_portp),
2091 2091 port_cmd_issue);
2092 2092 return (AHCI_FAILURE);
2093 2093 }
2094 2094
2095 2095 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2096 2096 "ahci_claim_free_slot: slot 0 is allocated for "
2097 2097 "READ/WRITE PORTMULT command", NULL);
2098 2098 slot = 0;
2099 2099 goto out;
2100 2100 }
2101 2101
2102 2102 slot = ddi_ffs(free_slots) - 1;
2103 2103 if (slot == -1) {
2104 2104 AHCIDBG(AHCIDBG_VERBOSE, ahci_ctlp,
2105 2105 "ahci_claim_free_slot: no empty slots", NULL);
2106 2106 return (AHCI_FAILURE);
2107 2107 }
2108 2108
2109 2109 /*
2110 2110 * According to the AHCI spec, to allow a simple mechanism for the
2111 2111 * HBA to map command list slots to queue entries, software must
2112 2112 * match the tag number it uses to the slot it is placing the command
2113 2113 * in. For example, if a queued command is placed in slot 5, the tag
2114 2114 * for that command must be 5.
2115 2115 */
2116 2116 if (command_type == AHCI_NCQ_CMD) {
2117 2117 ahci_portp->ahciport_pending_ncq_tags |= (0x1 << slot);
2118 2118 if (AHCI_ADDR_IS_PMPORT(addrp)) {
2119 2119 ASSERT(ahci_portp->ahciport_pmult_info != NULL);
2120 2120 AHCIPORT_NCQ_PMPORT(ahci_portp) = addrp->aa_pmport;
2121 2121 }
2122 2122 }
2123 2123
2124 2124 ahci_portp->ahciport_pending_tags |= (0x1 << slot);
2125 2125
2126 2126 out:
2127 2127 AHCIDBG(AHCIDBG_VERBOSE, ahci_ctlp,
2128 2128 "ahci_claim_free_slot: found slot: 0x%x", slot);
2129 2129
2130 2130 return (slot);
2131 2131 }
2132 2132
2133 2133 /*
2134 2134 * Builds the Command Table for the sata packet and delivers it to controller.
2135 2135 *
2136 2136 * Returns:
2137 2137 * slot number if we can obtain a slot successfully
2138 2138 * otherwise, return AHCI_FAILURE
2139 2139 */
2140 2140 static int
2141 2141 ahci_deliver_satapkt(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
2142 2142 ahci_addr_t *addrp, sata_pkt_t *spkt)
2143 2143 {
2144 2144 int cmd_slot;
2145 2145 sata_cmd_t *scmd;
2146 2146 ahci_fis_h2d_register_t *h2d_register_fisp;
2147 2147 ahci_cmd_table_t *cmd_table;
2148 2148 ahci_cmd_header_t *cmd_header;
2149 2149 int ncookies;
2150 2150 int i;
2151 2151 int command_type = AHCI_NON_NCQ_CMD;
2152 2152 int ncq_qdepth;
2153 2153 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
2154 2154 uint8_t port, pmport;
2155 2155 #if AHCI_DEBUG
2156 2156 uint32_t *ptr;
2157 2157 uint8_t *ptr2;
2158 2158 #endif
2159 2159
2160 2160 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
2161 2161
2162 2162 port = addrp->aa_port;
2163 2163 pmport = addrp->aa_pmport;
2164 2164
2165 2165 spkt->satapkt_reason = SATA_PKT_BUSY;
2166 2166
2167 2167 scmd = &spkt->satapkt_cmd;
2168 2168
2169 2169 /* Check if the command is a NCQ command */
2170 2170 if (scmd->satacmd_cmd_reg == SATAC_READ_FPDMA_QUEUED ||
2171 2171 scmd->satacmd_cmd_reg == SATAC_WRITE_FPDMA_QUEUED) {
2172 2172 command_type = AHCI_NCQ_CMD;
2173 2173
2174 2174 /*
2175 2175 * When NCQ is support, system software must determine the
2176 2176 * maximum tag allowed by the device and the HBA, and it
2177 2177 * must use a value not beyond of the lower bound of the two.
2178 2178 *
2179 2179 * Sata module is going to calculate the qdepth and send
2180 2180 * down to HBA driver via sata_cmd.
2181 2181 */
2182 2182 ncq_qdepth = scmd->satacmd_flags.sata_max_queue_depth + 1;
2183 2183
2184 2184 /*
2185 2185 * At the moment, the driver doesn't support the dynamic
2186 2186 * setting of the maximum ncq depth, and the value can be
2187 2187 * set either during the attach or after hot-plug insertion.
2188 2188 */
2189 2189 if (ahci_portp->ahciport_max_ncq_tags == 0) {
2190 2190 ahci_portp->ahciport_max_ncq_tags = ncq_qdepth;
2191 2191 AHCIDBG(AHCIDBG_NCQ, ahci_ctlp,
2192 2192 "ahci_deliver_satapkt: port %d the max tags for "
2193 2193 "NCQ command is %d", port, ncq_qdepth);
2194 2194 } else {
2195 2195 if (ncq_qdepth != ahci_portp->ahciport_max_ncq_tags) {
2196 2196 cmn_err(CE_WARN, "!ahci%d: ahci_deliver_satapkt"
2197 2197 " port %d the max tag for NCQ command is "
2198 2198 "requested to change from %d to %d, at the"
2199 2199 " moment the driver doesn't support the "
2200 2200 "dynamic change so it's going to "
2201 2201 "still use the previous tag value",
2202 2202 instance, port,
2203 2203 ahci_portp->ahciport_max_ncq_tags,
2204 2204 ncq_qdepth);
2205 2205 }
2206 2206 }
2207 2207 }
2208 2208
2209 2209 /* Check if the command is an error retrieval command */
2210 2210 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
2211 2211 command_type = AHCI_ERR_RETRI_CMD;
2212 2212
2213 2213 /* Check if the command is an read/write pmult command */
2214 2214 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp))
2215 2215 command_type = AHCI_RDWR_PMULT_CMD;
2216 2216
2217 2217 /* Check if there is an empty command slot */
2218 2218 cmd_slot = ahci_claim_free_slot(ahci_ctlp, ahci_portp,
2219 2219 addrp, command_type);
2220 2220 if (cmd_slot == AHCI_FAILURE) {
2221 2221 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "no free command slot", NULL);
2222 2222 return (AHCI_FAILURE);
2223 2223 }
2224 2224
2225 2225 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INFO, ahci_ctlp,
2226 2226 "ahci_deliver_satapkt enter: cmd_reg: 0x%x, cmd_slot: 0x%x, "
2227 2227 "port: %d, satapkt: 0x%p", scmd->satacmd_cmd_reg,
2228 2228 cmd_slot, port, (void *)spkt);
2229 2229
2230 2230 cmd_table = ahci_portp->ahciport_cmd_tables[cmd_slot];
2231 2231 bzero((void *)cmd_table, ahci_cmd_table_size);
2232 2232
2233 2233 /* For data transfer operations, it is the H2D Register FIS */
2234 2234 h2d_register_fisp =
2235 2235 &(cmd_table->ahcict_command_fis.ahcifc_fis.ahcifc_h2d_register);
2236 2236
2237 2237 SET_FIS_TYPE(h2d_register_fisp, AHCI_H2D_REGISTER_FIS_TYPE);
2238 2238
2239 2239 /*
2240 2240 * PMP field only make sense when target is a port multiplier or a
2241 2241 * device behind a port multiplier. Otherwise should set it to 0.
2242 2242 */
2243 2243 if (AHCI_ADDR_IS_PMULT(addrp) || AHCI_ADDR_IS_PMPORT(addrp))
2244 2244 SET_FIS_PMP(h2d_register_fisp, pmport);
2245 2245
2246 2246 SET_FIS_CDMDEVCTL(h2d_register_fisp, 1);
2247 2247 SET_FIS_COMMAND(h2d_register_fisp, scmd->satacmd_cmd_reg);
2248 2248 SET_FIS_FEATURES(h2d_register_fisp, scmd->satacmd_features_reg);
2249 2249 SET_FIS_SECTOR_COUNT(h2d_register_fisp, scmd->satacmd_sec_count_lsb);
2250 2250
2251 2251 switch (scmd->satacmd_addr_type) {
2252 2252
2253 2253 case 0:
2254 2254 /*
2255 2255 * satacmd_addr_type will be 0 for the commands below:
2256 2256 * ATAPI command
2257 2257 * SATAC_IDLE_IM
2258 2258 * SATAC_STANDBY_IM
2259 2259 * SATAC_DOWNLOAD_MICROCODE
2260 2260 * SATAC_FLUSH_CACHE
2261 2261 * SATAC_SET_FEATURES
2262 2262 * SATAC_SMART
2263 2263 * SATAC_ID_PACKET_DEVICE
2264 2264 * SATAC_ID_DEVICE
2265 2265 * SATAC_READ_PORTMULT
2266 2266 * SATAC_WRITE_PORTMULT
2267 2267 */
2268 2268 /* FALLTHRU */
2269 2269
2270 2270 case ATA_ADDR_LBA:
2271 2271 /* FALLTHRU */
2272 2272
2273 2273 case ATA_ADDR_LBA28:
2274 2274 /* LBA[7:0] */
2275 2275 SET_FIS_SECTOR(h2d_register_fisp, scmd->satacmd_lba_low_lsb);
2276 2276
2277 2277 /* LBA[15:8] */
2278 2278 SET_FIS_CYL_LOW(h2d_register_fisp, scmd->satacmd_lba_mid_lsb);
2279 2279
2280 2280 /* LBA[23:16] */
2281 2281 SET_FIS_CYL_HI(h2d_register_fisp, scmd->satacmd_lba_high_lsb);
2282 2282
2283 2283 /* LBA [27:24] (also called dev_head) */
2284 2284 SET_FIS_DEV_HEAD(h2d_register_fisp, scmd->satacmd_device_reg);
2285 2285
2286 2286 break;
2287 2287
2288 2288 case ATA_ADDR_LBA48:
2289 2289 /* LBA[7:0] */
2290 2290 SET_FIS_SECTOR(h2d_register_fisp, scmd->satacmd_lba_low_lsb);
2291 2291
2292 2292 /* LBA[15:8] */
2293 2293 SET_FIS_CYL_LOW(h2d_register_fisp, scmd->satacmd_lba_mid_lsb);
2294 2294
2295 2295 /* LBA[23:16] */
2296 2296 SET_FIS_CYL_HI(h2d_register_fisp, scmd->satacmd_lba_high_lsb);
2297 2297
2298 2298 /* LBA [31:24] */
2299 2299 SET_FIS_SECTOR_EXP(h2d_register_fisp,
2300 2300 scmd->satacmd_lba_low_msb);
2301 2301
2302 2302 /* LBA [39:32] */
2303 2303 SET_FIS_CYL_LOW_EXP(h2d_register_fisp,
2304 2304 scmd->satacmd_lba_mid_msb);
2305 2305
2306 2306 /* LBA [47:40] */
2307 2307 SET_FIS_CYL_HI_EXP(h2d_register_fisp,
2308 2308 scmd->satacmd_lba_high_msb);
2309 2309
2310 2310 /* Set dev_head */
2311 2311 SET_FIS_DEV_HEAD(h2d_register_fisp,
2312 2312 scmd->satacmd_device_reg);
2313 2313
2314 2314 /* Set the extended sector count and features */
2315 2315 SET_FIS_SECTOR_COUNT_EXP(h2d_register_fisp,
2316 2316 scmd->satacmd_sec_count_msb);
2317 2317 SET_FIS_FEATURES_EXP(h2d_register_fisp,
2318 2318 scmd->satacmd_features_reg_ext);
2319 2319 break;
2320 2320 }
2321 2321
2322 2322 /*
2323 2323 * For NCQ command (READ/WRITE FPDMA QUEUED), sector count 7:0 is
2324 2324 * filled into features field, and sector count 8:15 is filled into
2325 2325 * features (exp) field. The hba driver doesn't need to anything
2326 2326 * special with regard to this, since sata framework has already
2327 2327 * done so.
2328 2328 *
2329 2329 * However the driver needs to make sure TAG is filled into sector
2330 2330 * field.
2331 2331 */
2332 2332 if (command_type == AHCI_NCQ_CMD) {
2333 2333 SET_FIS_SECTOR_COUNT(h2d_register_fisp,
2334 2334 (cmd_slot << SATA_TAG_QUEUING_SHIFT));
2335 2335 }
2336 2336
2337 2337 ncookies = scmd->satacmd_num_dma_cookies;
2338 2338 AHCIDBG(AHCIDBG_PRDT, ahci_ctlp,
2339 2339 "ncookies = 0x%x, ahci_dma_prdt_number = 0x%x",
2340 2340 ncookies, ahci_dma_prdt_number);
2341 2341
2342 2342 ASSERT(ncookies <= ahci_dma_prdt_number);
2343 2343 ahci_portp->ahciport_prd_bytecounts[cmd_slot] = 0;
2344 2344
2345 2345 /* *** now fill the scatter gather list ******* */
2346 2346 for (i = 0; i < ncookies; i++) {
2347 2347 cmd_table->ahcict_prdt[i].ahcipi_data_base_addr =
2348 2348 scmd->satacmd_dma_cookie_list[i]._dmu._dmac_la[0];
2349 2349 cmd_table->ahcict_prdt[i].ahcipi_data_base_addr_upper =
2350 2350 scmd->satacmd_dma_cookie_list[i]._dmu._dmac_la[1];
2351 2351 cmd_table->ahcict_prdt[i].ahcipi_descr_info =
2352 2352 scmd->satacmd_dma_cookie_list[i].dmac_size - 1;
2353 2353 ahci_portp->ahciport_prd_bytecounts[cmd_slot] +=
2354 2354 scmd->satacmd_dma_cookie_list[i].dmac_size;
2355 2355 }
2356 2356
2357 2357 AHCIDBG(AHCIDBG_PRDT, ahci_ctlp,
2358 2358 "ahciport_prd_bytecounts 0x%x for cmd_slot 0x%x",
2359 2359 ahci_portp->ahciport_prd_bytecounts[cmd_slot], cmd_slot);
2360 2360
2361 2361 /* The ACMD field is filled in for ATAPI command */
2362 2362 if (scmd->satacmd_cmd_reg == SATAC_PACKET) {
2363 2363 bcopy(scmd->satacmd_acdb, cmd_table->ahcict_atapi_cmd,
2364 2364 SATA_ATAPI_MAX_CDB_LEN);
2365 2365 }
2366 2366
2367 2367 /* Set Command Header in Command List */
2368 2368 cmd_header = &ahci_portp->ahciport_cmd_list[cmd_slot];
2369 2369 BZERO_DESCR_INFO(cmd_header);
2370 2370 BZERO_PRD_BYTE_COUNT(cmd_header);
2371 2371
2372 2372 /* Set the number of entries in the PRD table */
2373 2373 SET_PRD_TABLE_LENGTH(cmd_header, ncookies);
2374 2374
2375 2375 /* Set the length of the command in the CFIS area */
2376 2376 SET_COMMAND_FIS_LENGTH(cmd_header, AHCI_H2D_REGISTER_FIS_LENGTH);
2377 2377
2378 2378 /*
2379 2379 * PMP field only make sense when target is a port multiplier or a
2380 2380 * device behind a port multiplier. Otherwise should set it to 0.
2381 2381 */
2382 2382 if (AHCI_ADDR_IS_PMULT(addrp) || AHCI_ADDR_IS_PMPORT(addrp))
2383 2383 SET_PORT_MULTI_PORT(cmd_header, pmport);
2384 2384
2385 2385 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "command data direction is "
2386 2386 "sata_data_direction = 0x%x",
2387 2387 scmd->satacmd_flags.sata_data_direction);
2388 2388
2389 2389 /* Set A bit if it is an ATAPI command */
2390 2390 if (scmd->satacmd_cmd_reg == SATAC_PACKET)
2391 2391 SET_ATAPI(cmd_header, AHCI_CMDHEAD_ATAPI);
2392 2392
2393 2393 /* Set W bit if data is going to the device */
2394 2394 if (scmd->satacmd_flags.sata_data_direction == SATA_DIR_WRITE)
2395 2395 SET_WRITE(cmd_header, AHCI_CMDHEAD_DATA_WRITE);
2396 2396
2397 2397 /*
2398 2398 * Set the prefetchable bit - this bit is only valid if the PRDTL
2399 2399 * field is non-zero or the ATAPI 'A' bit is set in the command
2400 2400 * header. This bit cannot be set when using native command
2401 2401 * queuing commands or when using FIS-based switching with a Port
2402 2402 * multiplier.
2403 2403 */
2404 2404 if (command_type != AHCI_NCQ_CMD)
2405 2405 SET_PREFETCHABLE(cmd_header, AHCI_CMDHEAD_PREFETCHABLE);
2406 2406
2407 2407 /*
2408 2408 * Now remember the sata packet in ahciport_slot_pkts[].
2409 2409 * Error retrieval command and r/w port multiplier command will
2410 2410 * be stored specifically for each port.
2411 2411 */
2412 2412 if (!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&
2413 2413 !RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp))
2414 2414 ahci_portp->ahciport_slot_pkts[cmd_slot] = spkt;
2415 2415
2416 2416 /*
2417 2417 * Keep the timeout value
2418 2418 */
2419 2419 ahci_portp->ahciport_slot_timeout[cmd_slot] = spkt->satapkt_time;
2420 2420
2421 2421 /*
2422 2422 * If the intial timout is less than 1 tick, then make it longer by
2423 2423 * 1 tick to avoid immediate timeout
2424 2424 */
2425 2425 if (ahci_portp->ahciport_slot_timeout[cmd_slot] <=
2426 2426 ahci_watchdog_timeout)
2427 2427 ahci_portp->ahciport_slot_timeout[cmd_slot] +=
2428 2428 ahci_watchdog_timeout;
2429 2429
2430 2430 #if AHCI_DEBUG
2431 2431 if (ahci_debug_flags & AHCIDBG_ATACMD &&
2432 2432 scmd->satacmd_cmd_reg != SATAC_PACKET ||
2433 2433 ahci_debug_flags & AHCIDBG_ATAPICMD &&
2434 2434 scmd->satacmd_cmd_reg == SATAC_PACKET) {
2435 2435
2436 2436 /* Dump the command header and table */
2437 2437 ahci_log(ahci_ctlp, CE_WARN, "\n");
2438 2438 ahci_log(ahci_ctlp, CE_WARN, "Command header&table for spkt "
2439 2439 "0x%p cmd_reg 0x%x port %d", spkt,
2440 2440 scmd->satacmd_cmd_reg, port);
2441 2441 ptr = (uint32_t *)cmd_header;
2442 2442 ahci_log(ahci_ctlp, CE_WARN,
2443 2443 " Command Header:%8x %8x %8x %8x",
2444 2444 ptr[0], ptr[1], ptr[2], ptr[3]);
2445 2445
2446 2446 /* Dump the H2D register FIS */
2447 2447 ptr = (uint32_t *)h2d_register_fisp;
2448 2448 ahci_log(ahci_ctlp, CE_WARN,
2449 2449 " Command FIS: %8x %8x %8x %8x",
2450 2450 ptr[0], ptr[1], ptr[2], ptr[3]);
2451 2451
2452 2452 /* Dump the ACMD register FIS */
2453 2453 ptr2 = (uint8_t *)&(cmd_table->ahcict_atapi_cmd);
2454 2454 for (i = 0; i < SATA_ATAPI_MAX_CDB_LEN/8; i++)
2455 2455 if (ahci_debug_flags & AHCIDBG_ATAPICMD)
2456 2456 ahci_log(ahci_ctlp, CE_WARN,
2457 2457 " ATAPI command: %2x %2x %2x %2x "
2458 2458 "%2x %2x %2x %2x",
2459 2459 ptr2[8 * i], ptr2[8 * i + 1],
2460 2460 ptr2[8 * i + 2], ptr2[8 * i + 3],
2461 2461 ptr2[8 * i + 4], ptr2[8 * i + 5],
2462 2462 ptr2[8 * i + 6], ptr2[8 * i + 7]);
2463 2463
2464 2464 /* Dump the PRDT */
2465 2465 for (i = 0; i < ncookies; i++) {
2466 2466 ptr = (uint32_t *)&(cmd_table->ahcict_prdt[i]);
2467 2467 ahci_log(ahci_ctlp, CE_WARN,
2468 2468 " Cookie %d: %8x %8x %8x %8x",
2469 2469 i, ptr[0], ptr[1], ptr[2], ptr[3]);
2470 2470 }
2471 2471 }
2472 2472 #endif
2473 2473
2474 2474 (void) ddi_dma_sync(
2475 2475 ahci_portp->ahciport_cmd_tables_dma_handle[cmd_slot],
2476 2476 0,
2477 2477 ahci_cmd_table_size,
2478 2478 DDI_DMA_SYNC_FORDEV);
2479 2479
2480 2480 (void) ddi_dma_sync(ahci_portp->ahciport_cmd_list_dma_handle,
2481 2481 cmd_slot * sizeof (ahci_cmd_header_t),
2482 2482 sizeof (ahci_cmd_header_t),
2483 2483 DDI_DMA_SYNC_FORDEV);
2484 2484
2485 2485 if ((ahci_check_dma_handle(ahci_portp->
2486 2486 ahciport_cmd_tables_dma_handle[cmd_slot]) != DDI_FM_OK) ||
2487 2487 ahci_check_dma_handle(ahci_portp->
2488 2488 ahciport_cmd_list_dma_handle) != DDI_FM_OK) {
2489 2489 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
2490 2490 DDI_SERVICE_UNAFFECTED);
2491 2491 return (AHCI_FAILURE);
2492 2492 }
2493 2493
2494 2494 /* Set the corresponding bit in the PxSACT.DS for queued command */
2495 2495 if (command_type == AHCI_NCQ_CMD) {
2496 2496 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
2497 2497 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port),
2498 2498 (0x1 << cmd_slot));
2499 2499 }
2500 2500
2501 2501 /* Indicate to the HBA that a command is active. */
2502 2502 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
2503 2503 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port),
2504 2504 (0x1 << cmd_slot));
2505 2505
2506 2506 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "ahci_deliver_satapkt "
2507 2507 "exit: port %d", port);
2508 2508
2509 2509 /* Make sure the command is started by the PxSACT/PxCI */
2510 2510 if (ahci_check_acc_handle(ahci_ctlp->
2511 2511 ahcictl_ahci_acc_handle) != DDI_FM_OK) {
2512 2512 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
2513 2513 DDI_SERVICE_UNAFFECTED);
2514 2514 return (AHCI_FAILURE);
2515 2515 }
2516 2516
2517 2517 return (cmd_slot);
2518 2518 }
2519 2519
2520 2520 /*
2521 2521 * Called by the sata framework to abort the previously sent packet(s).
2522 2522 *
2523 2523 * Reset device to abort commands.
2524 2524 */
2525 2525 static int
2526 2526 ahci_tran_abort(dev_info_t *dip, sata_pkt_t *spkt, int flag)
2527 2527 {
2528 2528 ahci_ctl_t *ahci_ctlp;
2529 2529 ahci_port_t *ahci_portp;
2530 2530 uint32_t slot_status = 0;
2531 2531 uint32_t aborted_tags = 0;
2532 2532 uint32_t finished_tags = 0;
2533 2533 uint8_t cport = spkt->satapkt_device.satadev_addr.cport;
2534 2534 uint8_t port;
2535 2535 int tmp_slot;
2536 2536 int instance = ddi_get_instance(dip);
2537 2537
2538 2538 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
2539 2539 port = ahci_ctlp->ahcictl_cport_to_port[cport];
2540 2540
2541 2541 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
2542 2542 "ahci_tran_abort enter: port %d", port);
2543 2543
2544 2544 ahci_portp = ahci_ctlp->ahcictl_ports[port];
2545 2545 mutex_enter(&ahci_portp->ahciport_mutex);
2546 2546
2547 2547 /*
2548 2548 * If AHCI_PORT_FLAG_MOPPING flag is set, it means all the pending
2549 2549 * commands are being mopped, therefore there is nothing else to do
2550 2550 */
2551 2551 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
2552 2552 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2553 2553 "ahci_tran_abort: port %d is in "
2554 2554 "mopping process, so just return directly ", port);
2555 2555 mutex_exit(&ahci_portp->ahciport_mutex);
2556 2556 return (SATA_SUCCESS);
2557 2557 }
2558 2558
2559 2559 /*
2560 2560 * If AHCI_PORT_FLAG_RDWR_PMULT flag is set, it means a R/W PMULT
2561 2561 * command is being executed so no other commands is outstanding,
2562 2562 * nothing to do.
2563 2563 */
2564 2564 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_RDWR_PMULT) {
2565 2565 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2566 2566 "ahci_tran_abort: port %d is reading/writing "
2567 2567 "port multiplier, so just return directly ", port);
2568 2568 mutex_exit(&ahci_portp->ahciport_mutex);
2569 2569 return (SATA_SUCCESS);
2570 2570 }
2571 2571
2572 2572 if (ahci_portp->ahciport_port_state & SATA_PSTATE_FAILED |
2573 2573 ahci_portp->ahciport_port_state & SATA_PSTATE_SHUTDOWN |
2574 2574 ahci_portp->ahciport_port_state & SATA_PSTATE_PWROFF) {
2575 2575 /*
2576 2576 * In case the targer driver would send the request before
2577 2577 * sata framework can have the opportunity to process those
2578 2578 * event reports.
2579 2579 */
2580 2580 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
2581 2581 spkt->satapkt_device.satadev_state =
2582 2582 ahci_portp->ahciport_port_state;
2583 2583 ahci_update_sata_registers(ahci_ctlp, port,
2584 2584 &spkt->satapkt_device);
2585 2585 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2586 2586 "ahci_tran_abort returning SATA_FAILURE while "
2587 2587 "port in FAILED/SHUTDOWN/PWROFF state: "
2588 2588 "port: %d", port);
2589 2589 mutex_exit(&ahci_portp->ahciport_mutex);
2590 2590 return (SATA_FAILURE);
2591 2591 }
2592 2592
2593 2593 if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
2594 2594 /*
2595 2595 * ahci_intr_phyrdy_change() may have rendered it to
2596 2596 * AHCI_PORT_TYPE_NODEV.
2597 2597 */
2598 2598 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
2599 2599 spkt->satapkt_device.satadev_type = SATA_DTYPE_NONE;
2600 2600 spkt->satapkt_device.satadev_state =
2601 2601 ahci_portp->ahciport_port_state;
2602 2602 ahci_update_sata_registers(ahci_ctlp, port,
2603 2603 &spkt->satapkt_device);
2604 2604 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2605 2605 "ahci_tran_abort returning SATA_FAILURE while "
2606 2606 "no device attached: port: %d", port);
2607 2607 mutex_exit(&ahci_portp->ahciport_mutex);
2608 2608 return (SATA_FAILURE);
2609 2609 }
2610 2610
2611 2611 if (flag == SATA_ABORT_ALL_PACKETS) {
2612 2612 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2613 2613 aborted_tags = ahci_portp->ahciport_pending_tags;
2614 2614 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2615 2615 aborted_tags = ahci_portp->ahciport_pending_ncq_tags;
2616 2616
2617 2617 cmn_err(CE_NOTE, "!ahci%d: ahci port %d abort all packets",
2618 2618 instance, port);
2619 2619 } else {
2620 2620 aborted_tags = 0xffffffff;
2621 2621 /*
2622 2622 * Aborting one specific packet, first search the
2623 2623 * ahciport_slot_pkts[] list for matching spkt.
2624 2624 */
2625 2625 for (tmp_slot = 0;
2626 2626 tmp_slot < ahci_ctlp->ahcictl_num_cmd_slots; tmp_slot++) {
2627 2627 if (ahci_portp->ahciport_slot_pkts[tmp_slot] == spkt) {
2628 2628 aborted_tags = (0x1 << tmp_slot);
2629 2629 break;
2630 2630 }
2631 2631 }
2632 2632
2633 2633 if (aborted_tags == 0xffffffff) {
2634 2634 /* request packet is not on the pending list */
2635 2635 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2636 2636 "Cannot find the aborting pkt 0x%p on the "
2637 2637 "pending list", (void *)spkt);
2638 2638 ahci_update_sata_registers(ahci_ctlp, port,
2639 2639 &spkt->satapkt_device);
2640 2640 mutex_exit(&ahci_portp->ahciport_mutex);
2641 2641 return (SATA_FAILURE);
2642 2642 }
2643 2643 cmn_err(CE_NOTE, "!ahci%d: ahci port %d abort satapkt 0x%p",
2644 2644 instance, port, (void *)spkt);
2645 2645 }
2646 2646
2647 2647 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2648 2648 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2649 2649 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
2650 2650 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2651 2651 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2652 2652 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
2653 2653
2654 2654 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
2655 2655 ahci_portp->ahciport_mop_in_progress++;
2656 2656
2657 2657 /*
2658 2658 * To abort the packet(s), first we are trying to clear PxCMD.ST
2659 2659 * to stop the port, and if the port can be stopped
2660 2660 * successfully with PxTFD.STS.BSY and PxTFD.STS.DRQ cleared to '0',
2661 2661 * then we just send back the aborted packet(s) with ABORTED flag
2662 2662 * and then restart the port by setting PxCMD.ST and PxCMD.FRE.
2663 2663 * If PxTFD.STS.BSY or PxTFD.STS.DRQ is set to '1', then we
2664 2664 * perform a COMRESET.
2665 2665 */
2666 2666 (void) ahci_restart_port_wait_till_ready(ahci_ctlp,
2667 2667 ahci_portp, port, NULL, NULL);
2668 2668
2669 2669 /*
2670 2670 * Compute which have finished and which need to be retried.
2671 2671 *
2672 2672 * The finished tags are ahciport_pending_tags/ahciport_pending_ncq_tags
2673 2673 * minus the slot_status. The aborted_tags has to be deducted by
2674 2674 * finished_tags since we can't possibly abort a tag which had finished
2675 2675 * already.
2676 2676 */
2677 2677 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2678 2678 finished_tags = ahci_portp->ahciport_pending_tags &
2679 2679 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2680 2680 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2681 2681 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
2682 2682 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2683 2683
2684 2684 aborted_tags &= ~finished_tags;
2685 2685
2686 2686 ahci_mop_commands(ahci_ctlp,
2687 2687 ahci_portp,
2688 2688 slot_status,
2689 2689 0, /* failed tags */
2690 2690 0, /* timeout tags */
2691 2691 aborted_tags,
2692 2692 0); /* reset tags */
2693 2693
2694 2694 ahci_update_sata_registers(ahci_ctlp, port, &spkt->satapkt_device);
2695 2695 mutex_exit(&ahci_portp->ahciport_mutex);
2696 2696
2697 2697 return (SATA_SUCCESS);
2698 2698 }
2699 2699
2700 2700 /*
2701 2701 * Used to do device reset and reject all the pending packets on a device
2702 2702 * during the reset operation.
2703 2703 *
2704 2704 * NOTE: ONLY called by ahci_tran_reset_dport
2705 2705 */
2706 2706 static int
2707 2707 ahci_reset_device_reject_pkts(ahci_ctl_t *ahci_ctlp,
2708 2708 ahci_port_t *ahci_portp, ahci_addr_t *addrp)
2709 2709 {
2710 2710 uint32_t slot_status = 0;
2711 2711 uint32_t reset_tags = 0;
2712 2712 uint32_t finished_tags = 0;
2713 2713 uint8_t port = addrp->aa_port;
2714 2714 sata_device_t sdevice;
2715 2715 int ret;
2716 2716
2717 2717 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
2718 2718
2719 2719 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
2720 2720 "ahci_reset_device_reject_pkts on port: %d", port);
2721 2721
2722 2722 /*
2723 2723 * If AHCI_PORT_FLAG_MOPPING flag is set, it means all the pending
2724 2724 * commands are being mopped, therefore there is nothing else to do
2725 2725 */
2726 2726 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
2727 2727 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2728 2728 "ahci_reset_device_reject_pkts: port %d is in "
2729 2729 "mopping process, so return directly ", port);
2730 2730 return (SATA_SUCCESS);
2731 2731 }
2732 2732
2733 2733 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2734 2734 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2735 2735 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
2736 2736 reset_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2737 2737 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2738 2738 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2739 2739 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
2740 2740 reset_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2741 2741 }
2742 2742
2743 2743 if (ahci_software_reset(ahci_ctlp, ahci_portp, addrp)
2744 2744 != AHCI_SUCCESS) {
2745 2745 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2746 2746 "Try to do a port reset after software "
2747 2747 "reset failed", port);
2748 2748 ret = ahci_port_reset(ahci_ctlp, ahci_portp, addrp);
2749 2749 if (ret != AHCI_SUCCESS) {
2750 2750 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2751 2751 "ahci_reset_device_reject_pkts: port %d "
2752 2752 "failed", port);
2753 2753 return (SATA_FAILURE);
2754 2754 }
2755 2755 }
2756 2756 /* Set the reset in progress flag */
2757 2757 ahci_portp->ahciport_reset_in_progress = 1;
2758 2758
2759 2759 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
2760 2760 ahci_portp->ahciport_mop_in_progress++;
2761 2761
2762 2762 /* Indicate to the framework that a reset has happened */
2763 2763 bzero((void *)&sdevice, sizeof (sata_device_t));
2764 2764 sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
2765 2765 sdevice.satadev_addr.pmport = 0;
2766 2766 sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
2767 2767 sdevice.satadev_state = SATA_DSTATE_RESET |
2768 2768 SATA_DSTATE_PWR_ACTIVE;
2769 2769 mutex_exit(&ahci_portp->ahciport_mutex);
2770 2770 sata_hba_event_notify(
2771 2771 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
2772 2772 &sdevice,
2773 2773 SATA_EVNT_DEVICE_RESET);
2774 2774 mutex_enter(&ahci_portp->ahciport_mutex);
2775 2775
2776 2776 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
2777 2777 "port %d sending event up: SATA_EVNT_DEVICE_RESET", port);
2778 2778
2779 2779 /* Next try to mop the pending commands */
2780 2780 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2781 2781 finished_tags = ahci_portp->ahciport_pending_tags &
2782 2782 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2783 2783 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2784 2784 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
2785 2785 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2786 2786
2787 2787 reset_tags &= ~finished_tags;
2788 2788
2789 2789 ahci_mop_commands(ahci_ctlp,
2790 2790 ahci_portp,
2791 2791 slot_status,
2792 2792 0, /* failed tags */
2793 2793 0, /* timeout tags */
2794 2794 0, /* aborted tags */
2795 2795 reset_tags); /* reset tags */
2796 2796
2797 2797 return (SATA_SUCCESS);
2798 2798 }
2799 2799
2800 2800 /*
2801 2801 * Used to do device reset and reject all the pending packets on a device
2802 2802 * during the reset operation.
2803 2803 *
2804 2804 * NOTE: ONLY called by ahci_tran_reset_dport
2805 2805 */
2806 2806 static int
2807 2807 ahci_reset_pmdevice_reject_pkts(ahci_ctl_t *ahci_ctlp,
2808 2808 ahci_port_t *ahci_portp, ahci_addr_t *addrp)
2809 2809 {
2810 2810 uint32_t finished_tags = 0, reset_tags = 0, slot_status = 0;
2811 2811 uint8_t port = addrp->aa_port;
2812 2812 uint8_t pmport = addrp->aa_pmport;
2813 2813 sata_device_t sdevice;
2814 2814
2815 2815 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
2816 2816
2817 2817 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_PMULT, ahci_ctlp,
2818 2818 "ahci_reset_pmdevice_reject_pkts at port %d:%d", port, pmport);
2819 2819
2820 2820 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
2821 2821 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2822 2822 "ahci_reset_pmdevice_reject_pkts: port %d is in "
2823 2823 "mopping process, so return directly ", port);
2824 2824 return (SATA_SUCCESS);
2825 2825 }
2826 2826
2827 2827 /* Checking for outstanding commands */
2828 2828 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2829 2829 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2830 2830 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
2831 2831 reset_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2832 2832 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2833 2833 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2834 2834 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
2835 2835 reset_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2836 2836 }
2837 2837
2838 2838 /* Issue SOFTWARE reset command. */
2839 2839 if (ahci_software_reset(ahci_ctlp, ahci_portp, addrp)
2840 2840 != AHCI_SUCCESS) {
2841 2841 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2842 2842 "Try to do a port reset after software "
2843 2843 "reset failed", port);
2844 2844 return (SATA_FAILURE);
2845 2845 }
2846 2846
2847 2847 /* Set the reset in progress flag */
2848 2848 ahci_portp->ahciport_reset_in_progress = 1;
2849 2849
2850 2850 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
2851 2851 ahci_portp->ahciport_mop_in_progress++;
2852 2852
2853 2853 /* Indicate to the framework that a reset has happened */
2854 2854 bzero((void *)&sdevice, sizeof (sata_device_t));
2855 2855 sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
2856 2856 sdevice.satadev_addr.pmport = pmport;
2857 2857 if (AHCI_ADDR_IS_PMULT(addrp))
2858 2858 sdevice.satadev_addr.qual = SATA_ADDR_PMULT;
2859 2859 else
2860 2860 sdevice.satadev_addr.qual = SATA_ADDR_DPMPORT;
2861 2861 sdevice.satadev_state = SATA_DSTATE_RESET |
2862 2862 SATA_DSTATE_PWR_ACTIVE;
2863 2863 mutex_exit(&ahci_portp->ahciport_mutex);
2864 2864 sata_hba_event_notify(
2865 2865 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
2866 2866 &sdevice,
2867 2867 SATA_EVNT_DEVICE_RESET);
2868 2868 mutex_enter(&ahci_portp->ahciport_mutex);
2869 2869
2870 2870 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
2871 2871 "port %d:%d sending event up: SATA_EVNT_DEVICE_RESET",
2872 2872 port, pmport);
2873 2873
2874 2874 /* Next try to mop the pending commands */
2875 2875 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2876 2876 finished_tags = ahci_portp->ahciport_pending_tags &
2877 2877 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2878 2878 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2879 2879 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
2880 2880 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2881 2881 reset_tags &= ~finished_tags;
2882 2882
2883 2883 AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
2884 2884 "reset_tags = %x, finished_tags = %x, slot_status = %x",
2885 2885 reset_tags, finished_tags, slot_status);
2886 2886
2887 2887 /*
2888 2888 * NOTE: Because PxCI be only erased by unset PxCMD.ST bit, so even we
2889 2889 * try to reset a single device behind a port multiplier will
2890 2890 * terminate all the commands on that HBA port. We need mop these
2891 2891 * commands as well.
2892 2892 */
2893 2893 ahci_mop_commands(ahci_ctlp,
2894 2894 ahci_portp,
2895 2895 slot_status,
2896 2896 0, /* failed tags */
2897 2897 0, /* timeout tags */
2898 2898 0, /* aborted tags */
2899 2899 reset_tags); /* reset tags */
2900 2900
2901 2901 return (SATA_SUCCESS);
2902 2902 }
2903 2903
2904 2904 /*
2905 2905 * Used to do port reset and reject all the pending packets on a port during
2906 2906 * the reset operation.
2907 2907 */
2908 2908 static int
2909 2909 ahci_reset_port_reject_pkts(ahci_ctl_t *ahci_ctlp,
2910 2910 ahci_port_t *ahci_portp, ahci_addr_t *addrp)
2911 2911 {
2912 2912 uint32_t slot_status = 0;
2913 2913 uint32_t reset_tags = 0;
2914 2914 uint32_t finished_tags = 0;
2915 2915 uint8_t port = addrp->aa_port;
2916 2916
2917 2917 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
2918 2918
2919 2919 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
2920 2920 "ahci_reset_port_reject_pkts at port: %d", port);
2921 2921
2922 2922 /*
2923 2923 * If AHCI_PORT_FLAG_MOPPING flag is set, it means all the pending
2924 2924 * commands are being mopped, therefore there is nothing else to do
2925 2925 */
2926 2926 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
2927 2927 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2928 2928 "ahci_reset_port_reject_pkts: port %d is in "
2929 2929 "mopping process, so return directly ", port);
2930 2930 return (SATA_SUCCESS);
2931 2931 }
2932 2932
2933 2933 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
2934 2934 ahci_portp->ahciport_mop_in_progress++;
2935 2935
2936 2936 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2937 2937 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2938 2938 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
2939 2939 reset_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2940 2940 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2941 2941 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2942 2942 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
2943 2943 reset_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2944 2944 }
2945 2945
2946 2946 if (ahci_restart_port_wait_till_ready(ahci_ctlp,
2947 2947 ahci_portp, port, AHCI_PORT_RESET|AHCI_RESET_NO_EVENTS_UP,
2948 2948 NULL) != AHCI_SUCCESS) {
2949 2949
2950 2950 /* Clear mop flag */
2951 2951 ahci_portp->ahciport_mop_in_progress--;
2952 2952 if (ahci_portp->ahciport_mop_in_progress == 0)
2953 2953 ahci_portp->ahciport_flags &=
2954 2954 ~AHCI_PORT_FLAG_MOPPING;
2955 2955 return (SATA_FAILURE);
2956 2956 }
2957 2957
2958 2958 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2959 2959 finished_tags = ahci_portp->ahciport_pending_tags &
2960 2960 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2961 2961 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2962 2962 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
2963 2963 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2964 2964
2965 2965 reset_tags &= ~finished_tags;
2966 2966
2967 2967 ahci_mop_commands(ahci_ctlp,
2968 2968 ahci_portp,
2969 2969 slot_status,
2970 2970 0, /* failed tags */
2971 2971 0, /* timeout tags */
2972 2972 0, /* aborted tags */
2973 2973 reset_tags); /* reset tags */
2974 2974
2975 2975 return (SATA_SUCCESS);
2976 2976 }
2977 2977
2978 2978 /*
2979 2979 * Used to do hba reset and reject all the pending packets on all ports
2980 2980 * during the reset operation.
2981 2981 */
2982 2982 static int
2983 2983 ahci_reset_hba_reject_pkts(ahci_ctl_t *ahci_ctlp)
2984 2984 {
2985 2985 ahci_port_t *ahci_portp;
2986 2986 uint32_t slot_status[AHCI_MAX_PORTS];
2987 2987 uint32_t reset_tags[AHCI_MAX_PORTS];
2988 2988 uint32_t finished_tags[AHCI_MAX_PORTS];
2989 2989 int port;
2990 2990 int ret = SATA_SUCCESS;
2991 2991
2992 2992 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
2993 2993 "ahci_reset_hba_reject_pkts enter", NULL);
2994 2994
2995 2995 bzero(slot_status, sizeof (slot_status));
2996 2996 bzero(reset_tags, sizeof (reset_tags));
2997 2997 bzero(finished_tags, sizeof (finished_tags));
2998 2998
2999 2999 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3000 3000 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3001 3001 continue;
3002 3002 }
3003 3003
3004 3004 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3005 3005
3006 3006 mutex_enter(&ahci_portp->ahciport_mutex);
3007 3007 ahci_portp->ahciport_reset_in_progress = 1;
3008 3008 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
3009 3009 slot_status[port] = ddi_get32(
3010 3010 ahci_ctlp->ahcictl_ahci_acc_handle,
3011 3011 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
3012 3012 reset_tags[port] = slot_status[port] &
3013 3013 AHCI_SLOT_MASK(ahci_ctlp);
3014 3014 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3015 3015 "port %d: reset_tags = 0x%x pending_tags = 0x%x",
3016 3016 port, reset_tags[port],
3017 3017 ahci_portp->ahciport_pending_tags);
3018 3018 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
3019 3019 slot_status[port] = ddi_get32(
3020 3020 ahci_ctlp->ahcictl_ahci_acc_handle,
3021 3021 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
3022 3022 reset_tags[port] = slot_status[port] &
3023 3023 AHCI_NCQ_SLOT_MASK(ahci_portp);
3024 3024 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3025 3025 "port %d: reset_tags = 0x%x pending_tags = 0x%x",
3026 3026 port, reset_tags[port],
3027 3027 ahci_portp->ahciport_pending_tags);
3028 3028 }
3029 3029 mutex_exit(&ahci_portp->ahciport_mutex);
3030 3030 }
3031 3031
3032 3032 if (ahci_hba_reset(ahci_ctlp) != AHCI_SUCCESS) {
3033 3033 ret = SATA_FAILURE;
3034 3034 }
3035 3035
3036 3036 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3037 3037 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3038 3038 continue;
3039 3039 }
3040 3040
3041 3041 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3042 3042
3043 3043 mutex_enter(&ahci_portp->ahciport_mutex);
3044 3044 /*
3045 3045 * To prevent recursive enter to ahci_mop_commands, we need
3046 3046 * check AHCI_PORT_FLAG_MOPPING flag.
3047 3047 */
3048 3048 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
3049 3049 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3050 3050 "ahci_reset_hba_reject_pkts: port %d is in "
3051 3051 "mopping process, so return directly ", port);
3052 3052 mutex_exit(&ahci_portp->ahciport_mutex);
3053 3053 continue;
3054 3054 }
3055 3055
3056 3056 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
3057 3057 ahci_portp->ahciport_mop_in_progress++;
3058 3058
3059 3059 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
3060 3060 finished_tags[port] =
3061 3061 ahci_portp->ahciport_pending_tags &
3062 3062 ~slot_status[port] & AHCI_SLOT_MASK(ahci_ctlp);
3063 3063 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
3064 3064 finished_tags[port] =
3065 3065 ahci_portp->ahciport_pending_ncq_tags &
3066 3066 ~slot_status[port] & AHCI_NCQ_SLOT_MASK(ahci_portp);
3067 3067
3068 3068 reset_tags[port] &= ~finished_tags[port];
3069 3069
3070 3070 ahci_mop_commands(ahci_ctlp,
3071 3071 ahci_portp,
3072 3072 slot_status[port],
3073 3073 0, /* failed tags */
3074 3074 0, /* timeout tags */
3075 3075 0, /* aborted tags */
3076 3076 reset_tags[port]); /* reset tags */
3077 3077 mutex_exit(&ahci_portp->ahciport_mutex);
3078 3078 }
3079 3079 out:
3080 3080 return (ret);
3081 3081 }
3082 3082
3083 3083 /*
3084 3084 * Called by sata framework to reset a port(s) or device.
3085 3085 */
3086 3086 static int
3087 3087 ahci_tran_reset_dport(dev_info_t *dip, sata_device_t *sd)
3088 3088 {
3089 3089 ahci_ctl_t *ahci_ctlp;
3090 3090 ahci_port_t *ahci_portp;
3091 3091 ahci_addr_t addr;
3092 3092 uint8_t cport = sd->satadev_addr.cport;
3093 3093 uint8_t pmport = sd->satadev_addr.pmport;
3094 3094 uint8_t port;
3095 3095 int ret = SATA_SUCCESS;
3096 3096 int instance = ddi_get_instance(dip);
3097 3097
3098 3098 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
3099 3099 port = ahci_ctlp->ahcictl_cport_to_port[cport];
3100 3100 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3101 3101
3102 3102 ahci_get_ahci_addr(ahci_ctlp, sd, &addr);
3103 3103
3104 3104 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
3105 3105 "ahci_tran_reset_dport enter: cport %d", cport);
3106 3106
3107 3107 switch (sd->satadev_addr.qual) {
3108 3108 case SATA_ADDR_PMPORT:
3109 3109 /*
3110 3110 * If we want to issue a COMRESET on a pmport, we need to
3111 3111 * reject the outstanding commands on that pmport. According
3112 3112 * to AHCI spec, PxCI register could only be cleared by
3113 3113 * clearing PxCMD.ST, which will halt the controller port - as
3114 3114 * well as other pmports.
3115 3115 *
3116 3116 * Therefore we directly reset the controller port for
3117 3117 * simplicity. ahci_tran_probe_port() will handle reset stuff
3118 3118 * like initializing the given pmport.
3119 3119 */
3120 3120 /* FALLTHRU */
3121 3121 case SATA_ADDR_CPORT:
3122 3122 /* Port reset */
3123 3123 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3124 3124 cmn_err(CE_NOTE, "!ahci%d: ahci_tran_reset_dport "
3125 3125 "port %d reset port", instance, port);
3126 3126
3127 3127 mutex_enter(&ahci_portp->ahciport_mutex);
3128 3128 ret = ahci_reset_port_reject_pkts(ahci_ctlp, ahci_portp, &addr);
3129 3129 mutex_exit(&ahci_portp->ahciport_mutex);
3130 3130
3131 3131 break;
3132 3132
3133 3133 case SATA_ADDR_DPMPORT:
3134 3134 cmn_err(CE_NOTE, "!ahci%d: ahci_tran_reset_dport "
3135 3135 "port %d:%d reset device", instance, port, pmport);
3136 3136 /* FALLTHRU */
3137 3137 case SATA_ADDR_DCPORT:
3138 3138 /* Device reset */
3139 3139 if (sd->satadev_addr.qual == SATA_ADDR_DCPORT)
3140 3140 cmn_err(CE_NOTE, "!ahci%d: ahci_tran_reset_dport "
3141 3141 "port %d reset device", instance, port);
3142 3142
3143 3143 mutex_enter(&ahci_portp->ahciport_mutex);
3144 3144 /*
3145 3145 * software reset request must be sent to SATA_PMULT_HOSTPORT
3146 3146 * if target is a port multiplier:
3147 3147 */
3148 3148 if (sd->satadev_addr.qual == SATA_ADDR_DCPORT &&
3149 3149 ahci_portp->ahciport_device_type == SATA_DTYPE_PMULT)
3150 3150 AHCI_ADDR_SET_PMULT(&addr, port);
3151 3151
3152 3152 if (ahci_portp->ahciport_port_state & SATA_PSTATE_FAILED |
3153 3153 ahci_portp->ahciport_port_state & SATA_PSTATE_SHUTDOWN |
3154 3154 ahci_portp->ahciport_port_state & SATA_PSTATE_PWROFF) {
3155 3155 /*
3156 3156 * In case the targer driver would send the request
3157 3157 * before sata framework can have the opportunity to
3158 3158 * process those event reports.
3159 3159 */
3160 3160 sd->satadev_state = ahci_portp->ahciport_port_state;
3161 3161 ahci_update_sata_registers(ahci_ctlp, port, sd);
3162 3162 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3163 3163 "ahci_tran_reset_dport returning SATA_FAILURE "
3164 3164 "while port in FAILED/SHUTDOWN/PWROFF state: "
3165 3165 "port: %d", port);
3166 3166 mutex_exit(&ahci_portp->ahciport_mutex);
3167 3167 ret = SATA_FAILURE;
3168 3168 break;
3169 3169 }
3170 3170
3171 3171 if (AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr) ==
3172 3172 SATA_DTYPE_NONE) {
3173 3173 /*
3174 3174 * ahci_intr_phyrdy_change() may have rendered it to
3175 3175 * AHCI_PORT_TYPE_NODEV.
3176 3176 */
3177 3177 sd->satadev_type = SATA_DTYPE_NONE;
3178 3178 sd->satadev_state = AHCIPORT_GET_STATE(ahci_portp,
3179 3179 &addr);
3180 3180 ahci_update_sata_registers(ahci_ctlp, port, sd);
3181 3181 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3182 3182 "ahci_tran_reset_dport returning SATA_FAILURE "
3183 3183 "while no device attached: port: %d", port);
3184 3184 mutex_exit(&ahci_portp->ahciport_mutex);
3185 3185 ret = SATA_FAILURE;
3186 3186 break;
3187 3187 }
3188 3188
3189 3189 if (AHCI_ADDR_IS_PORT(&addr)) {
3190 3190 ret = ahci_reset_device_reject_pkts(ahci_ctlp,
3191 3191 ahci_portp, &addr);
3192 3192 } else {
3193 3193 ret = ahci_reset_pmdevice_reject_pkts(ahci_ctlp,
3194 3194 ahci_portp, &addr);
3195 3195 }
3196 3196
3197 3197 mutex_exit(&ahci_portp->ahciport_mutex);
3198 3198 break;
3199 3199
3200 3200 case SATA_ADDR_CNTRL:
3201 3201 /* Reset the whole controller */
3202 3202 cmn_err(CE_NOTE, "!ahci%d: ahci_tran_reset_dport "
3203 3203 "reset the whole hba", instance);
3204 3204 ret = ahci_reset_hba_reject_pkts(ahci_ctlp);
3205 3205 break;
3206 3206
3207 3207 default:
3208 3208 ret = SATA_FAILURE;
3209 3209 }
3210 3210
3211 3211 return (ret);
3212 3212 }
3213 3213
3214 3214 /*
3215 3215 * Called by sata framework to activate a port as part of hotplug.
3216 3216 * (cfgadm -c connect satax/y)
3217 3217 * Support port multiplier.
3218 3218 */
3219 3219 static int
3220 3220 ahci_tran_hotplug_port_activate(dev_info_t *dip, sata_device_t *satadev)
3221 3221 {
3222 3222 ahci_ctl_t *ahci_ctlp;
3223 3223 ahci_port_t *ahci_portp;
3224 3224 ahci_addr_t addr;
3225 3225 uint8_t cport = satadev->satadev_addr.cport;
3226 3226 uint8_t pmport = satadev->satadev_addr.pmport;
3227 3227 uint8_t port;
3228 3228 int instance = ddi_get_instance(dip);
3229 3229
3230 3230 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
3231 3231 port = ahci_ctlp->ahcictl_cport_to_port[cport];
3232 3232
3233 3233 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
3234 3234 "ahci_tran_hotplug_port_activate enter: cport %d", cport);
3235 3235
3236 3236 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3237 3237
3238 3238 mutex_enter(&ahci_portp->ahciport_mutex);
3239 3239 ahci_get_ahci_addr(ahci_ctlp, satadev, &addr);
3240 3240 ASSERT(AHCI_ADDR_IS_PORT(&addr) || AHCI_ADDR_IS_PMPORT(&addr));
3241 3241
3242 3242 if (AHCI_ADDR_IS_PORT(&addr)) {
3243 3243 cmn_err(CE_NOTE, "!ahci%d: ahci port %d is activated",
3244 3244 instance, port);
3245 3245
3246 3246 /* Enable the interrupts on the port */
3247 3247 ahci_enable_port_intrs(ahci_ctlp, port);
3248 3248
3249 3249 /*
3250 3250 * Reset the port so that the PHY communication would be
3251 3251 * re-established. But this reset is an internal operation
3252 3252 * and the sata module doesn't need to know about it.
3253 3253 * Moreover, the port with a device attached will be started
3254 3254 * too.
3255 3255 */
3256 3256 (void) ahci_restart_port_wait_till_ready(ahci_ctlp,
3257 3257 ahci_portp, port,
3258 3258 AHCI_PORT_RESET|AHCI_RESET_NO_EVENTS_UP,
3259 3259 NULL);
3260 3260
3261 3261 /*
3262 3262 * Need to check the link status and device status of the port
3263 3263 * and consider raising power if the port was in D3 state
3264 3264 */
3265 3265 ahci_portp->ahciport_port_state |= SATA_PSTATE_PWRON;
3266 3266 ahci_portp->ahciport_port_state &= ~SATA_PSTATE_PWROFF;
3267 3267 ahci_portp->ahciport_port_state &= ~SATA_PSTATE_SHUTDOWN;
3268 3268 } else if (AHCI_ADDR_IS_PMPORT(&addr)) {
3269 3269 cmn_err(CE_NOTE, "!ahci%d: ahci port %d:%d is activated",
3270 3270 instance, port, pmport);
3271 3271 /* AHCI_ADDR_PMPORT */
3272 3272 AHCIPORT_PMSTATE(ahci_portp, &addr) |= SATA_PSTATE_PWRON;
3273 3273 AHCIPORT_PMSTATE(ahci_portp, &addr) &=
3274 3274 ~(SATA_PSTATE_PWROFF|SATA_PSTATE_SHUTDOWN);
3275 3275 }
3276 3276
3277 3277 satadev->satadev_state = ahci_portp->ahciport_port_state;
3278 3278
3279 3279 ahci_update_sata_registers(ahci_ctlp, port, satadev);
3280 3280
3281 3281 mutex_exit(&ahci_portp->ahciport_mutex);
3282 3282 return (SATA_SUCCESS);
3283 3283 }
3284 3284
3285 3285 /*
3286 3286 * Called by sata framework to deactivate a port as part of hotplug.
3287 3287 * (cfgadm -c disconnect satax/y)
3288 3288 * Support port multiplier.
3289 3289 */
3290 3290 static int
3291 3291 ahci_tran_hotplug_port_deactivate(dev_info_t *dip, sata_device_t *satadev)
3292 3292 {
3293 3293 ahci_ctl_t *ahci_ctlp;
3294 3294 ahci_port_t *ahci_portp;
3295 3295 ahci_addr_t addr;
3296 3296 uint8_t cport = satadev->satadev_addr.cport;
3297 3297 uint8_t pmport = satadev->satadev_addr.pmport;
3298 3298 uint8_t port;
3299 3299 uint32_t port_scontrol;
3300 3300 int instance = ddi_get_instance(dip);
3301 3301
3302 3302 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
3303 3303 port = ahci_ctlp->ahcictl_cport_to_port[cport];
3304 3304
3305 3305 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
3306 3306 "ahci_tran_hotplug_port_deactivate enter: cport %d", cport);
3307 3307
3308 3308 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3309 3309 mutex_enter(&ahci_portp->ahciport_mutex);
3310 3310 ahci_get_ahci_addr(ahci_ctlp, satadev, &addr);
3311 3311 ASSERT(AHCI_ADDR_IS_PORT(&addr) || AHCI_ADDR_IS_PMPORT(&addr));
3312 3312
3313 3313 if (AHCI_ADDR_IS_PORT(&addr)) {
3314 3314 cmn_err(CE_NOTE, "!ahci%d: ahci port %d is deactivated",
3315 3315 instance, port);
3316 3316
3317 3317 /* Disable the interrupts on the port */
3318 3318 ahci_disable_port_intrs(ahci_ctlp, port);
3319 3319
3320 3320 if (ahci_portp->ahciport_device_type != SATA_DTYPE_NONE) {
3321 3321
3322 3322 /* First to abort all the pending commands */
3323 3323 ahci_reject_all_abort_pkts(ahci_ctlp, ahci_portp, port);
3324 3324
3325 3325 /* Then stop the port */
3326 3326 (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
3327 3327 ahci_portp, port);
3328 3328 }
3329 3329
3330 3330 /* Next put the PHY offline */
3331 3331 port_scontrol = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3332 3332 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port));
3333 3333 SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_DISABLE);
3334 3334 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle, (uint32_t *)
3335 3335 AHCI_PORT_PxSCTL(ahci_ctlp, port), port_scontrol);
3336 3336 } else if (AHCI_ADDR_IS_PMPORT(&addr)) {
3337 3337 cmn_err(CE_NOTE, "!ahci%d: ahci port %d:%d is deactivated",
3338 3338 instance, port, pmport);
3339 3339
3340 3340 ahci_disable_port_intrs(ahci_ctlp, port);
3341 3341 if (AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr)
3342 3342 != SATA_DTYPE_NONE)
3343 3343 ahci_reject_all_abort_pkts(ahci_ctlp, ahci_portp, port);
3344 3344
3345 3345 /* Re-enable the interrupts for the other pmports */
3346 3346 ahci_enable_port_intrs(ahci_ctlp, port);
3347 3347 }
3348 3348
3349 3349 /* Update port state */
3350 3350 AHCIPORT_SET_STATE(ahci_portp, &addr, SATA_PSTATE_SHUTDOWN);
3351 3351 satadev->satadev_state = SATA_PSTATE_SHUTDOWN;
3352 3352
3353 3353 ahci_update_sata_registers(ahci_ctlp, port, satadev);
3354 3354
3355 3355 mutex_exit(&ahci_portp->ahciport_mutex);
3356 3356 return (SATA_SUCCESS);
3357 3357 }
3358 3358
3359 3359 /*
3360 3360 * To be used to mark all the outstanding pkts with SATA_PKT_ABORTED
3361 3361 * when a device is unplugged or a port is deactivated.
3362 3362 */
3363 3363 static void
3364 3364 ahci_reject_all_abort_pkts(ahci_ctl_t *ahci_ctlp,
3365 3365 ahci_port_t *ahci_portp, uint8_t port)
3366 3366 {
3367 3367 uint32_t slot_status = 0;
3368 3368 uint32_t abort_tags = 0;
3369 3369
3370 3370 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3371 3371
3372 3372 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
3373 3373 "ahci_reject_all_abort_pkts at port: %d", port);
3374 3374
3375 3375 /* Read/write port multiplier command takes highest priority */
3376 3376 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
3377 3377 slot_status = 0x1;
3378 3378 abort_tags = 0x1;
3379 3379 goto out;
3380 3380 }
3381 3381
3382 3382 /*
3383 3383 * When AHCI_PORT_FLAG_MOPPING is set, we need to check whether a
3384 3384 * REQUEST SENSE command or READ LOG EXT command is delivered to HBA
3385 3385 * to get the error data, if yes when the device is removed, the
3386 3386 * command needs to be aborted too.
3387 3387 */
3388 3388 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
3389 3389 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
3390 3390 slot_status = 0x1;
3391 3391 abort_tags = 0x1;
3392 3392 goto out;
3393 3393 } else {
3394 3394 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3395 3395 "ahci_reject_all_abort_pkts return directly "
3396 3396 "port %d no needs to reject any outstanding "
3397 3397 "commands", port);
3398 3398 return;
3399 3399 }
3400 3400 }
3401 3401
3402 3402 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
3403 3403 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3404 3404 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
3405 3405 abort_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
3406 3406 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
3407 3407 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3408 3408 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
3409 3409 abort_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
3410 3410 }
3411 3411
3412 3412 out:
3413 3413 /* No need to do mop when there is no outstanding commands */
3414 3414 if (slot_status != 0) {
3415 3415 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
3416 3416 ahci_portp->ahciport_mop_in_progress++;
3417 3417
3418 3418 ahci_mop_commands(ahci_ctlp,
3419 3419 ahci_portp,
3420 3420 slot_status,
3421 3421 0, /* failed tags */
3422 3422 0, /* timeout tags */
3423 3423 abort_tags, /* aborting tags */
3424 3424 0); /* reset tags */
3425 3425 }
3426 3426 }
3427 3427
3428 3428 #if defined(__lock_lint)
3429 3429 static int
3430 3430 ahci_selftest(dev_info_t *dip, sata_device_t *device)
3431 3431 {
3432 3432 return (SATA_SUCCESS);
3433 3433 }
3434 3434 #endif
3435 3435
3436 3436 /*
3437 3437 * Initialize fma capabilities and register with IO fault services.
3438 3438 */
3439 3439 static void
3440 3440 ahci_fm_init(ahci_ctl_t *ahci_ctlp)
3441 3441 {
3442 3442 /*
3443 3443 * Need to change iblock to priority for new MSI intr
3444 3444 */
3445 3445 ddi_iblock_cookie_t fm_ibc;
3446 3446
3447 3447 ahci_ctlp->ahcictl_fm_cap = ddi_getprop(DDI_DEV_T_ANY,
3448 3448 ahci_ctlp->ahcictl_dip,
3449 3449 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable",
3450 3450 DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
3451 3451 DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
3452 3452
3453 3453 /* Only register with IO Fault Services if we have some capability */
3454 3454 if (ahci_ctlp->ahcictl_fm_cap) {
3455 3455 /* Adjust access and dma attributes for FMA */
3456 3456 accattr.devacc_attr_access = DDI_FLAGERR_ACC;
3457 3457 buffer_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3458 3458 rcvd_fis_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3459 3459 cmd_list_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3460 3460 cmd_table_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3461 3461
3462 3462 /*
3463 3463 * Register capabilities with IO Fault Services.
3464 3464 * ahcictl_fm_cap will be updated to indicate
3465 3465 * capabilities actually supported (not requested.)
3466 3466 */
3467 3467 ddi_fm_init(ahci_ctlp->ahcictl_dip,
3468 3468 &ahci_ctlp->ahcictl_fm_cap, &fm_ibc);
3469 3469
3470 3470 if (ahci_ctlp->ahcictl_fm_cap == DDI_FM_NOT_CAPABLE) {
3471 3471 cmn_err(CE_WARN, "!ahci%d: fma init failed.",
3472 3472 ddi_get_instance(ahci_ctlp->ahcictl_dip));
3473 3473 return;
3474 3474 }
3475 3475 /*
3476 3476 * Initialize pci ereport capabilities if ereport
3477 3477 * capable (should always be.)
3478 3478 */
3479 3479 if (DDI_FM_EREPORT_CAP(ahci_ctlp->ahcictl_fm_cap) ||
3480 3480 DDI_FM_ERRCB_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3481 3481 pci_ereport_setup(ahci_ctlp->ahcictl_dip);
3482 3482 }
3483 3483
3484 3484 /*
3485 3485 * Register error callback if error callback capable.
3486 3486 */
3487 3487 if (DDI_FM_ERRCB_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3488 3488 ddi_fm_handler_register(ahci_ctlp->ahcictl_dip,
3489 3489 ahci_fm_error_cb, (void *) ahci_ctlp);
3490 3490 }
3491 3491
3492 3492 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3493 3493 "ahci_fm_fini: fma enabled.", NULL);
3494 3494 }
3495 3495 }
3496 3496
3497 3497 /*
3498 3498 * Releases fma capabilities and un-registers with IO fault services.
3499 3499 */
3500 3500 static void
3501 3501 ahci_fm_fini(ahci_ctl_t *ahci_ctlp)
3502 3502 {
3503 3503 /* Only unregister FMA capabilities if registered */
3504 3504 if (ahci_ctlp->ahcictl_fm_cap) {
3505 3505 /*
3506 3506 * Un-register error callback if error callback capable.
3507 3507 */
3508 3508 if (DDI_FM_ERRCB_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3509 3509 ddi_fm_handler_unregister(ahci_ctlp->ahcictl_dip);
3510 3510 }
3511 3511
3512 3512 /*
3513 3513 * Release any resources allocated by pci_ereport_setup()
3514 3514 */
3515 3515 if (DDI_FM_EREPORT_CAP(ahci_ctlp->ahcictl_fm_cap) ||
3516 3516 DDI_FM_ERRCB_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3517 3517 pci_ereport_teardown(ahci_ctlp->ahcictl_dip);
3518 3518 }
3519 3519
3520 3520 /* Unregister from IO Fault Services */
3521 3521 ddi_fm_fini(ahci_ctlp->ahcictl_dip);
3522 3522
3523 3523 /* Adjust access and dma attributes for FMA */
3524 3524 accattr.devacc_attr_access = DDI_DEFAULT_ACC;
3525 3525 buffer_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3526 3526 rcvd_fis_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3527 3527 cmd_list_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3528 3528 cmd_table_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3529 3529
3530 3530 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3531 3531 "ahci_fm_fini: fma disabled.", NULL);
3532 3532 }
3533 3533 }
3534 3534
3535 3535 /*ARGSUSED*/
3536 3536 static int
3537 3537 ahci_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
3538 3538 {
3539 3539 /*
3540 3540 * as the driver can always deal with an error in any dma or
3541 3541 * access handle, we can just return the fme_status value.
3542 3542 */
3543 3543 pci_ereport_post(dip, err, NULL);
3544 3544 return (err->fme_status);
3545 3545 }
3546 3546
3547 3547 int
3548 3548 ahci_check_acc_handle(ddi_acc_handle_t handle)
3549 3549 {
3550 3550 ddi_fm_error_t de;
3551 3551
3552 3552 ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION);
3553 3553 return (de.fme_status);
3554 3554 }
3555 3555
3556 3556 int
3557 3557 ahci_check_dma_handle(ddi_dma_handle_t handle)
3558 3558 {
3559 3559 ddi_fm_error_t de;
3560 3560
3561 3561 ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION);
3562 3562 return (de.fme_status);
3563 3563 }
3564 3564
3565 3565 /*
3566 3566 * Generate an ereport
3567 3567 */
3568 3568 void
3569 3569 ahci_fm_ereport(ahci_ctl_t *ahci_ctlp, char *detail)
3570 3570 {
3571 3571 uint64_t ena;
3572 3572 char buf[FM_MAX_CLASS];
3573 3573
3574 3574 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
3575 3575 ena = fm_ena_generate(0, FM_ENA_FMT1);
3576 3576 if (DDI_FM_EREPORT_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3577 3577 ddi_fm_ereport_post(ahci_ctlp->ahcictl_dip, buf, ena,
3578 3578 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8,
3579 3579 FM_EREPORT_VERSION, NULL);
3580 3580 }
3581 3581 }
3582 3582
3583 3583 /*
3584 3584 * Check if all handles are correctly allocated.
3585 3585 */
3586 3586 static int
3587 3587 ahci_check_all_handle(ahci_ctl_t *ahci_ctlp)
3588 3588 {
3589 3589 int port;
3590 3590
3591 3591 if (ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) {
3592 3592 return (DDI_FAILURE);
3593 3593 }
3594 3594
3595 3595 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3596 3596 ahci_port_t *ahci_portp;
3597 3597
3598 3598 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port))
3599 3599 continue;
3600 3600
3601 3601 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3602 3602
3603 3603 mutex_enter(&ahci_portp->ahciport_mutex);
3604 3604 if (ahci_check_port_handle(ahci_ctlp, port) != DDI_SUCCESS) {
3605 3605 mutex_exit(&ahci_portp->ahciport_mutex);
3606 3606 return (DDI_FAILURE);
3607 3607 }
3608 3608 mutex_exit(&ahci_portp->ahciport_mutex);
3609 3609 }
3610 3610
3611 3611 return (DDI_SUCCESS);
3612 3612 }
3613 3613
3614 3614 /*
3615 3615 * Check the access handles for the controller. Note that
3616 3616 * ahcictl_pci_conf_handle is only used in attach process.
3617 3617 */
3618 3618 static int
3619 3619 ahci_check_ctl_handle(ahci_ctl_t *ahci_ctlp)
3620 3620 {
3621 3621 if ((ahci_check_acc_handle(ahci_ctlp->
3622 3622 ahcictl_pci_conf_handle) != DDI_FM_OK) ||
3623 3623 (ahci_check_acc_handle(ahci_ctlp->
3624 3624 ahcictl_ahci_acc_handle) != DDI_FM_OK)) {
3625 3625 return (DDI_FAILURE);
3626 3626 }
3627 3627 return (DDI_SUCCESS);
3628 3628 }
3629 3629
3630 3630 /*
3631 3631 * Check the DMA handles and the access handles of a controller port.
3632 3632 */
3633 3633 static int
3634 3634 ahci_check_port_handle(ahci_ctl_t *ahci_ctlp, int port)
3635 3635 {
3636 3636 ahci_port_t *ahci_portp = ahci_ctlp->ahcictl_ports[port];
3637 3637 int slot;
3638 3638
3639 3639 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3640 3640
3641 3641 if ((ahci_check_dma_handle(ahci_portp->
3642 3642 ahciport_rcvd_fis_dma_handle) != DDI_FM_OK) ||
3643 3643 (ahci_check_dma_handle(ahci_portp->
3644 3644 ahciport_cmd_list_dma_handle) != DDI_FM_OK) ||
3645 3645 (ahci_check_acc_handle(ahci_portp->
3646 3646 ahciport_rcvd_fis_acc_handle) != DDI_FM_OK) ||
3647 3647 (ahci_check_acc_handle(ahci_portp->
3648 3648 ahciport_cmd_list_acc_handle) != DDI_FM_OK)) {
3649 3649 return (DDI_FAILURE);
3650 3650 }
3651 3651 for (slot = 0; slot < ahci_ctlp->ahcictl_num_cmd_slots; slot++) {
3652 3652 if (ahci_check_slot_handle(ahci_portp, slot)
3653 3653 != DDI_SUCCESS) {
3654 3654 return (DDI_FAILURE);
3655 3655 }
3656 3656 }
3657 3657 return (DDI_SUCCESS);
3658 3658 }
3659 3659
3660 3660 /*
3661 3661 * Check the DMA handles and the access handles of a cmd table slot.
3662 3662 */
3663 3663 static int
3664 3664 ahci_check_slot_handle(ahci_port_t *ahci_portp, int slot)
3665 3665 {
3666 3666 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3667 3667
3668 3668 if ((ahci_check_acc_handle(ahci_portp->
3669 3669 ahciport_cmd_tables_acc_handle[slot]) != DDI_FM_OK) ||
3670 3670 (ahci_check_dma_handle(ahci_portp->
3671 3671 ahciport_cmd_tables_dma_handle[slot]) != DDI_FM_OK)) {
3672 3672 return (DDI_FAILURE);
3673 3673 }
3674 3674 return (DDI_SUCCESS);
3675 3675 }
3676 3676
3677 3677 /*
3678 3678 * Allocate the ports structure, only called by ahci_attach
3679 3679 */
3680 3680 static int
3681 3681 ahci_alloc_ports_state(ahci_ctl_t *ahci_ctlp)
3682 3682 {
3683 3683 int port, cport = 0;
3684 3684
3685 3685 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
3686 3686 "ahci_alloc_ports_state enter", NULL);
3687 3687
3688 3688 mutex_enter(&ahci_ctlp->ahcictl_mutex);
3689 3689
3690 3690 /* Allocate structures only for the implemented ports */
3691 3691 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3692 3692 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3693 3693 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3694 3694 "hba port %d not implemented", port);
3695 3695 continue;
3696 3696 }
3697 3697
3698 3698 ahci_ctlp->ahcictl_cport_to_port[cport] = (uint8_t)port;
3699 3699 ahci_ctlp->ahcictl_port_to_cport[port] =
3700 3700 (uint8_t)cport++;
3701 3701
3702 3702 if (ahci_alloc_port_state(ahci_ctlp, port) != AHCI_SUCCESS) {
3703 3703 goto err_out;
3704 3704 }
3705 3705 }
3706 3706
3707 3707 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3708 3708 return (AHCI_SUCCESS);
3709 3709
3710 3710 err_out:
3711 3711 for (port--; port >= 0; port--) {
3712 3712 if (AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3713 3713 ahci_dealloc_port_state(ahci_ctlp, port);
3714 3714 }
3715 3715 }
3716 3716
3717 3717 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3718 3718 return (AHCI_FAILURE);
3719 3719 }
3720 3720
3721 3721 /*
3722 3722 * Reverse of ahci_alloc_ports_state(), only called by ahci_detach
3723 3723 */
3724 3724 static void
3725 3725 ahci_dealloc_ports_state(ahci_ctl_t *ahci_ctlp)
3726 3726 {
3727 3727 int port;
3728 3728
3729 3729 mutex_enter(&ahci_ctlp->ahcictl_mutex);
3730 3730 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3731 3731 /* if this port is implemented by the HBA */
3732 3732 if (AHCI_PORT_IMPLEMENTED(ahci_ctlp, port))
3733 3733 ahci_dealloc_port_state(ahci_ctlp, port);
3734 3734 }
3735 3735 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3736 3736 }
3737 3737
3738 3738 /*
3739 3739 * Drain the taskq.
3740 3740 */
3741 3741 static void
3742 3742 ahci_drain_ports_taskq(ahci_ctl_t *ahci_ctlp)
3743 3743 {
3744 3744 ahci_port_t *ahci_portp;
3745 3745 int port;
3746 3746
3747 3747 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3748 3748 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3749 3749 continue;
3750 3750 }
3751 3751
3752 3752 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3753 3753
3754 3754 mutex_enter(&ahci_portp->ahciport_mutex);
3755 3755 ddi_taskq_wait(ahci_portp->ahciport_event_taskq);
3756 3756 mutex_exit(&ahci_portp->ahciport_mutex);
3757 3757 }
3758 3758 }
3759 3759
3760 3760 /*
3761 3761 * Initialize the controller and all ports. And then try to start the ports
3762 3762 * if there are devices attached.
3763 3763 *
3764 3764 * This routine can be called from three seperate cases: DDI_ATTACH,
3765 3765 * PM_LEVEL_D0 and DDI_RESUME. The DDI_ATTACH case is different from
3766 3766 * other two cases; device signature probing are attempted only during
3767 3767 * DDI_ATTACH case.
3768 3768 */
3769 3769 static int
3770 3770 ahci_initialize_controller(ahci_ctl_t *ahci_ctlp)
3771 3771 {
3772 3772 ahci_port_t *ahci_portp;
3773 3773 ahci_addr_t addr;
3774 3774 int port;
3775 3775
3776 3776 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
3777 3777 "ahci_initialize_controller enter", NULL);
3778 3778
3779 3779 /* Disable the whole controller interrupts */
3780 3780 mutex_enter(&ahci_ctlp->ahcictl_mutex);
3781 3781 ahci_disable_all_intrs(ahci_ctlp);
3782 3782 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3783 3783
3784 3784 /* Initialize the implemented ports and structures */
3785 3785 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3786 3786 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3787 3787 continue;
3788 3788 }
3789 3789
3790 3790 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3791 3791 mutex_enter(&ahci_portp->ahciport_mutex);
3792 3792
3793 3793 /*
3794 3794 * Ensure that the controller is not in the running state
3795 3795 * by checking every implemented port's PxCMD register
3796 3796 */
3797 3797 AHCI_ADDR_SET_PORT(&addr, (uint8_t)port);
3798 3798
3799 3799 if (ahci_initialize_port(ahci_ctlp, ahci_portp, &addr)
3800 3800 != AHCI_SUCCESS) {
3801 3801 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3802 3802 "ahci_initialize_controller: failed to "
3803 3803 "initialize port %d", port);
3804 3804 /*
3805 3805 * Set the port state to SATA_PSTATE_FAILED if
3806 3806 * failed to initialize it.
3807 3807 */
3808 3808 ahci_portp->ahciport_port_state = SATA_PSTATE_FAILED;
3809 3809 }
3810 3810
3811 3811 mutex_exit(&ahci_portp->ahciport_mutex);
3812 3812 }
3813 3813
3814 3814 /* Enable the whole controller interrupts */
3815 3815 mutex_enter(&ahci_ctlp->ahcictl_mutex);
3816 3816 ahci_enable_all_intrs(ahci_ctlp);
3817 3817 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3818 3818
3819 3819 return (AHCI_SUCCESS);
3820 3820 }
3821 3821
3822 3822 /*
3823 3823 * Reverse of ahci_initialize_controller()
3824 3824 *
3825 3825 * We only need to stop the ports and disable the interrupt.
3826 3826 */
3827 3827 static void
3828 3828 ahci_uninitialize_controller(ahci_ctl_t *ahci_ctlp)
3829 3829 {
3830 3830 ahci_port_t *ahci_portp;
3831 3831 int port;
3832 3832
3833 3833 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3834 3834 "ahci_uninitialize_controller enter", NULL);
3835 3835
3836 3836 /* disable all the interrupts. */
3837 3837 mutex_enter(&ahci_ctlp->ahcictl_mutex);
3838 3838 ahci_disable_all_intrs(ahci_ctlp);
3839 3839 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3840 3840
3841 3841 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3842 3842 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3843 3843 continue;
3844 3844 }
3845 3845
3846 3846 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3847 3847
3848 3848 /* Stop the port by clearing PxCMD.ST */
3849 3849 mutex_enter(&ahci_portp->ahciport_mutex);
3850 3850
3851 3851 /*
3852 3852 * Here we must disable the port interrupt because
3853 3853 * ahci_disable_all_intrs only clear GHC.IE, and IS
3854 3854 * register will be still set if PxIE is enabled.
3855 3855 * When ahci shares one IRQ with other drivers, the
3856 3856 * intr handler may claim the intr mistakenly.
3857 3857 */
3858 3858 ahci_disable_port_intrs(ahci_ctlp, port);
3859 3859 (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
3860 3860 ahci_portp, port);
3861 3861 mutex_exit(&ahci_portp->ahciport_mutex);
3862 3862 }
3863 3863 }
3864 3864
3865 3865 /*
3866 3866 * ahci_alloc_pmult()
3867 3867 * 1. Setting HBA port registers which are necessary for a port multiplier.
3868 3868 * (Set PxCMD.PMA while PxCMD.ST is '0')
3869 3869 * 2. Allocate ahci_pmult_info structure.
3870 3870 *
3871 3871 * NOTE: Must stop port before the function is called.
3872 3872 */
3873 3873 static void
3874 3874 ahci_alloc_pmult(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
3875 3875 {
3876 3876 uint32_t port_cmd_status;
3877 3877 uint8_t port = ahci_portp->ahciport_port_num;
3878 3878
3879 3879 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3880 3880
3881 3881 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3882 3882 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
3883 3883
3884 3884 /* The port must have been stopped before. */
3885 3885 ASSERT(!(port_cmd_status & AHCI_CMD_STATUS_ST));
3886 3886
3887 3887 if (!(port_cmd_status & AHCI_CMD_STATUS_PMA)) {
3888 3888 /* set PMA bit */
3889 3889 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
3890 3890 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
3891 3891 port_cmd_status|AHCI_CMD_STATUS_PMA);
3892 3892
3893 3893 AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
3894 3894 "ahci_alloc_pmult: "
3895 3895 "PxCMD.PMA bit set at port %d.", port);
3896 3896 }
3897 3897
3898 3898 /* Allocate port multiplier information structure */
3899 3899 if (ahci_portp->ahciport_pmult_info == NULL) {
3900 3900 ahci_portp->ahciport_pmult_info = (ahci_pmult_info_t *)
3901 3901 kmem_zalloc(sizeof (ahci_pmult_info_t), KM_SLEEP);
3902 3902 }
3903 3903
3904 3904 ASSERT(ahci_portp->ahciport_pmult_info != NULL);
3905 3905 }
3906 3906
3907 3907 /*
3908 3908 * ahci_dealloc_pmult()
3909 3909 * 1. Clearing related registers when a port multiplier is detached.
3910 3910 * (Clear PxCMD.PMA while PxCMD.ST is '0')
3911 3911 * 2. Deallocate ahci_pmult_info structure.
3912 3912 *
3913 3913 * NOTE: Must stop port before the function is called.
3914 3914 */
3915 3915 static void
3916 3916 ahci_dealloc_pmult(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
3917 3917 {
3918 3918 uint32_t port_cmd_status;
3919 3919 uint8_t port = ahci_portp->ahciport_port_num;
3920 3920
3921 3921 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3922 3922
3923 3923 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3924 3924 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
3925 3925
3926 3926 if (port_cmd_status & AHCI_CMD_STATUS_PMA) {
3927 3927 /* Clear PMA bit */
3928 3928 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
3929 3929 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
3930 3930 (port_cmd_status & (~AHCI_CMD_STATUS_PMA)));
3931 3931
3932 3932 AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
3933 3933 "ahci_dealloc_pmult: "
3934 3934 "PxCMD.PMA bit cleared at port %d.", port);
3935 3935 }
3936 3936
3937 3937 /* Release port multiplier information structure */
3938 3938 if (ahci_portp->ahciport_pmult_info != NULL) {
3939 3939 kmem_free(ahci_portp->ahciport_pmult_info,
3940 3940 sizeof (ahci_pmult_info_t));
3941 3941 ahci_portp->ahciport_pmult_info = NULL;
3942 3942 }
3943 3943 }
3944 3944
3945 3945 /*
3946 3946 * Staggered Spin-up.
3947 3947 */
3948 3948 static void
3949 3949 ahci_staggered_spin_up(ahci_ctl_t *ahci_ctlp, uint8_t port)
3950 3950 {
3951 3951 uint32_t cap_status;
3952 3952 uint32_t port_cmd_status;
3953 3953
3954 3954 ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
3955 3955
3956 3956 cap_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3957 3957 (uint32_t *)AHCI_GLOBAL_CAP(ahci_ctlp));
3958 3958
3959 3959 /* Check for staggered spin-up support */
3960 3960 if (!(cap_status & AHCI_HBA_CAP_SSS))
3961 3961 return;
3962 3962
3963 3963 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3964 3964 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
3965 3965
3966 3966 /* If PxCMD.SUD == 1, no staggered spin-up is needed */
3967 3967 if (port_cmd_status & AHCI_CMD_STATUS_SUD)
3968 3968 return;
3969 3969
3970 3970 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "Spin-up at port %d", port);
3971 3971
3972 3972 /* Set PxCMD.SUD */
3973 3973 port_cmd_status |= AHCI_CMD_STATUS_SUD;
3974 3974 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
3975 3975 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
3976 3976 port_cmd_status);
3977 3977 }
3978 3978
3979 3979 /*
3980 3980 * The routine is to initialize a port. First put the port in NotRunning
3981 3981 * state, then enable port interrupt and clear Serror register. And under
3982 3982 * AHCI_ATTACH case, find device signature and then try to start the port.
3983 3983 *
3984 3984 * Called by
3985 3985 * 1. ahci_initialize_controller
3986 3986 * 2. ahci_intr_phyrdy_change (hotplug)
3987 3987 */
3988 3988 static int
3989 3989 ahci_initialize_port(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
3990 3990 ahci_addr_t *addrp)
3991 3991 {
3992 3992 uint32_t port_sstatus, port_task_file, port_cmd_status;
3993 3993 uint8_t port = addrp->aa_port;
3994 3994 boolean_t resuming = B_TRUE; /* processing DDI_RESUME */
3995 3995 int ret;
3996 3996
3997 3997 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3998 3998
3999 3999 /* AHCI_ADDR_PORT: We've no idea of the attached device here. */
4000 4000 ASSERT(AHCI_ADDR_IS_PORT(addrp));
4001 4001
4002 4002 /*
4003 4003 * At the time being, only probe ports/devices and get the types of
4004 4004 * attached devices during DDI_ATTACH. In fact, the device can be
4005 4005 * changed during power state changes, but at the time being, we
4006 4006 * don't support the situation.
4007 4007 */
4008 4008 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_HOTPLUG) {
4009 4009 resuming = B_FALSE;
4010 4010 } else {
4011 4011 /* check for DDI_RESUME case */
4012 4012 mutex_exit(&ahci_portp->ahciport_mutex);
4013 4013 mutex_enter(&ahci_ctlp->ahcictl_mutex);
4014 4014 if (ahci_ctlp->ahcictl_flags & AHCI_ATTACH)
4015 4015 resuming = B_FALSE;
4016 4016 mutex_exit(&ahci_ctlp->ahcictl_mutex);
4017 4017 mutex_enter(&ahci_portp->ahciport_mutex);
4018 4018 }
4019 4019
4020 4020 if (resuming) {
4021 4021 /*
4022 4022 * During the resume, we need to set the PxCLB, PxCLBU, PxFB
4023 4023 * and PxFBU registers in case these registers were cleared
4024 4024 * during the suspend.
4025 4025 */
4026 4026 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4027 4027 "ahci_initialize_port: port %d "
4028 4028 "set PxCLB, PxCLBU, PxFB and PxFBU "
4029 4029 "during resume", port);
4030 4030
4031 4031 if (ahci_setup_port_base_addresses(ahci_ctlp, ahci_portp) !=
4032 4032 AHCI_SUCCESS)
4033 4033 return (AHCI_FAILURE);
4034 4034 }
4035 4035
4036 4036 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4037 4037 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
4038 4038
4039 4039 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
4040 4040 "ahci_initialize_port: port %d ", port);
4041 4041
4042 4042 /*
4043 4043 * Check whether the port is in NotRunning state, if not,
4044 4044 * put the port in NotRunning state
4045 4045 */
4046 4046 if (port_cmd_status &
4047 4047 (AHCI_CMD_STATUS_ST |
4048 4048 AHCI_CMD_STATUS_CR |
4049 4049 AHCI_CMD_STATUS_FRE |
4050 4050 AHCI_CMD_STATUS_FR)) {
4051 4051 (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
4052 4052 ahci_portp, port);
4053 4053 }
4054 4054
4055 4055 /* Make sure the drive is spun-up */
4056 4056 ahci_staggered_spin_up(ahci_ctlp, port);
4057 4057
4058 4058 /* Disable interrupt */
4059 4059 ahci_disable_port_intrs(ahci_ctlp, port);
4060 4060
4061 4061 /* Device is unknown at first */
4062 4062 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_UNKNOWN);
4063 4063
4064 4064 /* Disable the interface power management */
4065 4065 ahci_disable_interface_pm(ahci_ctlp, port);
4066 4066
4067 4067 port_sstatus = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4068 4068 (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp, port));
4069 4069 port_task_file = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4070 4070 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
4071 4071
4072 4072 /* Check physcial link status */
4073 4073 if (SSTATUS_GET_IPM(port_sstatus) == SSTATUS_IPM_NODEV_NOPHYCOM ||
4074 4074 SSTATUS_GET_DET(port_sstatus) == SSTATUS_DET_DEVPRE_NOPHYCOM ||
4075 4075
4076 4076 /* Check interface status */
4077 4077 port_task_file & AHCI_TFD_STS_BSY ||
4078 4078 port_task_file & AHCI_TFD_STS_DRQ ||
4079 4079
4080 4080 /* Check whether port reset must be executed */
4081 4081 ahci_ctlp->ahcictl_cap & AHCI_CAP_INIT_PORT_RESET ||
4082 4082
4083 4083 /* Always reset port on RESUME */
4084 4084 resuming != B_FALSE) {
4085 4085
4086 4086 /* Something went wrong, we need do some reset things */
4087 4087 ret = ahci_port_reset(ahci_ctlp, ahci_portp, addrp);
4088 4088
4089 4089 /* Does port reset succeed on HBA port? */
4090 4090 if (ret != AHCI_SUCCESS) {
4091 4091 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ERRS, ahci_ctlp,
4092 4092 "ahci_initialize_port:"
4093 4093 "port reset failed at port %d", port);
4094 4094 return (AHCI_FAILURE);
4095 4095 }
4096 4096
4097 4097 /* Is port failed? */
4098 4098 if (AHCIPORT_GET_STATE(ahci_portp, addrp) &
4099 4099 SATA_PSTATE_FAILED) {
4100 4100 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ERRS, ahci_ctlp,
4101 4101 "ahci_initialize_port: port %d state 0x%x",
4102 4102 port, ahci_portp->ahciport_port_state);
4103 4103 return (AHCI_FAILURE);
4104 4104 }
4105 4105 }
4106 4106
4107 4107 AHCIPORT_SET_STATE(ahci_portp, addrp, SATA_STATE_READY);
4108 4108 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "port %d is ready now.", port);
4109 4109
4110 4110 /*
4111 4111 * Try to get the device signature if the port is not empty.
4112 4112 */
4113 4113 if (!resuming && AHCIPORT_DEV_TYPE(ahci_portp, addrp) !=
4114 4114 SATA_DTYPE_NONE)
4115 4115 ahci_find_dev_signature(ahci_ctlp, ahci_portp, addrp);
4116 4116
4117 4117 /* Return directly if no device connected */
4118 4118 if (AHCIPORT_DEV_TYPE(ahci_portp, addrp) == SATA_DTYPE_NONE) {
4119 4119 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4120 4120 "No device connected to port %d", port);
4121 4121 goto out;
4122 4122 }
4123 4123
4124 4124 /* If this is a port multiplier, we need do some initialization */
4125 4125 if (AHCIPORT_DEV_TYPE(ahci_portp, addrp) == SATA_DTYPE_PMULT) {
4126 4126 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4127 4127 "Port multiplier found at port %d", port);
4128 4128 ahci_alloc_pmult(ahci_ctlp, ahci_portp);
4129 4129 }
4130 4130
4131 4131 /* Try to start the port */
4132 4132 if (ahci_start_port(ahci_ctlp, ahci_portp, port)
4133 4133 != AHCI_SUCCESS) {
4134 4134 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4135 4135 "failed to start port %d", port);
4136 4136 return (AHCI_FAILURE);
4137 4137 }
4138 4138 out:
4139 4139 /* Enable port interrupts */
4140 4140 ahci_enable_port_intrs(ahci_ctlp, port);
4141 4141
4142 4142 return (AHCI_SUCCESS);
4143 4143 }
4144 4144
4145 4145 /*
4146 4146 * Handle hardware defect, and check the capabilities. For example,
4147 4147 * power management capabilty and MSI capability.
4148 4148 */
4149 4149 static int
4150 4150 ahci_config_space_init(ahci_ctl_t *ahci_ctlp)
4151 4151 {
4152 4152 ushort_t caps_ptr, cap_count, cap;
4153 4153 #if AHCI_DEBUG
4154 4154 ushort_t pmcap, pmcsr;
4155 4155 ushort_t msimc;
4156 4156 #endif
4157 4157 uint8_t revision;
4158 4158
4159 4159 ahci_ctlp->ahcictl_venid =
4160 4160 pci_config_get16(ahci_ctlp->ahcictl_pci_conf_handle,
4161 4161 PCI_CONF_VENID);
4162 4162
4163 4163 ahci_ctlp->ahcictl_devid =
4164 4164 pci_config_get16(ahci_ctlp->ahcictl_pci_conf_handle,
4165 4165 PCI_CONF_DEVID);
4166 4166
4167 4167 /*
4168 4168 * Modify dma_attr_align of ahcictl_buffer_dma_attr. For VT8251, those
4169 4169 * controllers with 0x00 revision id work on 4-byte aligned buffer,
4170 4170 * which is a bug and was fixed after 0x00 revision id controllers.
4171 4171 *
4172 4172 * Moreover, VT8251 cannot use multiple command slots in the command
4173 4173 * list for non-queued commands because the previous register content
4174 4174 * of PxCI can be re-written in the register write, so a flag will be
4175 4175 * set to record this defect - AHCI_CAP_NO_MCMDLIST_NONQUEUE.
4176 4176 *
4177 4177 * For VT8251, software reset also has the same defect as the below
4178 4178 * AMD/ATI chipset. That is, software reset will get failed if 0xf
4179 4179 * is filled in pmport field. Therefore, another software reset need
4180 4180 * to be done with 0 filled in pmport field.
4181 4181 */
4182 4182 if (ahci_ctlp->ahcictl_venid == VIA_VENID) {
4183 4183 revision = pci_config_get8(ahci_ctlp->ahcictl_pci_conf_handle,
4184 4184 PCI_CONF_REVID);
4185 4185 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4186 4186 "revision id = 0x%x", revision);
4187 4187 if (revision == 0x00) {
4188 4188 ahci_ctlp->ahcictl_buffer_dma_attr.dma_attr_align = 0x4;
4189 4189 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4190 4190 "change ddi_attr_align to 0x4", NULL);
4191 4191 }
4192 4192
4193 4193 ahci_ctlp->ahcictl_cap |= AHCI_CAP_NO_MCMDLIST_NONQUEUE;
4194 4194 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4195 4195 "VT8251 cannot use multiple command lists for "
4196 4196 "non-queued commands", NULL);
4197 4197
4198 4198 ahci_ctlp->ahcictl_cap |= AHCI_CAP_SRST_NO_HOSTPORT;
4199 4199 }
4200 4200
4201 4201 /*
4202 4202 * AMD/ATI SB600 (0x1002,0x4380) AHCI chipset doesn't support 64-bit
4203 4203 * DMA addressing for communication memory descriptors though S64A bit
4204 4204 * of CAP register declares it supports. Even though 64-bit DMA for
4205 4205 * data buffer works on ASUS M2A-VM with newer BIOS, three other
4206 4206 * motherboards are known not, so both AHCI_CAP_BUF_32BIT_DMA and
4207 4207 * AHCI_CAP_COMMU_32BIT_DMA are set for this controller.
4208 4208 *
4209 4209 * Due to certain hardware issue, the chipset must do port reset during
4210 4210 * initialization, otherwise, when retrieving device signature,
4211 4211 * software reset will get time out. So AHCI_CAP_INIT_PORT_RESET flag
4212 4212 * need to set.
4213 4213 *
4214 4214 * For this chipset software reset will get failure if the pmport of
4215 4215 * Register FIS was set with SATA_PMULT_HOSTPORT (0xf) and no port
4216 4216 * multiplier is connected to the port. In order to fix the issue,
4217 4217 * AHCI_CAP_SRST_NO_HOSTPORT flag need to be set, and once software
4218 4218 * reset got failure, the driver will try to do another software reset
4219 4219 * with pmport 0.
4220 4220 */
4221 4221 if (ahci_ctlp->ahcictl_venid == 0x1002 &&
4222 4222 ahci_ctlp->ahcictl_devid == 0x4380) {
4223 4223 ahci_ctlp->ahcictl_cap |= AHCI_CAP_BUF_32BIT_DMA;
4224 4224 ahci_ctlp->ahcictl_cap |= AHCI_CAP_COMMU_32BIT_DMA;
4225 4225 ahci_ctlp->ahcictl_cap |= AHCI_CAP_INIT_PORT_RESET;
4226 4226 ahci_ctlp->ahcictl_cap |= AHCI_CAP_SRST_NO_HOSTPORT;
4227 4227
4228 4228 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4229 4229 "ATI SB600 cannot do 64-bit DMA for both data buffer and "
4230 4230 "communication memory descriptors though CAP indicates "
4231 4231 "support, so force it to use 32-bit DMA", NULL);
4232 4232 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4233 4233 "ATI SB600 need to do a port reset during initialization",
4234 4234 NULL);
4235 4235 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4236 4236 "ATI SB600 will get software reset failure if pmport "
4237 4237 "is set 0xf and no port multiplier is attached", NULL);
4238 4238 }
4239 4239
4240 4240 /*
4241 4241 * AMD/ATI SB700/710/750/800 and SP5100 AHCI chipset share the same
4242 4242 * vendor ID and device ID (0x1002,0x4391).
4243 4243 *
4244 4244 * SB700/750 AHCI chipset on some boards doesn't support 64-bit
4245 4245 * DMA addressing for communication memory descriptors though S64A bit
4246 4246 * of CAP register declares the support. However, it does support
4247 4247 * 64-bit DMA for data buffer. So only AHCI_CAP_COMMU_32BIT_DMA is
4248 4248 * set for this controller.
4249 4249 *
4250 4250 * SB710 has the same initialization issue as SB600, so it also need
4251 4251 * a port reset. That is AHCI_CAP_INIT_PORT_RESET need to set for it.
4252 4252 *
4253 4253 * SB700 also has the same issue about software reset, and thus
4254 4254 * AHCI_CAP_SRST_NO_HOSTPORT flag also is needed.
4255 4255 */
4256 4256 if (ahci_ctlp->ahcictl_venid == 0x1002 &&
4257 4257 ahci_ctlp->ahcictl_devid == 0x4391) {
4258 4258 ahci_ctlp->ahcictl_cap |= AHCI_CAP_COMMU_32BIT_DMA;
4259 4259 ahci_ctlp->ahcictl_cap |= AHCI_CAP_INIT_PORT_RESET;
4260 4260 ahci_ctlp->ahcictl_cap |= AHCI_CAP_SRST_NO_HOSTPORT;
4261 4261
4262 4262 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4263 4263 "ATI SB700/750 cannot do 64-bit DMA for communication "
4264 4264 "memory descriptors though CAP indicates support, "
4265 4265 "so force it to use 32-bit DMA", NULL);
4266 4266 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4267 4267 "ATI SB710 need to do a port reset during initialization",
4268 4268 NULL);
4269 4269 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4270 4270 "ATI SB700 will get software reset failure if pmport "
4271 4271 "is set 0xf and no port multiplier is attached", NULL);
4272 4272 }
4273 4273
4274 4274 /*
4275 4275 * Check if capabilities list is supported and if so,
4276 4276 * get initial capabilities pointer and clear bits 0,1.
4277 4277 */
4278 4278 if (pci_config_get16(ahci_ctlp->ahcictl_pci_conf_handle,
4279 4279 PCI_CONF_STAT) & PCI_STAT_CAP) {
4280 4280 caps_ptr = P2ALIGN(pci_config_get8(
4281 4281 ahci_ctlp->ahcictl_pci_conf_handle,
4282 4282 PCI_CONF_CAP_PTR), 4);
4283 4283 } else {
4284 4284 caps_ptr = PCI_CAP_NEXT_PTR_NULL;
4285 4285 }
4286 4286
4287 4287 /*
4288 4288 * Walk capabilities if supported.
4289 4289 */
4290 4290 for (cap_count = 0; caps_ptr != PCI_CAP_NEXT_PTR_NULL; ) {
4291 4291
4292 4292 /*
4293 4293 * Check that we haven't exceeded the maximum number of
4294 4294 * capabilities and that the pointer is in a valid range.
4295 4295 */
4296 4296 if (++cap_count > PCI_CAP_MAX_PTR) {
4297 4297 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
4298 4298 "too many device capabilities", NULL);
4299 4299 return (AHCI_FAILURE);
4300 4300 }
4301 4301 if (caps_ptr < PCI_CAP_PTR_OFF) {
4302 4302 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
4303 4303 "capabilities pointer 0x%x out of range",
4304 4304 caps_ptr);
4305 4305 return (AHCI_FAILURE);
4306 4306 }
4307 4307
4308 4308 /*
4309 4309 * Get next capability and check that it is valid.
4310 4310 * For now, we only support power management.
4311 4311 */
4312 4312 cap = pci_config_get8(ahci_ctlp->ahcictl_pci_conf_handle,
4313 4313 caps_ptr);
4314 4314 switch (cap) {
4315 4315 case PCI_CAP_ID_PM:
4316 4316
4317 4317 /* power management supported */
4318 4318 ahci_ctlp->ahcictl_cap |= AHCI_CAP_PM;
4319 4319
4320 4320 /* Save PMCSR offset */
4321 4321 ahci_ctlp->ahcictl_pmcsr_offset = caps_ptr + PCI_PMCSR;
4322 4322
4323 4323 #if AHCI_DEBUG
4324 4324 pmcap = pci_config_get16(
4325 4325 ahci_ctlp->ahcictl_pci_conf_handle,
4326 4326 caps_ptr + PCI_PMCAP);
4327 4327 pmcsr = pci_config_get16(
4328 4328 ahci_ctlp->ahcictl_pci_conf_handle,
4329 4329 ahci_ctlp->ahcictl_pmcsr_offset);
4330 4330 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4331 4331 "Power Management capability found PCI_PMCAP "
4332 4332 "= 0x%x PCI_PMCSR = 0x%x", pmcap, pmcsr);
4333 4333 if ((pmcap & 0x3) == 0x3)
4334 4334 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4335 4335 "PCI Power Management Interface "
4336 4336 "spec 1.2 compliant", NULL);
4337 4337 #endif
4338 4338 break;
4339 4339
4340 4340 case PCI_CAP_ID_MSI:
4341 4341 #if AHCI_DEBUG
4342 4342 msimc = pci_config_get16(
4343 4343 ahci_ctlp->ahcictl_pci_conf_handle,
4344 4344 caps_ptr + PCI_MSI_CTRL);
4345 4345 AHCIDBG(AHCIDBG_MSI, ahci_ctlp,
4346 4346 "Message Signaled Interrupt capability found "
4347 4347 "MSICAP_MC.MMC = 0x%x", (msimc & 0xe) >> 1);
4348 4348 #endif
4349 4349 AHCIDBG(AHCIDBG_MSI, ahci_ctlp,
4350 4350 "MSI capability found", NULL);
4351 4351 break;
4352 4352
4353 4353 case PCI_CAP_ID_PCIX:
4354 4354 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4355 4355 "PCI-X capability found", NULL);
4356 4356 break;
4357 4357
4358 4358 case PCI_CAP_ID_PCI_E:
4359 4359 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4360 4360 "PCI Express capability found", NULL);
4361 4361 break;
4362 4362
4363 4363 case PCI_CAP_ID_MSI_X:
4364 4364 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4365 4365 "MSI-X capability found", NULL);
4366 4366 break;
4367 4367
4368 4368 case PCI_CAP_ID_SATA:
4369 4369 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4370 4370 "SATA capability found", NULL);
4371 4371 break;
4372 4372
4373 4373 case PCI_CAP_ID_VS:
4374 4374 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4375 4375 "Vendor Specific capability found", NULL);
4376 4376 break;
4377 4377
4378 4378 default:
4379 4379 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4380 4380 "unrecognized capability 0x%x", cap);
4381 4381 break;
4382 4382 }
4383 4383
4384 4384 /*
4385 4385 * Get next capabilities pointer and clear bits 0,1.
4386 4386 */
4387 4387 caps_ptr = P2ALIGN(pci_config_get8(
4388 4388 ahci_ctlp->ahcictl_pci_conf_handle,
4389 4389 (caps_ptr + PCI_CAP_NEXT_PTR)), 4);
4390 4390 }
4391 4391
4392 4392 return (AHCI_SUCCESS);
4393 4393 }
4394 4394
4395 4395 /*
4396 4396 * Read/Write a register at port multiplier by SATA READ PORTMULT / SATA WRITE
4397 4397 * PORTMULT command. SYNC & POLLING mode is used.
4398 4398 */
4399 4399 static int
4400 4400 ahci_rdwr_pmult(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4401 4401 uint8_t regn, uint32_t *pregv, uint8_t type)
4402 4402 {
4403 4403 ahci_port_t *ahci_portp;
4404 4404 ahci_addr_t pmult_addr;
4405 4405 sata_pkt_t *spkt;
4406 4406 sata_cmd_t *scmd;
4407 4407 sata_device_t sata_device;
4408 4408 uint8_t port = addrp->aa_port;
4409 4409 uint8_t pmport = addrp->aa_pmport;
4410 4410 uint8_t cport;
4411 4411 uint32_t intr_mask;
4412 4412 int rval;
4413 4413 char portstr[10];
4414 4414
4415 4415 SET_PORTSTR(portstr, addrp);
4416 4416 cport = ahci_ctlp->ahcictl_port_to_cport[port];
4417 4417 ahci_portp = ahci_ctlp->ahcictl_ports[port];
4418 4418
4419 4419 ASSERT(AHCI_ADDR_IS_PMPORT(addrp) || AHCI_ADDR_IS_PMULT(addrp));
4420 4420 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4421 4421
4422 4422 /* Check the existence of the port multiplier */
4423 4423 if (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT)
4424 4424 return (AHCI_FAILURE);
4425 4425
4426 4426 /* Request a READ/WRITE PORTMULT sata packet. */
4427 4427 bzero(&sata_device, sizeof (sata_device_t));
4428 4428 sata_device.satadev_addr.cport = cport;
4429 4429 sata_device.satadev_addr.pmport = pmport;
4430 4430 sata_device.satadev_addr.qual = SATA_ADDR_PMULT;
4431 4431 sata_device.satadev_rev = SATA_DEVICE_REV;
4432 4432
4433 4433 /*
4434 4434 * Make sure no command is outstanding here. All R/W PMULT requests
4435 4435 * come from
4436 4436 *
4437 4437 * 1. ahci_attach()
4438 4438 * The port should be empty.
4439 4439 *
4440 4440 * 2. ahci_tran_probe_port()
4441 4441 * Any request from SATA framework (via ahci_tran_start) should be
4442 4442 * rejected if R/W PMULT command is outstanding.
4443 4443 *
4444 4444 * If we are doing mopping, do not check those flags because no
4445 4445 * command will be actually outstanding.
4446 4446 *
4447 4447 * If the port has been occupied by any other commands, the probe
4448 4448 * function will return a SATA_RETRY. SATA framework will retry
4449 4449 * later.
4450 4450 */
4451 4451 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
4452 4452 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4453 4453 "R/W PMULT failed: R/W PMULT in progress at port %d.",
4454 4454 port, ahci_portp->ahciport_flags);
4455 4455 return (AHCI_FAILURE);
4456 4456 }
4457 4457
4458 4458 if (!(ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) && (
4459 4459 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) ||
4460 4460 NCQ_CMD_IN_PROGRESS(ahci_portp) ||
4461 4461 NON_NCQ_CMD_IN_PROGRESS(ahci_portp))) {
4462 4462 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4463 4463 "R/W PMULT failed: port %d is occupied (flags 0x%x).",
4464 4464 port, ahci_portp->ahciport_flags);
4465 4465 return (AHCI_FAILURE);
4466 4466 }
4467 4467
4468 4468 /*
4469 4469 * The port multiplier is gone. This may happen when
4470 4470 * 1. Cutting off the power of an enclosure. The device lose the power
4471 4471 * before port multiplier.
4472 4472 * 2. Disconnecting the port multiplier during hot-plugging a sub-drive.
4473 4473 *
4474 4474 * The issued command should be aborted and the following command
4475 4475 * should not be continued.
4476 4476 */
4477 4477 if (!(ahci_portp->ahciport_port_state & SATA_STATE_READY)) {
4478 4478 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4479 4479 "READ/WRITE PMULT failed: "
4480 4480 "port-mult is removed from port %d", port);
4481 4481 return (AHCI_FAILURE);
4482 4482 }
4483 4483
4484 4484 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_RDWR_PMULT;
4485 4485
4486 4486 spkt = sata_get_rdwr_pmult_pkt(ahci_ctlp->ahcictl_dip,
4487 4487 &sata_device, regn, *pregv, type);
4488 4488
4489 4489 /*
4490 4490 * READ/WRITE PORTMULT command is intended to sent to the control port
4491 4491 * of the port multiplier.
4492 4492 */
4493 4493 AHCI_ADDR_SET_PMULT(&pmult_addr, addrp->aa_port);
4494 4494
4495 4495 ahci_portp->ahciport_rdwr_pmult_pkt = spkt;
4496 4496
4497 4497 /* No interrupt here. Store the interrupt enable mask. */
4498 4498 intr_mask = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4499 4499 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port));
4500 4500 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
4501 4501 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port), 0);
4502 4502
4503 4503 rval = ahci_do_sync_start(ahci_ctlp, ahci_portp, &pmult_addr, spkt);
4504 4504
4505 4505 if (rval == AHCI_SUCCESS &&
4506 4506 spkt->satapkt_reason == SATA_PKT_COMPLETED) {
4507 4507 if (type == SATA_RDWR_PMULT_PKT_TYPE_READ) {
4508 4508 scmd = &spkt->satapkt_cmd;
4509 4509 *pregv = scmd->satacmd_lba_high_lsb << 24 |
4510 4510 scmd->satacmd_lba_mid_lsb << 16 |
4511 4511 scmd->satacmd_lba_low_lsb << 8 |
4512 4512 scmd->satacmd_sec_count_lsb;
4513 4513 }
4514 4514 } else {
4515 4515 /* Failed or not completed. */
4516 4516 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4517 4517 "ahci_rdwr_pmult: cannot [%s] %s[%d] at port %s",
4518 4518 type == SATA_RDWR_PMULT_PKT_TYPE_READ?"Read":"Write",
4519 4519 AHCI_ADDR_IS_PMULT(addrp)?"gscr":"pscr", regn, portstr);
4520 4520 rval = AHCI_FAILURE;
4521 4521 }
4522 4522 out:
4523 4523 /* Restore the interrupt mask */
4524 4524 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
4525 4525 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port), intr_mask);
4526 4526
4527 4527 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_RDWR_PMULT;
4528 4528 ahci_portp->ahciport_rdwr_pmult_pkt = NULL;
4529 4529 sata_free_rdwr_pmult_pkt(spkt);
4530 4530 return (rval);
4531 4531 }
4532 4532
4533 4533 static int
4534 4534 ahci_read_pmult(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4535 4535 uint8_t regn, uint32_t *pregv)
4536 4536 {
4537 4537 return ahci_rdwr_pmult(ahci_ctlp, addrp, regn, pregv,
4538 4538 SATA_RDWR_PMULT_PKT_TYPE_READ);
4539 4539 }
4540 4540
4541 4541 static int
4542 4542 ahci_write_pmult(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4543 4543 uint8_t regn, uint32_t regv)
4544 4544 {
4545 4545 return ahci_rdwr_pmult(ahci_ctlp, addrp, regn, ®v,
4546 4546 SATA_RDWR_PMULT_PKT_TYPE_WRITE);
4547 4547 }
4548 4548
4549 4549 #define READ_PMULT(addrp, r, pv, out) \
4550 4550 if (ahci_read_pmult(ahci_ctlp, addrp, r, pv) != AHCI_SUCCESS) \
4551 4551 goto out;
4552 4552
4553 4553 #define WRITE_PMULT(addrp, r, v, out) \
4554 4554 if (ahci_write_pmult(ahci_ctlp, addrp, r, v) != AHCI_SUCCESS) \
4555 4555 goto out;
4556 4556
4557 4557 /*
4558 4558 * Update sata registers on port multiplier, including GSCR/PSCR registers.
4559 4559 * ahci_update_pmult_gscr()
4560 4560 * ahci_update_pmult_pscr()
4561 4561 */
4562 4562 static int
4563 4563 ahci_update_pmult_gscr(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4564 4564 sata_pmult_gscr_t *sg)
4565 4565 {
4566 4566 ASSERT(MUTEX_HELD(
4567 4567 &ahci_ctlp->ahcictl_ports[addrp->aa_port]->ahciport_mutex));
4568 4568
4569 4569 READ_PMULT(addrp, SATA_PMULT_GSCR0, &sg->gscr0, err);
4570 4570 READ_PMULT(addrp, SATA_PMULT_GSCR1, &sg->gscr1, err);
4571 4571 READ_PMULT(addrp, SATA_PMULT_GSCR2, &sg->gscr2, err);
4572 4572 READ_PMULT(addrp, SATA_PMULT_GSCR64, &sg->gscr64, err);
4573 4573
4574 4574 return (AHCI_SUCCESS);
4575 4575
4576 4576 err: /* R/W PMULT error */
4577 4577 return (AHCI_FAILURE);
4578 4578 }
4579 4579
4580 4580 static int
4581 4581 ahci_update_pmult_pscr(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4582 4582 sata_device_t *sd)
4583 4583 {
4584 4584 ASSERT(AHCI_ADDR_IS_PMPORT(addrp));
4585 4585 ASSERT(MUTEX_HELD(
4586 4586 &ahci_ctlp->ahcictl_ports[addrp->aa_port]->ahciport_mutex));
4587 4587
4588 4588 READ_PMULT(addrp, SATA_PMULT_REG_SSTS, &sd->satadev_scr.sstatus, err);
4589 4589 READ_PMULT(addrp, SATA_PMULT_REG_SERR, &sd->satadev_scr.serror, err);
4590 4590 READ_PMULT(addrp, SATA_PMULT_REG_SCTL, &sd->satadev_scr.scontrol, err);
4591 4591 READ_PMULT(addrp, SATA_PMULT_REG_SACT, &sd->satadev_scr.sactive, err);
4592 4592
4593 4593 return (AHCI_SUCCESS);
4594 4594
4595 4595 err: /* R/W PMULT error */
4596 4596 return (AHCI_FAILURE);
4597 4597 }
4598 4598
4599 4599 /*
4600 4600 * ahci_initialize_pmult()
4601 4601 *
4602 4602 * Initialize a port multiplier, including
4603 4603 * 1. Enable FEATURES register at port multiplier. (SATA Chp.16)
4604 4604 * 2. Redefine MASK register. (SATA Chap 16.?)
4605 4605 */
4606 4606 static int
4607 4607 ahci_initialize_pmult(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
4608 4608 ahci_addr_t *addrp, sata_device_t *sd)
4609 4609 {
4610 4610 sata_pmult_gscr_t sg;
4611 4611 uint32_t gscr64;
4612 4612 uint8_t port = addrp->aa_port;
4613 4613
4614 4614 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4615 4615
4616 4616 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4617 4617 "[Initialize] Port-multiplier at port %d.", port);
4618 4618
4619 4619 /*
4620 4620 * Enable features of port multiplier. Currently only
4621 4621 * Asynchronous Notification is enabled.
4622 4622 */
4623 4623 /* Check gscr64 for supported features. */
4624 4624 READ_PMULT(addrp, SATA_PMULT_GSCR64, &gscr64, err);
4625 4625
4626 4626 if (gscr64 & SATA_PMULT_CAP_SNOTIF) {
4627 4627 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4628 4628 "port %d: Port Multiplier supports "
4629 4629 "Asynchronous Notification.", port);
4630 4630
4631 4631 /* Write to gscr96 to enabled features */
4632 4632 WRITE_PMULT(addrp, SATA_PMULT_GSCR96,
4633 4633 SATA_PMULT_CAP_SNOTIF, err);
4634 4634
4635 4635 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
4636 4636 (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp, port),
4637 4637 AHCI_SNOTIF_CLEAR_ALL);
4638 4638 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4639 4639 "port %d: PMult PxSNTF cleared.", port);
4640 4640
4641 4641 }
4642 4642
4643 4643 /*
4644 4644 * Now we need to update gscr33 register to enable hot-plug interrupt
4645 4645 * for sub devices behind port multiplier.
4646 4646 */
4647 4647 WRITE_PMULT(addrp, SATA_PMULT_GSCR33, (0x1ffff), err);
4648 4648 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4649 4649 "port %d: gscr33 mask set to %x.", port, (0x1ffff));
4650 4650
4651 4651 /*
4652 4652 * Fetch the number of device ports of the port multiplier
4653 4653 */
4654 4654 if (ahci_update_pmult_gscr(ahci_ctlp, addrp, &sg) != AHCI_SUCCESS)
4655 4655 return (AHCI_FAILURE);
4656 4656
4657 4657 /* Register the port multiplier to SATA Framework. */
4658 4658 mutex_exit(&ahci_portp->ahciport_mutex);
4659 4659 sata_register_pmult(ahci_ctlp->ahcictl_dip, sd, &sg);
4660 4660 mutex_enter(&ahci_portp->ahciport_mutex);
4661 4661
4662 4662 ahci_portp->ahciport_pmult_info->ahcipmi_num_dev_ports =
4663 4663 sd->satadev_add_info & SATA_PMULT_PORTNUM_MASK;
4664 4664
4665 4665 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4666 4666 "port %d: pmult sub-port number updated to %x.", port,
4667 4667 ahci_portp->ahciport_pmult_info->ahcipmi_num_dev_ports);
4668 4668
4669 4669 /* Till now port-mult is successfully initialized */
4670 4670 ahci_portp->ahciport_port_state |= SATA_DSTATE_PMULT_INIT;
4671 4671 return (AHCI_SUCCESS);
4672 4672
4673 4673 err: /* R/W PMULT error */
4674 4674 return (AHCI_FAILURE);
4675 4675 }
4676 4676
4677 4677 /*
4678 4678 * Initialize a port multiplier port. According to spec, firstly we need
4679 4679 * issue a COMRESET, then a software reset to get its signature.
4680 4680 *
4681 4681 * NOTE: This function should only be called in ahci_probe_pmport()
4682 4682 */
4683 4683 static int
4684 4684 ahci_initialize_pmport(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
4685 4685 ahci_addr_t *addrp)
4686 4686 {
4687 4687 uint32_t finished_tags = 0, reset_tags = 0, slot_status = 0;
4688 4688 uint8_t port = addrp->aa_port;
4689 4689 uint8_t pmport = addrp->aa_pmport;
4690 4690 int ret = AHCI_FAILURE;
4691 4691
4692 4692 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4693 4693 ASSERT(AHCI_ADDR_IS_PMPORT(addrp));
4694 4694
4695 4695 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
4696 4696 "ahci_initialize_pmport: port %d:%d", port, pmport);
4697 4697
4698 4698 /* Check HBA port state */
4699 4699 if (ahci_portp->ahciport_port_state & SATA_PSTATE_FAILED) {
4700 4700 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ERRS, ahci_ctlp,
4701 4701 "ahci_initialize_pmport:"
4702 4702 "port %d:%d Port Multiplier is failed.",
4703 4703 port, pmport);
4704 4704 return (AHCI_FAILURE);
4705 4705 }
4706 4706
4707 4707 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_HOTPLUG) {
4708 4708 return (AHCI_FAILURE);
4709 4709 }
4710 4710 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_HOTPLUG;
4711 4711
4712 4712 /* Checking for outstanding commands */
4713 4713 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
4714 4714 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4715 4715 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
4716 4716 reset_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
4717 4717 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
4718 4718 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4719 4719 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
4720 4720 reset_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
4721 4721 }
4722 4722
4723 4723 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
4724 4724 ahci_portp->ahciport_mop_in_progress++;
4725 4725
4726 4726 /* Clear status */
4727 4727 AHCIPORT_SET_STATE(ahci_portp, addrp, SATA_STATE_UNKNOWN);
4728 4728
4729 4729 /* Firstly assume an unknown device */
4730 4730 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_UNKNOWN);
4731 4731
4732 4732 ahci_disable_port_intrs(ahci_ctlp, port);
4733 4733
4734 4734 /* port reset is necessary for port multiplier port */
4735 4735 if (ahci_pmport_reset(ahci_ctlp, ahci_portp, addrp) != AHCI_SUCCESS) {
4736 4736 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ERRS, ahci_ctlp,
4737 4737 "ahci_initialize_pmport:"
4738 4738 "port reset failed at port %d:%d",
4739 4739 port, pmport);
4740 4740 goto out;
4741 4741 }
4742 4742
4743 4743 /* Is port failed? */
4744 4744 if (AHCIPORT_GET_STATE(ahci_portp, addrp) &
4745 4745 SATA_PSTATE_FAILED) {
4746 4746 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
4747 4747 "ahci_initialize_pmport: port %d:%d failed. "
4748 4748 "state = 0x%x", port, pmport,
4749 4749 ahci_portp->ahciport_port_state);
4750 4750 goto out;
4751 4751 }
4752 4752
4753 4753 /* Is there any device attached? */
4754 4754 if (AHCIPORT_GET_DEV_TYPE(ahci_portp, addrp)
4755 4755 == SATA_DTYPE_NONE) {
4756 4756 /* Do not waste time on an empty port */
4757 4757 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
4758 4758 "ahci_initialize_pmport: No device is found "
4759 4759 "at port %d:%d", port, pmport);
4760 4760 ret = AHCI_SUCCESS;
4761 4761 goto out;
4762 4762 }
4763 4763
4764 4764 AHCIPORT_SET_STATE(ahci_portp, addrp, SATA_STATE_READY);
4765 4765 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4766 4766 "port %d:%d is ready now.", port, pmport);
4767 4767
4768 4768 /*
4769 4769 * Till now we can assure a device attached to that HBA port and work
4770 4770 * correctly. Now try to get the device signature. This is an optional
4771 4771 * step. If failed, unknown device is assumed, then SATA module will
4772 4772 * continue to use IDENTIFY DEVICE to get the information of the
4773 4773 * device.
4774 4774 */
4775 4775 ahci_find_dev_signature(ahci_ctlp, ahci_portp, addrp);
4776 4776
4777 4777 ret = AHCI_SUCCESS;
4778 4778
4779 4779 out:
4780 4780 /* Next try to mop the pending commands */
4781 4781 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
4782 4782 finished_tags = ahci_portp->ahciport_pending_tags &
4783 4783 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
4784 4784 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
4785 4785 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
4786 4786 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
4787 4787 reset_tags &= ~finished_tags;
4788 4788
4789 4789 ahci_mop_commands(ahci_ctlp,
4790 4790 ahci_portp,
4791 4791 slot_status,
4792 4792 0, /* failed tags */
4793 4793 0, /* timeout tags */
4794 4794 0, /* aborted tags */
4795 4795 reset_tags); /* reset tags */
4796 4796
4797 4797 /* Clear PxSNTF register if supported. */
4798 4798 if (ahci_ctlp->ahcictl_cap & AHCI_CAP_SNTF) {
4799 4799 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
4800 4800 (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp, port),
4801 4801 AHCI_SNOTIF_CLEAR_ALL);
4802 4802 }
4803 4803
4804 4804 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_HOTPLUG;
4805 4805 ahci_enable_port_intrs(ahci_ctlp, port);
4806 4806 return (ret);
4807 4807 }
4808 4808
4809 4809 /*
4810 4810 * ahci_probe_pmult()
4811 4811 *
4812 4812 * This function will be called to probe a port multiplier, which will
4813 4813 * handle hotplug events on port multiplier ports.
4814 4814 *
4815 4815 * NOTE: Only called from ahci_tran_probe_port()
4816 4816 */
4817 4817 static int
4818 4818 ahci_probe_pmult(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
4819 4819 ahci_addr_t *addrp)
4820 4820 {
4821 4821 sata_device_t sdevice;
4822 4822 ahci_addr_t pmport_addr;
4823 4823 uint32_t gscr32, port_hotplug_tags;
4824 4824 uint32_t pmport_sstatus;
4825 4825 int dev_exists_now = 0, dev_existed_previously = 0;
4826 4826 uint8_t port = addrp->aa_port;
4827 4827 int npmport;
4828 4828
4829 4829 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4830 4830
4831 4831 /* The bits in GSCR32 refers to the pmport that has a hot-plug event. */
4832 4832 READ_PMULT(addrp, SATA_PMULT_GSCR32, &gscr32, err);
4833 4833 port_hotplug_tags = gscr32 & AHCI_PMPORT_MASK(ahci_portp);
4834 4834
4835 4835 do {
4836 4836 npmport = ddi_ffs(port_hotplug_tags) - 1;
4837 4837 if (npmport == -1)
4838 4838 /* no pending hot plug events. */
4839 4839 return (AHCI_SUCCESS);
4840 4840
4841 4841 AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4842 4842 "hot-plug event at port %d:%d", port, npmport);
4843 4843
4844 4844 AHCI_ADDR_SET_PMPORT(&pmport_addr, port, (uint8_t)npmport);
4845 4845
4846 4846 /* Check previous device at that port */
4847 4847 if (AHCIPORT_GET_DEV_TYPE(ahci_portp, &pmport_addr)
4848 4848 != SATA_DTYPE_NONE)
4849 4849 dev_existed_previously = 1;
4850 4850
4851 4851 /* PxSStatus tells the presence of device. */
4852 4852 READ_PMULT(&pmport_addr, SATA_PMULT_REG_SSTS,
4853 4853 &pmport_sstatus, err);
4854 4854
4855 4855 if (SSTATUS_GET_DET(pmport_sstatus) ==
4856 4856 SSTATUS_DET_DEVPRE_PHYCOM)
4857 4857 dev_exists_now = 1;
4858 4858
4859 4859 /*
4860 4860 * Clear PxSERR is critical. The transition from 0 to 1 will
4861 4861 * emit a FIS which generates an asynchronous notification
4862 4862 * event at controller. If we fail to clear the PxSERR, the
4863 4863 * Async Notif events will no longer be activated on this
4864 4864 * pmport.
4865 4865 */
4866 4866 WRITE_PMULT(&pmport_addr, SATA_PMULT_REG_SERR,
4867 4867 AHCI_SERROR_CLEAR_ALL, err);
4868 4868
4869 4869 bzero((void *)&sdevice, sizeof (sata_device_t));
4870 4870 sdevice.satadev_addr.cport = ahci_ctlp->
4871 4871 ahcictl_port_to_cport[port];
4872 4872 sdevice.satadev_addr.qual = SATA_ADDR_PMPORT;
4873 4873 sdevice.satadev_addr.pmport = (uint8_t)npmport;
4874 4874 sdevice.satadev_state = SATA_PSTATE_PWRON;
4875 4875
4876 4876 AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4877 4877 "[Existence] %d -> %d", dev_existed_previously,
4878 4878 dev_exists_now);
4879 4879
4880 4880 if (dev_exists_now) {
4881 4881 if (dev_existed_previously) {
4882 4882 /* Link (may) not change: Exist -> Exist * */
4883 4883 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
4884 4884 "ahci_probe_pmult: port %d:%d "
4885 4885 "device link lost/established",
4886 4886 port, npmport);
4887 4887
4888 4888 mutex_exit(&ahci_portp->ahciport_mutex);
4889 4889 sata_hba_event_notify(
4890 4890 ahci_ctlp->ahcictl_sata_hba_tran->
4891 4891 sata_tran_hba_dip,
4892 4892 &sdevice,
4893 4893 SATA_EVNT_LINK_LOST|
4894 4894 SATA_EVNT_LINK_ESTABLISHED);
4895 4895 mutex_enter(&ahci_portp->ahciport_mutex);
4896 4896 } else {
4897 4897 /* Link change: None -> Exist */
4898 4898 AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4899 4899 "ahci_probe_pmult: port %d:%d "
4900 4900 "device link established", port, npmport);
4901 4901
4902 4902 /* Clear port state */
4903 4903 AHCIPORT_SET_STATE(ahci_portp, &pmport_addr,
4904 4904 SATA_STATE_UNKNOWN);
4905 4905 AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4906 4906 "ahci_probe_pmult: port %d "
4907 4907 "ahciport_port_state [Cleared].", port);
4908 4908
4909 4909 mutex_exit(&ahci_portp->ahciport_mutex);
4910 4910 sata_hba_event_notify(
4911 4911 ahci_ctlp->ahcictl_sata_hba_tran->
4912 4912 sata_tran_hba_dip,
4913 4913 &sdevice,
4914 4914 SATA_EVNT_LINK_ESTABLISHED);
4915 4915 mutex_enter(&ahci_portp->ahciport_mutex);
4916 4916 }
4917 4917 } else { /* No device exists now */
4918 4918 if (dev_existed_previously) {
4919 4919
4920 4920 /* Link change: Exist -> None */
4921 4921 AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4922 4922 "ahci_probe_pmult: port %d:%d "
4923 4923 "device link lost", port, npmport);
4924 4924
4925 4925 /* An existing device is lost. */
4926 4926 AHCIPORT_SET_STATE(ahci_portp, &pmport_addr,
4927 4927 SATA_STATE_UNKNOWN);
4928 4928 AHCIPORT_SET_DEV_TYPE(ahci_portp, &pmport_addr,
4929 4929 SATA_DTYPE_NONE);
4930 4930
4931 4931 mutex_exit(&ahci_portp->ahciport_mutex);
4932 4932 sata_hba_event_notify(
4933 4933 ahci_ctlp->ahcictl_sata_hba_tran->
4934 4934 sata_tran_hba_dip,
4935 4935 &sdevice,
4936 4936 SATA_EVNT_LINK_LOST);
4937 4937 mutex_enter(&ahci_portp->ahciport_mutex);
4938 4938 }
4939 4939 }
4940 4940
4941 4941 CLEAR_BIT(port_hotplug_tags, npmport);
4942 4942 } while (port_hotplug_tags != 0);
4943 4943
4944 4944 return (AHCI_SUCCESS);
4945 4945
4946 4946 err: /* R/W PMULT error */
4947 4947 return (AHCI_FAILURE);
4948 4948 }
4949 4949
4950 4950 /*
4951 4951 * Probe and initialize a port multiplier port.
4952 4952 * A port multiplier port could only be initilaizer here.
4953 4953 */
4954 4954 static int
4955 4955 ahci_probe_pmport(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
4956 4956 ahci_addr_t *addrp, sata_device_t *sd)
4957 4957 {
4958 4958 uint32_t port_state;
4959 4959 uint8_t port = addrp->aa_port;
4960 4960 ahci_addr_t addr_pmult;
4961 4961
4962 4962 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4963 4963
4964 4964 /*
4965 4965 * Check the parent - port multiplier first.
4966 4966 */
4967 4967
4968 4968 /*
4969 4969 * Parent port multiplier might have been removed. This event will be
4970 4970 * ignored and failure.
4971 4971 */
4972 4972 if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE ||
4973 4973 ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) {
4974 4974 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4975 4975 "ahci_tran_probe_port: "
4976 4976 "parent device removed, ignore event.", NULL);
4977 4977
4978 4978 return (AHCI_FAILURE);
4979 4979 }
4980 4980
4981 4981 /* The port is ready? */
4982 4982 port_state = ahci_portp->ahciport_port_state;
4983 4983 if (!(port_state & SATA_STATE_READY)) {
4984 4984 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4985 4985 "ahci_tran_probe_port: "
4986 4986 "parent port-mult is NOT ready.", NULL);
4987 4987
4988 4988 if (ahci_restart_port_wait_till_ready(ahci_ctlp,
4989 4989 ahci_portp, port, AHCI_PORT_RESET, NULL) !=
4990 4990 AHCI_SUCCESS) {
4991 4991 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4992 4992 "ahci_tran_probe_port: "
4993 4993 "restart port-mult failed.", NULL);
4994 4994 return (AHCI_FAILURE);
4995 4995 }
4996 4996 }
4997 4997
4998 4998 /*
4999 4999 * If port-mult is restarted due to some reason, we need
5000 5000 * re-initialized the PMult.
5001 5001 */
5002 5002 if (!(port_state & SATA_DSTATE_PMULT_INIT)) {
5003 5003 /* Initialize registers on a port multiplier */
5004 5004 AHCI_ADDR_SET_PMULT(&addr_pmult, addrp->aa_port);
5005 5005 if (ahci_initialize_pmult(ahci_ctlp, ahci_portp,
5006 5006 &addr_pmult, sd) != AHCI_SUCCESS)
5007 5007 return (AHCI_FAILURE);
5008 5008 }
5009 5009
5010 5010 /*
5011 5011 * Then we check the port-mult port
5012 5012 */
5013 5013 /* Is this pmport initialized? */
5014 5014 port_state = AHCIPORT_GET_STATE(ahci_portp, addrp);
5015 5015 if (!(port_state & SATA_STATE_READY)) {
5016 5016
5017 5017 /* ahci_initialize_pmport() will set READY state */
5018 5018 if (ahci_initialize_pmport(ahci_ctlp,
5019 5019 ahci_portp, addrp) != AHCI_SUCCESS)
5020 5020 return (AHCI_FAILURE);
5021 5021 }
5022 5022
5023 5023 return (AHCI_SUCCESS);
5024 5024 }
5025 5025
5026 5026 /*
5027 5027 * AHCI device reset ...; a single device on one of the ports is reset,
5028 5028 * but the HBA and physical communication remain intact. This is the
5029 5029 * least intrusive.
5030 5030 *
5031 5031 * When issuing a software reset sequence, there should not be other
5032 5032 * commands in the command list, so we will first clear and then re-set
5033 5033 * PxCMD.ST to clear PxCI. And before issuing the software reset,
5034 5034 * the port must be idle and PxTFD.STS.BSY and PxTFD.STS.DRQ must be
5035 5035 * cleared unless command list override (PxCMD.CLO) is supported.
5036 5036 */
5037 5037 static int
5038 5038 ahci_software_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
5039 5039 ahci_addr_t *addrp)
5040 5040 {
5041 5041 ahci_fis_h2d_register_t *h2d_register_fisp;
5042 5042 ahci_cmd_table_t *cmd_table;
5043 5043 ahci_cmd_header_t *cmd_header;
5044 5044 uint32_t port_cmd_status, port_cmd_issue, port_task_file;
5045 5045 int slot, loop_count;
5046 5046 uint8_t port = addrp->aa_port;
5047 5047 uint8_t pmport = addrp->aa_pmport;
5048 5048 int rval = AHCI_FAILURE;
5049 5049
5050 5050 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
5051 5051
5052 5052 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
5053 5053 "port %d:%d device software resetting (FIS)", port, pmport);
5054 5054
5055 5055 /* First clear PxCMD.ST (AHCI v1.2 10.4.1) */
5056 5056 if (ahci_put_port_into_notrunning_state(ahci_ctlp, ahci_portp,
5057 5057 port) != AHCI_SUCCESS) {
5058 5058 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5059 5059 "ahci_software_reset: cannot stop HBA port %d.", port);
5060 5060 goto out;
5061 5061 }
5062 5062
5063 5063 /* Check PxTFD.STS.BSY and PxTFD.STS.DRQ */
5064 5064 port_task_file = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5065 5065 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
5066 5066
5067 5067 if (port_task_file & AHCI_TFD_STS_BSY ||
5068 5068 port_task_file & AHCI_TFD_STS_DRQ) {
5069 5069 if (!(ahci_ctlp->ahcictl_cap & AHCI_CAP_SCLO)) {
5070 5070 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5071 5071 "PxTFD.STS.BSY/DRQ is set (PxTFD=0x%x), "
5072 5072 "cannot issue a software reset.", port_task_file);
5073 5073 goto out;
5074 5074 }
5075 5075
5076 5076 /*
5077 5077 * If HBA Support CLO, as Command List Override (CAP.SCLO is
5078 5078 * set), PxCMD.CLO bit should be set before set PxCMD.ST, in
5079 5079 * order to clear PxTFD.STS.BSY and PxTFD.STS.DRQ.
5080 5080 */
5081 5081 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5082 5082 "PxTFD.STS.BSY/DRQ is set, try SCLO.", NULL)
5083 5083
5084 5084 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5085 5085 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5086 5086 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5087 5087 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
5088 5088 port_cmd_status|AHCI_CMD_STATUS_CLO);
5089 5089
5090 5090 /* Waiting till PxCMD.SCLO bit is cleared */
5091 5091 loop_count = 0;
5092 5092 do {
5093 5093 /* Wait for 10 millisec */
5094 5094 drv_usecwait(AHCI_10MS_USECS);
5095 5095
5096 5096 /* We are effectively timing out after 1 sec. */
5097 5097 if (loop_count++ > 100) {
5098 5098 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5099 5099 "SCLO time out. port %d is busy.", port);
5100 5100 goto out;
5101 5101 }
5102 5102
5103 5103 port_cmd_status =
5104 5104 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5105 5105 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5106 5106 } while (port_cmd_status & AHCI_CMD_STATUS_CLO);
5107 5107
5108 5108 /* Re-check */
5109 5109 port_task_file = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5110 5110 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
5111 5111 if (port_task_file & AHCI_TFD_STS_BSY ||
5112 5112 port_task_file & AHCI_TFD_STS_DRQ) {
5113 5113 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5114 5114 "SCLO cannot clear PxTFD.STS.BSY/DRQ (PxTFD=0x%x)",
5115 5115 port_task_file);
5116 5116 goto out;
5117 5117 }
5118 5118 }
5119 5119
5120 5120 /* Then start port */
5121 5121 if (ahci_start_port(ahci_ctlp, ahci_portp, port)
5122 5122 != AHCI_SUCCESS) {
5123 5123 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5124 5124 "ahci_software_reset: cannot start AHCI port %d.", port);
5125 5125 goto out;
5126 5126 }
5127 5127
5128 5128 /*
5129 5129 * When ahci_port.ahciport_mop_in_progress is set, A non-zero
5130 5130 * ahci_port.ahciport_pending_ncq_tags may fail
5131 5131 * ahci_claim_free_slot(). Actually according to spec, by clearing
5132 5132 * PxCMD.ST there is no command outstanding while executing software
5133 5133 * reseting. Hence we directly use slot 0 instead of
5134 5134 * ahci_claim_free_slot().
5135 5135 */
5136 5136 slot = 0;
5137 5137
5138 5138 /* Now send the first H2D Register FIS with SRST set to 1 */
5139 5139 cmd_table = ahci_portp->ahciport_cmd_tables[slot];
5140 5140 bzero((void *)cmd_table, ahci_cmd_table_size);
5141 5141
5142 5142 h2d_register_fisp =
5143 5143 &(cmd_table->ahcict_command_fis.ahcifc_fis.ahcifc_h2d_register);
5144 5144
5145 5145 SET_FIS_TYPE(h2d_register_fisp, AHCI_H2D_REGISTER_FIS_TYPE);
5146 5146 SET_FIS_PMP(h2d_register_fisp, pmport);
5147 5147 SET_FIS_DEVCTL(h2d_register_fisp, SATA_DEVCTL_SRST);
5148 5148
5149 5149 /* Set Command Header in Command List */
5150 5150 cmd_header = &ahci_portp->ahciport_cmd_list[slot];
5151 5151 BZERO_DESCR_INFO(cmd_header);
5152 5152 BZERO_PRD_BYTE_COUNT(cmd_header);
5153 5153 SET_COMMAND_FIS_LENGTH(cmd_header, 5);
5154 5154 SET_PORT_MULTI_PORT(cmd_header, pmport);
5155 5155
5156 5156 SET_CLEAR_BUSY_UPON_R_OK(cmd_header, 1);
5157 5157 SET_RESET(cmd_header, 1);
5158 5158 SET_WRITE(cmd_header, 1);
5159 5159
5160 5160 (void) ddi_dma_sync(ahci_portp->ahciport_cmd_tables_dma_handle[slot],
5161 5161 0,
5162 5162 ahci_cmd_table_size,
5163 5163 DDI_DMA_SYNC_FORDEV);
5164 5164
5165 5165 (void) ddi_dma_sync(ahci_portp->ahciport_cmd_list_dma_handle,
5166 5166 slot * sizeof (ahci_cmd_header_t),
5167 5167 sizeof (ahci_cmd_header_t),
5168 5168 DDI_DMA_SYNC_FORDEV);
5169 5169
5170 5170 /* Indicate to the HBA that a command is active. */
5171 5171 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5172 5172 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port),
5173 5173 (0x1 << slot));
5174 5174
5175 5175 loop_count = 0;
5176 5176
5177 5177 /* Loop till the first command is finished */
5178 5178 do {
5179 5179 port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5180 5180 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
5181 5181
5182 5182 /* We are effectively timing out after 1 sec. */
5183 5183 if (loop_count++ > AHCI_POLLRATE_PORT_SOFTRESET) {
5184 5184 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5185 5185 "the first SRST FIS is timed out, "
5186 5186 "loop_count = %d", loop_count);
5187 5187 goto out;
5188 5188 }
5189 5189 /* Wait for 10 millisec */
5190 5190 drv_usecwait(AHCI_10MS_USECS);
5191 5191 } while (port_cmd_issue & AHCI_SLOT_MASK(ahci_ctlp) & (0x1 << slot));
5192 5192
5193 5193 AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5194 5194 "ahci_software_reset: 1st loop count: %d, "
5195 5195 "port_cmd_issue = 0x%x, slot = 0x%x",
5196 5196 loop_count, port_cmd_issue, slot);
5197 5197
5198 5198 /* According to ATA spec, we need wait at least 5 microsecs here. */
5199 5199 drv_usecwait(AHCI_1MS_USECS);
5200 5200
5201 5201 /* Now send the second H2D Register FIS with SRST cleard to zero */
5202 5202 cmd_table = ahci_portp->ahciport_cmd_tables[slot];
5203 5203 bzero((void *)cmd_table, ahci_cmd_table_size);
5204 5204
5205 5205 h2d_register_fisp =
5206 5206 &(cmd_table->ahcict_command_fis.ahcifc_fis.ahcifc_h2d_register);
5207 5207
5208 5208 SET_FIS_TYPE(h2d_register_fisp, AHCI_H2D_REGISTER_FIS_TYPE);
5209 5209 SET_FIS_PMP(h2d_register_fisp, pmport);
5210 5210
5211 5211 /* Set Command Header in Command List */
5212 5212 cmd_header = &ahci_portp->ahciport_cmd_list[slot];
5213 5213 BZERO_DESCR_INFO(cmd_header);
5214 5214 BZERO_PRD_BYTE_COUNT(cmd_header);
5215 5215 SET_COMMAND_FIS_LENGTH(cmd_header, 5);
5216 5216 SET_PORT_MULTI_PORT(cmd_header, pmport);
5217 5217
5218 5218 SET_WRITE(cmd_header, 1);
5219 5219
5220 5220 (void) ddi_dma_sync(ahci_portp->ahciport_cmd_tables_dma_handle[slot],
5221 5221 0,
5222 5222 ahci_cmd_table_size,
5223 5223 DDI_DMA_SYNC_FORDEV);
5224 5224
5225 5225 (void) ddi_dma_sync(ahci_portp->ahciport_cmd_list_dma_handle,
5226 5226 slot * sizeof (ahci_cmd_header_t),
5227 5227 sizeof (ahci_cmd_header_t),
5228 5228 DDI_DMA_SYNC_FORDEV);
5229 5229
5230 5230 /* Indicate to the HBA that a command is active. */
5231 5231 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5232 5232 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port),
5233 5233 (0x1 << slot));
5234 5234
5235 5235 loop_count = 0;
5236 5236
5237 5237 /* Loop till the second command is finished */
5238 5238 do {
5239 5239 port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5240 5240 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
5241 5241
5242 5242 /* We are effectively timing out after 1 sec. */
5243 5243 if (loop_count++ > AHCI_POLLRATE_PORT_SOFTRESET) {
5244 5244 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5245 5245 "the second SRST FIS is timed out, "
5246 5246 "loop_count = %d", loop_count);
5247 5247 goto out;
5248 5248 }
5249 5249
5250 5250 /* Wait for 10 millisec */
5251 5251 drv_usecwait(AHCI_10MS_USECS);
5252 5252 } while (port_cmd_issue & AHCI_SLOT_MASK(ahci_ctlp) & (0x1 << slot));
5253 5253
5254 5254 AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5255 5255 "ahci_software_reset: 2nd loop count: %d, "
5256 5256 "port_cmd_issue = 0x%x, slot = 0x%x",
5257 5257 loop_count, port_cmd_issue, slot);
5258 5258
5259 5259 if ((ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) ||
5260 5260 (ahci_check_port_handle(ahci_ctlp, port) != DDI_SUCCESS)) {
5261 5261 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
5262 5262 DDI_SERVICE_UNAFFECTED);
5263 5263 goto out;
5264 5264 }
5265 5265
5266 5266 rval = AHCI_SUCCESS;
5267 5267 out:
5268 5268 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5269 5269 "ahci_software_reset: %s at port %d:%d",
5270 5270 rval == AHCI_SUCCESS ? "succeed" : "failed",
5271 5271 port, pmport);
5272 5272
5273 5273 return (rval);
5274 5274 }
5275 5275
5276 5276 /*
5277 5277 * AHCI port reset ...; the physical communication between the HBA and device
5278 5278 * on a port are disabled. This is more intrusive.
5279 5279 *
5280 5280 * When an HBA or port reset occurs, Phy communication is going to
5281 5281 * be re-established with the device through a COMRESET followed by the
5282 5282 * normal out-of-band communication sequence defined in Serial ATA. At
5283 5283 * the end of reset, the device, if working properly, will send a D2H
5284 5284 * Register FIS, which contains the device signature. When the HBA receives
5285 5285 * this FIS, it updates PxTFD.STS and PxTFD.ERR register fields, and updates
5286 5286 * the PxSIG register with the signature.
5287 5287 *
5288 5288 * NOTE: It is expected both PxCMD.ST and PxCMD.CR are cleared before the
5289 5289 * function is called. If not, it is assumed the interface is in hung
5290 5290 * condition.
5291 5291 */
5292 5292 static int
5293 5293 ahci_port_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
5294 5294 ahci_addr_t *addrp)
5295 5295 {
5296 5296 ahci_addr_t pmult_addr;
5297 5297 uint32_t port_cmd_status;
5298 5298 uint32_t port_scontrol, port_sstatus;
5299 5299 uint32_t port_task_file;
5300 5300 uint32_t port_state;
5301 5301 uint8_t port = addrp->aa_port;
5302 5302
5303 5303 int loop_count;
5304 5304 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
5305 5305
5306 5306 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
5307 5307
5308 5308 /* Target is a port multiplier port? */
5309 5309 if (AHCI_ADDR_IS_PMPORT(addrp))
5310 5310 return (ahci_pmport_reset(ahci_ctlp, ahci_portp, addrp));
5311 5311
5312 5312 /* Otherwise it must be an HBA port. */
5313 5313 ASSERT(AHCI_ADDR_IS_PORT(addrp));
5314 5314
5315 5315 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
5316 5316 "Port %d port resetting...", port);
5317 5317 ahci_portp->ahciport_port_state = 0;
5318 5318
5319 5319 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5320 5320 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5321 5321
5322 5322 /*
5323 5323 * According to the spec, SUD bit should be set here,
5324 5324 * but JMicron JMB363 doesn't follow it, so print
5325 5325 * a debug message.
5326 5326 */
5327 5327 if (!(port_cmd_status & AHCI_CMD_STATUS_SUD))
5328 5328 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5329 5329 "ahci_port_reset: port %d SUD bit not set", port);
5330 5330
5331 5331 port_scontrol = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5332 5332 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port));
5333 5333 SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_COMRESET);
5334 5334
5335 5335 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5336 5336 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port),
5337 5337 port_scontrol);
5338 5338
5339 5339 /* Enable PxCMD.FRE to read device */
5340 5340 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5341 5341 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
5342 5342 port_cmd_status|AHCI_CMD_STATUS_FRE);
5343 5343
5344 5344 /*
5345 5345 * The port enters P:StartComm state, and the HBA tells the link layer
5346 5346 * to start communication, which involves sending COMRESET to the
5347 5347 * device. And the HBA resets PxTFD.STS to 7Fh.
5348 5348 *
5349 5349 * Give time for COMRESET to percolate, according to the AHCI
5350 5350 * spec, software shall wait at least 1 millisecond before
5351 5351 * clearing PxSCTL.DET
5352 5352 */
5353 5353 drv_usecwait(AHCI_1MS_USECS * 2);
5354 5354
5355 5355 /* Fetch the SCONTROL again and rewrite the DET part with 0 */
5356 5356 port_scontrol = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5357 5357 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port));
5358 5358 SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_NOACTION);
5359 5359 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5360 5360 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port),
5361 5361 port_scontrol);
5362 5362
5363 5363 /*
5364 5364 * When a COMINIT is received from the device, then the port enters
5365 5365 * P:ComInit state. And HBA sets PxTFD.STS to FFh or 80h. HBA sets
5366 5366 * PxSSTS.DET to 1h to indicate a device is detected but communication
5367 5367 * is not yet established. HBA sets PxSERR.DIAG.X to '1' to indicate
5368 5368 * a COMINIT has been received.
5369 5369 */
5370 5370 /*
5371 5371 * The DET field is valid only if IPM field indicates
5372 5372 * that the interface is in active state.
5373 5373 */
5374 5374 loop_count = 0;
5375 5375 for (;;) {
5376 5376 port_sstatus = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5377 5377 (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp, port));
5378 5378
5379 5379 if (SSTATUS_GET_IPM(port_sstatus) != SSTATUS_IPM_ACTIVE) {
5380 5380 /*
5381 5381 * If the interface is not active, the DET field
5382 5382 * is considered not accurate. So we want to
5383 5383 * continue looping.
5384 5384 */
5385 5385 SSTATUS_SET_DET(port_sstatus, SSTATUS_DET_NODEV);
5386 5386 }
5387 5387
5388 5388 if (SSTATUS_GET_DET(port_sstatus) == SSTATUS_DET_DEVPRE_PHYCOM)
5389 5389 break;
5390 5390
5391 5391 if (loop_count++ > AHCI_POLLRATE_PORT_SSTATUS) {
5392 5392 /*
5393 5393 * We are effectively timing out after 0.1 sec.
5394 5394 */
5395 5395 break;
5396 5396 }
5397 5397
5398 5398 /* Wait for 10 millisec */
5399 5399 drv_usecwait(AHCI_10MS_USECS);
5400 5400 }
5401 5401
5402 5402 AHCIDBG(AHCIDBG_INIT|AHCIDBG_POLL_LOOP, ahci_ctlp,
5403 5403 "ahci_port_reset: 1st loop count: %d, "
5404 5404 "port_sstatus = 0x%x port %d",
5405 5405 loop_count, port_sstatus, port);
5406 5406
5407 5407 if (SSTATUS_GET_DET(port_sstatus) != SSTATUS_DET_DEVPRE_PHYCOM) {
5408 5408 /*
5409 5409 * Either the port is not active or there
5410 5410 * is no device present.
5411 5411 */
5412 5412 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_NONE);
5413 5413 return (AHCI_SUCCESS);
5414 5414 }
5415 5415
5416 5416 /* Clear port serror register for the port */
5417 5417 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5418 5418 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
5419 5419 AHCI_SERROR_CLEAR_ALL);
5420 5420
5421 5421 /*
5422 5422 * Devices should return a FIS contains its signature to HBA after
5423 5423 * COMINIT signal. Check whether a D2H Register FIS is received by
5424 5424 * polling PxTFD.STS.
5425 5425 */
5426 5426 loop_count = 0;
5427 5427 for (;;) {
5428 5428 port_task_file =
5429 5429 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5430 5430 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
5431 5431
5432 5432 if ((port_task_file & (AHCI_TFD_STS_BSY | AHCI_TFD_STS_DRQ |
5433 5433 AHCI_TFD_STS_ERR)) == 0)
5434 5434 break;
5435 5435
5436 5436 if (loop_count++ > AHCI_POLLRATE_PORT_TFD_ERROR) {
5437 5437 /*
5438 5438 * We are effectively timing out after 11 sec.
5439 5439 */
5440 5440 cmn_err(CE_WARN, "!ahci%d: ahci_port_reset port %d "
5441 5441 "the device hardware has been initialized and "
5442 5442 "the power-up diagnostics failed",
5443 5443 instance, port);
5444 5444
5445 5445 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_port_reset: "
5446 5446 "port %d: some or all of BSY, DRQ and ERR in "
5447 5447 "PxTFD.STS are not clear. We need another "
5448 5448 "software reset.", port);
5449 5449
5450 5450 /* Clear port serror register for the port */
5451 5451 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5452 5452 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
5453 5453 AHCI_SERROR_CLEAR_ALL);
5454 5454
5455 5455 AHCI_ADDR_SET_PMULT(&pmult_addr, port);
5456 5456
5457 5457 /* Try another software reset. */
5458 5458 if (ahci_software_reset(ahci_ctlp, ahci_portp,
5459 5459 &pmult_addr) != AHCI_SUCCESS) {
5460 5460 AHCIPORT_SET_STATE(ahci_portp, addrp,
5461 5461 SATA_PSTATE_FAILED);
5462 5462 return (AHCI_FAILURE);
5463 5463 }
5464 5464 break;
5465 5465 }
5466 5466
5467 5467 /* Wait for 10 millisec */
5468 5468 drv_usecwait(AHCI_10MS_USECS);
5469 5469 }
5470 5470
5471 5471 AHCIDBG(AHCIDBG_INIT|AHCIDBG_POLL_LOOP, ahci_ctlp,
5472 5472 "ahci_port_reset: 2nd loop count: %d, "
5473 5473 "port_task_file = 0x%x port %d",
5474 5474 loop_count, port_task_file, port);
5475 5475
5476 5476 /* Clear port serror register for the port */
5477 5477 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5478 5478 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
5479 5479 AHCI_SERROR_CLEAR_ALL);
5480 5480
5481 5481 /* Set port as ready */
5482 5482 port_state = AHCIPORT_GET_STATE(ahci_portp, addrp);
5483 5483 AHCIPORT_SET_STATE(ahci_portp, addrp, port_state|SATA_STATE_READY);
5484 5484
5485 5485 AHCIDBG(AHCIDBG_INFO|AHCIDBG_ERRS, ahci_ctlp,
5486 5486 "ahci_port_reset: succeed at port %d.", port);
5487 5487 return (AHCI_SUCCESS);
5488 5488 }
5489 5489
5490 5490 /*
5491 5491 * COMRESET on a port multiplier port.
5492 5492 *
5493 5493 * NOTE: Only called in ahci_port_reset()
5494 5494 */
5495 5495 static int
5496 5496 ahci_pmport_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
5497 5497 ahci_addr_t *addrp)
5498 5498 {
5499 5499 uint32_t port_scontrol, port_sstatus, port_serror;
5500 5500 uint32_t port_cmd_status, port_intr_status;
5501 5501 uint32_t port_state;
5502 5502 uint8_t port = addrp->aa_port;
5503 5503 uint8_t pmport = addrp->aa_pmport;
5504 5504 int loop_count;
5505 5505 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
5506 5506
5507 5507 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
5508 5508 "port %d:%d: pmport resetting", port, pmport);
5509 5509
5510 5510 /* Initialize pmport state */
5511 5511 AHCIPORT_SET_STATE(ahci_portp, addrp, 0);
5512 5512
5513 5513 READ_PMULT(addrp, SATA_PMULT_REG_SCTL, &port_scontrol, err);
5514 5514 SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_COMRESET);
5515 5515 WRITE_PMULT(addrp, SATA_PMULT_REG_SCTL, port_scontrol, err);
5516 5516
5517 5517 /* PxCMD.FRE should be set before. */
5518 5518 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5519 5519 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5520 5520 ASSERT(port_cmd_status & AHCI_CMD_STATUS_FRE);
5521 5521 if (!(port_cmd_status & AHCI_CMD_STATUS_FRE))
5522 5522 return (AHCI_FAILURE);
5523 5523
5524 5524 /*
5525 5525 * Give time for COMRESET to percolate, according to the AHCI
5526 5526 * spec, software shall wait at least 1 millisecond before
5527 5527 * clearing PxSCTL.DET
5528 5528 */
5529 5529 drv_usecwait(AHCI_1MS_USECS*2);
5530 5530
5531 5531 /*
5532 5532 * Fetch the SCONTROL again and rewrite the DET part with 0
5533 5533 * This will generate an Asychronous Notification events.
5534 5534 */
5535 5535 READ_PMULT(addrp, SATA_PMULT_REG_SCTL, &port_scontrol, err);
5536 5536 SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_NOACTION);
5537 5537 WRITE_PMULT(addrp, SATA_PMULT_REG_SCTL, port_scontrol, err);
5538 5538
5539 5539 /*
5540 5540 * The port enters P:StartComm state, and HBA tells link layer to
5541 5541 * start communication, which involves sending COMRESET to device.
5542 5542 * And the HBA resets PxTFD.STS to 7Fh.
5543 5543 *
5544 5544 * When a COMINIT is received from the device, then the port enters
5545 5545 * P:ComInit state. And HBA sets PxTFD.STS to FFh or 80h. HBA sets
5546 5546 * PxSSTS.DET to 1h to indicate a device is detected but communication
5547 5547 * is not yet established. HBA sets PxSERR.DIAG.X to '1' to indicate
5548 5548 * a COMINIT has been received.
5549 5549 */
5550 5550 /*
5551 5551 * The DET field is valid only if IPM field indicates
5552 5552 * that the interface is in active state.
5553 5553 */
5554 5554 loop_count = 0;
5555 5555 do {
5556 5556 READ_PMULT(addrp, SATA_PMULT_REG_SSTS, &port_sstatus, err);
5557 5557
5558 5558 if (SSTATUS_GET_IPM(port_sstatus) != SSTATUS_IPM_ACTIVE) {
5559 5559 /*
5560 5560 * If the interface is not active, the DET field
5561 5561 * is considered not accurate. So we want to
5562 5562 * continue looping.
5563 5563 */
5564 5564 SSTATUS_SET_DET(port_sstatus, SSTATUS_DET_NODEV);
5565 5565 }
5566 5566
5567 5567 if (loop_count++ > AHCI_POLLRATE_PORT_SSTATUS) {
5568 5568 /*
5569 5569 * We are effectively timing out after 0.1 sec.
5570 5570 */
5571 5571 break;
5572 5572 }
5573 5573
5574 5574 /* Wait for 10 millisec */
5575 5575 drv_usecwait(AHCI_10MS_USECS);
5576 5576
5577 5577 } while (SSTATUS_GET_DET(port_sstatus) != SSTATUS_DET_DEVPRE_PHYCOM);
5578 5578
5579 5579 AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5580 5580 "ahci_pmport_reset: 1st loop count: %d, "
5581 5581 "port_sstatus = 0x%x port %d:%d",
5582 5582 loop_count, port_sstatus, port, pmport);
5583 5583
5584 5584 if ((SSTATUS_GET_IPM(port_sstatus) != SSTATUS_IPM_ACTIVE) ||
5585 5585 (SSTATUS_GET_DET(port_sstatus) != SSTATUS_DET_DEVPRE_PHYCOM)) {
5586 5586 /*
5587 5587 * Either the port is not active or there
5588 5588 * is no device present.
5589 5589 */
5590 5590 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INFO, ahci_ctlp,
5591 5591 "ahci_pmport_reset: "
5592 5592 "no device attached to port %d:%d",
5593 5593 port, pmport);
5594 5594 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_NONE);
5595 5595 return (AHCI_SUCCESS);
5596 5596 }
5597 5597
5598 5598 /* Now we can make sure there is a device connected to the port */
5599 5599 /* COMINIT signal is supposed to be received (PxSERR.DIAG.X = '1') */
5600 5600 READ_PMULT(addrp, SATA_PMULT_REG_SERR, &port_serror, err);
5601 5601
5602 5602 if (!(port_serror & (1 << 26))) {
5603 5603 cmn_err(CE_WARN, "!ahci%d: ahci_pmport_reset: "
5604 5604 "COMINIT signal from the device not received port %d:%d",
5605 5605 instance, port, pmport);
5606 5606
5607 5607 AHCIPORT_SET_STATE(ahci_portp, addrp, SATA_PSTATE_FAILED);
5608 5608 return (AHCI_FAILURE);
5609 5609 }
5610 5610
5611 5611 /*
5612 5612 * After clear PxSERR register, we will receive a D2H FIS.
5613 5613 * Normally this FIS will cause a IPMS error according to AHCI spec
5614 5614 * v1.2 because there is no command outstanding for it. So we need
5615 5615 * to ignore this error.
5616 5616 */
5617 5617 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_IGNORE_IPMS;
5618 5618 WRITE_PMULT(addrp, SATA_PMULT_REG_SERR, AHCI_SERROR_CLEAR_ALL, err);
5619 5619
5620 5620 /* Now we need to check the D2H FIS by checking IPMS error. */
5621 5621 loop_count = 0;
5622 5622 do {
5623 5623 port_intr_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5624 5624 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port));
5625 5625
5626 5626 if (loop_count++ > AHCI_POLLRATE_PORT_TFD_ERROR) {
5627 5627 /*
5628 5628 * No D2H FIS received. This is possible according
5629 5629 * to SATA 2.6 spec.
5630 5630 */
5631 5631 cmn_err(CE_WARN, "ahci_port_reset: port %d:%d "
5632 5632 "PxIS.IPMS is not set, we need another "
5633 5633 "software reset.", port, pmport);
5634 5634
5635 5635 break;
5636 5636 }
5637 5637
5638 5638 /* Wait for 10 millisec */
5639 5639 mutex_exit(&ahci_portp->ahciport_mutex);
5640 5640 delay(AHCI_10MS_TICKS);
5641 5641 mutex_enter(&ahci_portp->ahciport_mutex);
5642 5642
5643 5643 } while (!(port_intr_status & AHCI_INTR_STATUS_IPMS));
5644 5644
5645 5645 AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5646 5646 "ahci_pmport_reset: 2st loop count: %d, "
5647 5647 "port_sstatus = 0x%x port %d:%d",
5648 5648 loop_count, port_sstatus, port, pmport);
5649 5649
5650 5650 /* Clear IPMS */
5651 5651 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5652 5652 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port),
5653 5653 AHCI_INTR_STATUS_IPMS);
5654 5654 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_IGNORE_IPMS;
5655 5655
5656 5656 /* This pmport is now ready for ahci_tran_start() */
5657 5657 port_state = AHCIPORT_GET_STATE(ahci_portp, addrp);
5658 5658 AHCIPORT_SET_STATE(ahci_portp, addrp, port_state|SATA_STATE_READY);
5659 5659
5660 5660 AHCIDBG(AHCIDBG_INFO|AHCIDBG_ERRS, ahci_ctlp,
5661 5661 "ahci_pmport_reset: succeed at port %d:%d", port, pmport);
5662 5662 return (AHCI_SUCCESS);
5663 5663
5664 5664 err: /* R/W PMULT error */
5665 5665 /* IPMS flags might be set before. */
5666 5666 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_IGNORE_IPMS;
5667 5667 AHCIDBG(AHCIDBG_INFO|AHCIDBG_ERRS, ahci_ctlp,
5668 5668 "ahci_pmport_reset: failed at port %d:%d", port, pmport);
5669 5669
5670 5670 return (AHCI_FAILURE);
5671 5671 }
5672 5672
5673 5673 /*
5674 5674 * AHCI HBA reset ...; the entire HBA is reset, and all ports are disabled.
5675 5675 * This is the most intrusive.
5676 5676 *
5677 5677 * When an HBA reset occurs, Phy communication will be re-established with
5678 5678 * the device through a COMRESET followed by the normal out-of-band
5679 5679 * communication sequence defined in Serial ATA. At the end of reset, the
5680 5680 * device, if working properly, will send a D2H Register FIS, which contains
5681 5681 * the device signature. When the HBA receives this FIS, it updates PxTFD.STS
5682 5682 * and PxTFD.ERR register fields, and updates the PxSIG register with the
5683 5683 * signature.
5684 5684 *
5685 5685 * Remember to set GHC.AE to 1 before calling ahci_hba_reset.
5686 5686 */
5687 5687 static int
5688 5688 ahci_hba_reset(ahci_ctl_t *ahci_ctlp)
5689 5689 {
5690 5690 ahci_port_t *ahci_portp;
5691 5691 uint32_t ghc_control;
5692 5692 uint8_t port;
5693 5693 int loop_count;
5694 5694 int rval = AHCI_SUCCESS;
5695 5695
5696 5696 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp, "HBA resetting",
5697 5697 NULL);
5698 5698
5699 5699 mutex_enter(&ahci_ctlp->ahcictl_mutex);
5700 5700
5701 5701 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5702 5702 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
5703 5703
5704 5704 /* Setting GHC.HR to 1, remember GHC.AE is already set to 1 before */
5705 5705 ghc_control |= AHCI_HBA_GHC_HR;
5706 5706 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5707 5707 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
5708 5708
5709 5709 /*
5710 5710 * Wait until HBA Reset complete or timeout
5711 5711 */
5712 5712 loop_count = 0;
5713 5713 do {
5714 5714 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5715 5715 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
5716 5716
5717 5717 if (loop_count++ > AHCI_POLLRATE_HBA_RESET) {
5718 5718 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
5719 5719 "ahci hba reset is timing out, "
5720 5720 "ghc_control = 0x%x", ghc_control);
5721 5721 /* We are effectively timing out after 1 sec. */
5722 5722 break;
5723 5723 }
5724 5724
5725 5725 /* Wait for 10 millisec */
5726 5726 drv_usecwait(AHCI_10MS_USECS);
5727 5727 } while (ghc_control & AHCI_HBA_GHC_HR);
5728 5728
5729 5729 AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5730 5730 "ahci_hba_reset: 1st loop count: %d, "
5731 5731 "ghc_control = 0x%x", loop_count, ghc_control);
5732 5732
5733 5733 if (ghc_control & AHCI_HBA_GHC_HR) {
5734 5734 /* The hba is not reset for some reasons */
5735 5735 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
5736 5736 "hba reset failed: HBA in a hung or locked state", NULL);
5737 5737 mutex_exit(&ahci_ctlp->ahcictl_mutex);
5738 5738 return (AHCI_FAILURE);
5739 5739 }
5740 5740
5741 5741 /*
5742 5742 * HBA reset will clear (AHCI Spec v1.2 10.4.3) GHC.IE / GHC.AE
5743 5743 */
5744 5744 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5745 5745 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
5746 5746 ghc_control |= (AHCI_HBA_GHC_AE | AHCI_HBA_GHC_IE);
5747 5747 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5748 5748 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
5749 5749
5750 5750 mutex_exit(&ahci_ctlp->ahcictl_mutex);
5751 5751
5752 5752 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
5753 5753 /* Only check implemented ports */
5754 5754 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
5755 5755 continue;
5756 5756 }
5757 5757
5758 5758 ahci_portp = ahci_ctlp->ahcictl_ports[port];
5759 5759 mutex_enter(&ahci_portp->ahciport_mutex);
5760 5760
5761 5761 /* Make sure the drive is spun-up */
5762 5762 ahci_staggered_spin_up(ahci_ctlp, port);
5763 5763
5764 5764 if (ahci_restart_port_wait_till_ready(ahci_ctlp, ahci_portp,
5765 5765 port, AHCI_PORT_RESET|AHCI_RESET_NO_EVENTS_UP, NULL) !=
5766 5766 AHCI_SUCCESS) {
5767 5767 rval = AHCI_FAILURE;
5768 5768 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5769 5769 "ahci_hba_reset: port %d failed", port);
5770 5770 /*
5771 5771 * Set the port state to SATA_PSTATE_FAILED if
5772 5772 * failed to initialize it.
5773 5773 */
5774 5774 ahci_portp->ahciport_port_state = SATA_PSTATE_FAILED;
5775 5775 }
5776 5776
5777 5777 mutex_exit(&ahci_portp->ahciport_mutex);
5778 5778 }
5779 5779
5780 5780 return (rval);
5781 5781 }
5782 5782
5783 5783 /*
5784 5784 * This routine is only called from AHCI_ATTACH or phyrdy change
5785 5785 * case. It first calls software reset, then stop the port and try to
5786 5786 * read PxSIG register to find the type of device attached to the port.
5787 5787 *
5788 5788 * The caller should make sure a valid device exists on specified port and
5789 5789 * physical communication has been established so that the signature could
5790 5790 * be retrieved by software reset.
5791 5791 *
5792 5792 * NOTE: The port interrupts should be disabled before the function is called.
5793 5793 */
5794 5794 static void
5795 5795 ahci_find_dev_signature(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
5796 5796 ahci_addr_t *addrp)
5797 5797 {
5798 5798 ahci_addr_t dev_addr;
5799 5799 uint32_t signature;
5800 5800 uint8_t port = addrp->aa_port;
5801 5801 uint8_t pmport = addrp->aa_pmport;
5802 5802 int rval;
5803 5803
5804 5804 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
5805 5805 ASSERT(AHCI_ADDR_IS_VALID(addrp));
5806 5806
5807 5807 /*
5808 5808 * If the HBA doesn't support port multiplier, then the driver
5809 5809 * doesn't need to bother to check port multiplier device.
5810 5810 *
5811 5811 * The second port of ICH7 on ASUS P5W DH deluxe motherboard is
5812 5812 * connected to Silicon Image 4723, to which the two sata drives
5813 5813 * attached can be set with RAID1, RAID0 or Spanning mode.
5814 5814 *
5815 5815 * We found software reset will get failure if port multiplier address
5816 5816 * 0xf is used by software reset, so just ignore the check since
5817 5817 * ICH7 doesn't support port multiplier device at all.
5818 5818 */
5819 5819 if (AHCI_ADDR_IS_PORT(addrp) &&
5820 5820 (ahci_ctlp->ahcictl_cap & AHCI_CAP_PMULT_CBSS)) {
5821 5821 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
5822 5822 "ahci_find_dev_signature enter: port %d", port);
5823 5823
5824 5824 /*
5825 5825 * NOTE: when the ahci address is a HBA port, we do not know
5826 5826 * it is a device or a port multiplier that attached. we need
5827 5827 * try a software reset at port multiplier address (0xf
5828 5828 * pmport)
5829 5829 */
5830 5830 AHCI_ADDR_SET_PMULT(&dev_addr, addrp->aa_port);
5831 5831 } else {
5832 5832 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
5833 5833 "ahci_find_dev_signature enter: port %d:%d",
5834 5834 port, pmport);
5835 5835 dev_addr = *addrp;
5836 5836 }
5837 5837
5838 5838 /* Assume it is unknown. */
5839 5839 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_UNKNOWN);
5840 5840
5841 5841 /* Issue a software reset to get the signature */
5842 5842 rval = ahci_software_reset(ahci_ctlp, ahci_portp, &dev_addr);
5843 5843 if (rval != AHCI_SUCCESS) {
5844 5844
5845 5845 /*
5846 5846 * Try to do software reset again with pmport set with 0 if
5847 5847 * the controller is set with AHCI_CAP_SRST_NO_HOSTPORT and
5848 5848 * the original pmport is set with SATA_PMULT_HOSTPORT (0xf)
5849 5849 */
5850 5850 if ((ahci_ctlp->ahcictl_cap & AHCI_CAP_SRST_NO_HOSTPORT) &&
5851 5851 (dev_addr.aa_pmport == SATA_PMULT_HOSTPORT)) {
5852 5852 dev_addr.aa_pmport = 0;
5853 5853 rval = ahci_software_reset(ahci_ctlp, ahci_portp,
5854 5854 &dev_addr);
5855 5855 }
5856 5856
5857 5857 if (rval != AHCI_SUCCESS) {
5858 5858 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5859 5859 "ahci_find_dev_signature: software reset failed "
5860 5860 "at port %d:%d, cannot get signature.",
5861 5861 port, pmport);
5862 5862
5863 5863 AHCIPORT_SET_STATE(ahci_portp, addrp,
5864 5864 SATA_PSTATE_FAILED);
5865 5865 return;
5866 5866 }
5867 5867 }
5868 5868
5869 5869 /*
5870 5870 * ahci_software_reset has started the port, so we need manually stop
5871 5871 * the port again.
5872 5872 */
5873 5873 if (AHCI_ADDR_IS_PORT(addrp)) {
5874 5874 if (ahci_put_port_into_notrunning_state(ahci_ctlp,
5875 5875 ahci_portp, port) != AHCI_SUCCESS) {
5876 5876 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5877 5877 "ahci_find_dev_signature: cannot stop port %d.",
5878 5878 port);
5879 5879 ahci_portp->ahciport_port_state = SATA_PSTATE_FAILED;
5880 5880 return;
5881 5881 }
5882 5882 }
5883 5883
5884 5884 /* Now we can make sure that a valid signature is received. */
5885 5885 signature = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5886 5886 (uint32_t *)AHCI_PORT_PxSIG(ahci_ctlp, port));
5887 5887
5888 5888 if (AHCI_ADDR_IS_PMPORT(addrp)) {
5889 5889 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
5890 5890 "ahci_find_dev_signature: signature = 0x%x at port %d:%d",
5891 5891 signature, port, pmport);
5892 5892 } else {
5893 5893 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INFO, ahci_ctlp,
5894 5894 "ahci_find_dev_signature: signature = 0x%x at port %d",
5895 5895 signature, port);
5896 5896 }
5897 5897
5898 5898 /* NOTE: Only support ATAPI device at controller port. */
5899 5899 if (signature == AHCI_SIGNATURE_ATAPI && !AHCI_ADDR_IS_PORT(addrp))
5900 5900 signature = SATA_DTYPE_UNKNOWN;
5901 5901
5902 5902 switch (signature) {
5903 5903
5904 5904 case AHCI_SIGNATURE_DISK:
5905 5905 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_ATADISK);
5906 5906 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5907 5907 "Disk is found at port: %d", port);
5908 5908 break;
5909 5909
5910 5910 case AHCI_SIGNATURE_ATAPI:
5911 5911 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_ATAPI);
5912 5912 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5913 5913 "ATAPI device is found at port: %d", port);
5914 5914 break;
5915 5915
5916 5916 case AHCI_SIGNATURE_PORT_MULTIPLIER:
5917 5917 /* Port Multiplier cannot recursively attached. */
5918 5918 ASSERT(AHCI_ADDR_IS_PORT(addrp));
5919 5919 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_PMULT);
5920 5920 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5921 5921 "Port Multiplier is found at port: %d", port);
5922 5922 break;
5923 5923
5924 5924 default:
5925 5925 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_UNKNOWN);
5926 5926 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5927 5927 "Unknown device is found at port: %d", port);
5928 5928 }
5929 5929 }
5930 5930
5931 5931 /*
5932 5932 * According to the spec, to reliably detect hot plug removals, software
5933 5933 * must disable interface power management. Software should perform the
5934 5934 * following initialization on a port after a device is attached:
5935 5935 * Set PxSCTL.IPM to 3h to disable interface state transitions
5936 5936 * Set PxCMD.ALPE to '0' to disable aggressive power management
5937 5937 * Disable device initiated interface power management by SET FEATURE
5938 5938 *
5939 5939 * We can ignore the last item because by default the feature is disabled
5940 5940 */
5941 5941 static void
5942 5942 ahci_disable_interface_pm(ahci_ctl_t *ahci_ctlp, uint8_t port)
5943 5943 {
5944 5944 uint32_t port_scontrol, port_cmd_status;
5945 5945
5946 5946 port_scontrol = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5947 5947 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port));
5948 5948 SCONTROL_SET_IPM(port_scontrol, SCONTROL_IPM_DISABLE_BOTH);
5949 5949 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5950 5950 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port), port_scontrol);
5951 5951
5952 5952 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5953 5953 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5954 5954 port_cmd_status &= ~AHCI_CMD_STATUS_ALPE;
5955 5955 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5956 5956 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port), port_cmd_status);
5957 5957 }
5958 5958
5959 5959 /*
5960 5960 * Start the port - set PxCMD.ST to 1, if PxCMD.FRE is not set
5961 5961 * to 1, then set it firstly.
5962 5962 *
5963 5963 * Each port contains two major DMA engines. One DMA engine walks through
5964 5964 * the command list, and is controlled by PxCMD.ST. The second DMA engine
5965 5965 * copies received FISes into system memory, and is controlled by PxCMD.FRE.
5966 5966 *
5967 5967 * Software shall not set PxCMD.ST to '1' until it verifies that PxCMD.CR
5968 5968 * is '0' and has set PxCMD.FRE is '1'. And software shall not clear
5969 5969 * PxCMD.FRE while PxCMD.ST or PxCMD.CR is set '1'.
5970 5970 *
5971 5971 * Software shall not set PxCMD.ST to '1' unless a functional device is
5972 5972 * present on the port(as determined by PxTFD.STS.BSY = '0',
5973 5973 * PxTFD.STS.DRQ = '0', and PxSSTS.DET = 3h).
5974 5974 */
5975 5975 static int
5976 5976 ahci_start_port(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp, uint8_t port)
5977 5977 {
5978 5978 uint32_t port_cmd_status;
5979 5979
5980 5980 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
5981 5981
5982 5982 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_start_port: %d enter", port);
5983 5983
5984 5984 if (ahci_portp->ahciport_port_state & SATA_PSTATE_FAILED) {
5985 5985 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_start_port failed "
5986 5986 "the state for port %d is 0x%x",
5987 5987 port, ahci_portp->ahciport_port_state);
5988 5988 return (AHCI_FAILURE);
5989 5989 }
5990 5990
5991 5991 if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
5992 5992 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_start_port failed "
5993 5993 "no device is attached at port %d", port);
5994 5994 return (AHCI_FAILURE);
5995 5995 }
5996 5996
5997 5997 /* First to set PxCMD.FRE before setting PxCMD.ST. */
5998 5998 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5999 5999 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
6000 6000
6001 6001 if (!(port_cmd_status & AHCI_CMD_STATUS_FRE)) {
6002 6002 port_cmd_status |= AHCI_CMD_STATUS_FRE;
6003 6003 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6004 6004 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
6005 6005 port_cmd_status);
6006 6006 }
6007 6007
6008 6008 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6009 6009 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
6010 6010
6011 6011 port_cmd_status |= AHCI_CMD_STATUS_ST;
6012 6012
6013 6013 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6014 6014 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
6015 6015 port_cmd_status);
6016 6016
6017 6017 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_STARTED;
6018 6018
6019 6019 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_start_port: "
6020 6020 "PxCMD.ST set to '1' at port %d", port);
6021 6021
6022 6022 return (AHCI_SUCCESS);
6023 6023 }
6024 6024
6025 6025 /*
6026 6026 * Setup PxCLB, PxCLBU, PxFB, and PxFBU for particular port. First, we need
6027 6027 * to make sure PxCMD.ST, PxCMD.CR, PxCMD.FRE, and PxCMD.FR are all cleared.
6028 6028 * Then set PxCLB, PxCLBU, PxFB, and PxFBU.
6029 6029 */
6030 6030 static int
6031 6031 ahci_setup_port_base_addresses(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6032 6032 {
6033 6033 uint8_t port = ahci_portp->ahciport_port_num;
6034 6034 uint32_t port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6035 6035 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
6036 6036
6037 6037 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6038 6038
6039 6039 /* Step 1: Make sure both PxCMD.ST and PxCMD.CR are cleared. */
6040 6040 if (port_cmd_status & (AHCI_CMD_STATUS_ST | AHCI_CMD_STATUS_CR)) {
6041 6041 if (ahci_put_port_into_notrunning_state(ahci_ctlp, ahci_portp,
6042 6042 port) != AHCI_SUCCESS)
6043 6043 return (AHCI_FAILURE);
6044 6044
6045 6045 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6046 6046 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
6047 6047 }
6048 6048
6049 6049 /* Step 2: Make sure both PxCMD.FRE and PxCMD.FR are cleared. */
6050 6050 if (port_cmd_status & (AHCI_CMD_STATUS_FRE | AHCI_CMD_STATUS_FR)) {
6051 6051 int loop_count = 0;
6052 6052
6053 6053 /* Clear PxCMD.FRE */
6054 6054 port_cmd_status &= ~AHCI_CMD_STATUS_FRE;
6055 6055 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6056 6056 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
6057 6057 port_cmd_status);
6058 6058
6059 6059 /* Wait until PxCMD.FR is cleared */
6060 6060 for (;;) {
6061 6061 port_cmd_status =
6062 6062 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6063 6063 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
6064 6064
6065 6065 if (!(port_cmd_status & AHCI_CMD_STATUS_FR))
6066 6066 break;
6067 6067
6068 6068 if (loop_count++ >= AHCI_POLLRATE_PORT_IDLE_FR) {
6069 6069 AHCIDBG(AHCIDBG_INIT | AHCIDBG_ERRS, ahci_ctlp,
6070 6070 "ahci_setup_port_base_addresses: cannot "
6071 6071 "clear PxCMD.FR for port %d.", port);
6072 6072
6073 6073 /*
6074 6074 * We are effectively timing out after 0.5 sec.
6075 6075 * This value is specified in AHCI spec.
6076 6076 */
6077 6077 return (AHCI_FAILURE);
6078 6078 }
6079 6079
6080 6080 /* Wait for 1 millisec */
6081 6081 drv_usecwait(AHCI_1MS_USECS);
6082 6082 }
6083 6083 }
6084 6084
6085 6085 /* Step 3: Config Port Command List Base Address */
6086 6086 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6087 6087 (uint32_t *)AHCI_PORT_PxCLB(ahci_ctlp, port),
6088 6088 ahci_portp->ahciport_cmd_list_dma_cookie.dmac_address);
6089 6089
6090 6090 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6091 6091 (uint32_t *)AHCI_PORT_PxCLBU(ahci_ctlp, port),
6092 6092 ahci_portp->ahciport_cmd_list_dma_cookie.dmac_notused);
6093 6093
6094 6094 /* Step 4: Config Port Received FIS Base Address */
6095 6095 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6096 6096 (uint32_t *)AHCI_PORT_PxFB(ahci_ctlp, port),
6097 6097 ahci_portp->ahciport_rcvd_fis_dma_cookie.dmac_address);
6098 6098
6099 6099 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6100 6100 (uint32_t *)AHCI_PORT_PxFBU(ahci_ctlp, port),
6101 6101 ahci_portp->ahciport_rcvd_fis_dma_cookie.dmac_notused);
6102 6102
6103 6103 return (AHCI_SUCCESS);
6104 6104 }
6105 6105
6106 6106 /*
6107 6107 * Allocate the ahci_port_t including Received FIS and Command List.
6108 6108 * The argument - port is the physical port number, and not logical
6109 6109 * port number seen by the SATA framework.
6110 6110 */
6111 6111 static int
6112 6112 ahci_alloc_port_state(ahci_ctl_t *ahci_ctlp, uint8_t port)
6113 6113 {
6114 6114 dev_info_t *dip = ahci_ctlp->ahcictl_dip;
6115 6115 ahci_port_t *ahci_portp;
6116 6116 char taskq_name[64] = "event_handle_taskq";
6117 6117
6118 6118 ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_mutex));
6119 6119
6120 6120 ahci_portp =
6121 6121 (ahci_port_t *)kmem_zalloc(sizeof (ahci_port_t), KM_SLEEP);
6122 6122
6123 6123 ahci_ctlp->ahcictl_ports[port] = ahci_portp;
6124 6124 ahci_portp->ahciport_port_num = port;
6125 6125
6126 6126 /* Initialize the port condition variable */
6127 6127 cv_init(&ahci_portp->ahciport_cv, NULL, CV_DRIVER, NULL);
6128 6128
6129 6129 /* Initialize the port mutex */
6130 6130 mutex_init(&ahci_portp->ahciport_mutex, NULL, MUTEX_DRIVER,
6131 6131 (void *)(uintptr_t)ahci_ctlp->ahcictl_intr_pri);
6132 6132
6133 6133 mutex_enter(&ahci_portp->ahciport_mutex);
6134 6134
6135 6135 /*
6136 6136 * Allocate memory for received FIS structure and
6137 6137 * command list for this port
6138 6138 */
6139 6139 if (ahci_alloc_rcvd_fis(ahci_ctlp, ahci_portp) != AHCI_SUCCESS) {
6140 6140 goto err_case1;
6141 6141 }
6142 6142
6143 6143 if (ahci_alloc_cmd_list(ahci_ctlp, ahci_portp) != AHCI_SUCCESS) {
6144 6144 goto err_case2;
6145 6145 }
6146 6146
6147 6147 /* Setup PxCMD.CLB, PxCMD.CLBU, PxCMD.FB, and PxCMD.FBU */
6148 6148 if (ahci_setup_port_base_addresses(ahci_ctlp, ahci_portp) !=
6149 6149 AHCI_SUCCESS) {
6150 6150 goto err_case3;
6151 6151 }
6152 6152
6153 6153 (void) snprintf(taskq_name + strlen(taskq_name),
6154 6154 sizeof (taskq_name) - strlen(taskq_name),
6155 6155 "_port%d", port);
6156 6156
6157 6157 /* Create the taskq for the port */
6158 6158 if ((ahci_portp->ahciport_event_taskq = ddi_taskq_create(dip,
6159 6159 taskq_name, 2, TASKQ_DEFAULTPRI, 0)) == NULL) {
6160 6160 cmn_err(CE_WARN, "!ahci%d: ddi_taskq_create failed for event "
6161 6161 "handle", ddi_get_instance(ahci_ctlp->ahcictl_dip));
↓ open down ↓ |
6161 lines elided |
↑ open up ↑ |
6162 6162 goto err_case3;
6163 6163 }
6164 6164
6165 6165 /* Allocate the argument for the taskq */
6166 6166 ahci_portp->ahciport_event_args =
6167 6167 kmem_zalloc(sizeof (ahci_event_arg_t), KM_SLEEP);
6168 6168
6169 6169 ahci_portp->ahciport_event_args->ahciea_addrp =
6170 6170 kmem_zalloc(sizeof (ahci_addr_t), KM_SLEEP);
6171 6171
6172 - if (ahci_portp->ahciport_event_args == NULL)
6173 - goto err_case4;
6174 -
6175 6172 /* Initialize the done queue */
6176 6173 ahci_portp->ahciport_doneq = NULL;
6177 6174 ahci_portp->ahciport_doneqtail = &ahci_portp->ahciport_doneq;
6178 6175 ahci_portp->ahciport_doneq_len = 0;
6179 6176
6180 6177 mutex_exit(&ahci_portp->ahciport_mutex);
6181 6178
6182 6179 return (AHCI_SUCCESS);
6183 6180
6184 -err_case4:
6185 - ddi_taskq_destroy(ahci_portp->ahciport_event_taskq);
6186 -
6187 6181 err_case3:
6188 6182 ahci_dealloc_cmd_list(ahci_ctlp, ahci_portp);
6189 6183
6190 6184 err_case2:
6191 6185 ahci_dealloc_rcvd_fis(ahci_portp);
6192 6186
6193 6187 err_case1:
6194 6188 mutex_exit(&ahci_portp->ahciport_mutex);
6195 6189 mutex_destroy(&ahci_portp->ahciport_mutex);
6196 6190 cv_destroy(&ahci_portp->ahciport_cv);
6197 6191
6198 6192 kmem_free(ahci_portp, sizeof (ahci_port_t));
6199 6193
6200 6194 return (AHCI_FAILURE);
6201 6195 }
6202 6196
6203 6197 /*
6204 6198 * Reverse of ahci_alloc_port_state().
6205 6199 */
6206 6200 static void
6207 6201 ahci_dealloc_port_state(ahci_ctl_t *ahci_ctlp, uint8_t port)
6208 6202 {
6209 6203 ahci_port_t *ahci_portp = ahci_ctlp->ahcictl_ports[port];
6210 6204
6211 6205 ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_mutex));
6212 6206 ASSERT(ahci_portp != NULL);
6213 6207
6214 6208 mutex_enter(&ahci_portp->ahciport_mutex);
6215 6209 kmem_free(ahci_portp->ahciport_event_args->ahciea_addrp,
6216 6210 sizeof (ahci_addr_t));
6217 6211 ahci_portp->ahciport_event_args->ahciea_addrp = NULL;
6218 6212 kmem_free(ahci_portp->ahciport_event_args, sizeof (ahci_event_arg_t));
6219 6213 ahci_portp->ahciport_event_args = NULL;
6220 6214 ddi_taskq_destroy(ahci_portp->ahciport_event_taskq);
6221 6215 ahci_dealloc_cmd_list(ahci_ctlp, ahci_portp);
6222 6216 ahci_dealloc_rcvd_fis(ahci_portp);
6223 6217 ahci_dealloc_pmult(ahci_ctlp, ahci_portp);
6224 6218 mutex_exit(&ahci_portp->ahciport_mutex);
6225 6219
6226 6220 mutex_destroy(&ahci_portp->ahciport_mutex);
6227 6221 cv_destroy(&ahci_portp->ahciport_cv);
6228 6222
6229 6223 kmem_free(ahci_portp, sizeof (ahci_port_t));
6230 6224
6231 6225 ahci_ctlp->ahcictl_ports[port] = NULL;
6232 6226 }
6233 6227
6234 6228 /*
6235 6229 * Allocates memory for the Received FIS Structure
6236 6230 */
6237 6231 static int
6238 6232 ahci_alloc_rcvd_fis(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6239 6233 {
6240 6234 size_t rcvd_fis_size;
6241 6235 size_t ret_len;
6242 6236 uint_t cookie_count;
6243 6237
6244 6238 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6245 6239
6246 6240 rcvd_fis_size = sizeof (ahci_rcvd_fis_t);
6247 6241
6248 6242 /* allocate rcvd FIS dma handle. */
6249 6243 if (ddi_dma_alloc_handle(ahci_ctlp->ahcictl_dip,
6250 6244 &ahci_ctlp->ahcictl_rcvd_fis_dma_attr,
6251 6245 DDI_DMA_SLEEP,
6252 6246 NULL,
6253 6247 &ahci_portp->ahciport_rcvd_fis_dma_handle) !=
6254 6248 DDI_SUCCESS) {
6255 6249 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6256 6250 "rcvd FIS dma handle alloc failed", NULL);
6257 6251
6258 6252 return (AHCI_FAILURE);
6259 6253 }
6260 6254
6261 6255 if (ddi_dma_mem_alloc(ahci_portp->ahciport_rcvd_fis_dma_handle,
6262 6256 rcvd_fis_size,
6263 6257 &accattr,
6264 6258 DDI_DMA_CONSISTENT,
6265 6259 DDI_DMA_SLEEP,
6266 6260 NULL,
6267 6261 (caddr_t *)&ahci_portp->ahciport_rcvd_fis,
6268 6262 &ret_len,
6269 6263 &ahci_portp->ahciport_rcvd_fis_acc_handle) != NULL) {
6270 6264
6271 6265 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6272 6266 "rcvd FIS dma mem alloc fail", NULL);
6273 6267 /* error.. free the dma handle. */
6274 6268 ddi_dma_free_handle(&ahci_portp->ahciport_rcvd_fis_dma_handle);
6275 6269 return (AHCI_FAILURE);
6276 6270 }
6277 6271
6278 6272 if (ddi_dma_addr_bind_handle(ahci_portp->ahciport_rcvd_fis_dma_handle,
6279 6273 NULL,
6280 6274 (caddr_t)ahci_portp->ahciport_rcvd_fis,
6281 6275 rcvd_fis_size,
6282 6276 DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
6283 6277 DDI_DMA_SLEEP,
6284 6278 NULL,
6285 6279 &ahci_portp->ahciport_rcvd_fis_dma_cookie,
6286 6280 &cookie_count) != DDI_DMA_MAPPED) {
6287 6281
6288 6282 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6289 6283 "rcvd FIS dma handle bind fail", NULL);
6290 6284 /* error.. free the dma handle & free the memory. */
6291 6285 ddi_dma_mem_free(&ahci_portp->ahciport_rcvd_fis_acc_handle);
6292 6286 ddi_dma_free_handle(&ahci_portp->ahciport_rcvd_fis_dma_handle);
6293 6287 return (AHCI_FAILURE);
6294 6288 }
6295 6289
6296 6290 bzero((void *)ahci_portp->ahciport_rcvd_fis, rcvd_fis_size);
6297 6291
6298 6292 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "64-bit, dma address: 0x%llx",
6299 6293 ahci_portp->ahciport_rcvd_fis_dma_cookie.dmac_laddress);
6300 6294 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "32-bit, dma address: 0x%x",
6301 6295 ahci_portp->ahciport_rcvd_fis_dma_cookie.dmac_address);
6302 6296
6303 6297 return (AHCI_SUCCESS);
6304 6298 }
6305 6299
6306 6300 /*
6307 6301 * Deallocates the Received FIS Structure
6308 6302 */
6309 6303 static void
6310 6304 ahci_dealloc_rcvd_fis(ahci_port_t *ahci_portp)
6311 6305 {
6312 6306 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6313 6307
6314 6308 /* Unbind the cmd list dma handle first. */
6315 6309 (void) ddi_dma_unbind_handle(ahci_portp->ahciport_rcvd_fis_dma_handle);
6316 6310
6317 6311 /* Then free the underlying memory. */
6318 6312 ddi_dma_mem_free(&ahci_portp->ahciport_rcvd_fis_acc_handle);
6319 6313
6320 6314 /* Now free the handle itself. */
6321 6315 ddi_dma_free_handle(&ahci_portp->ahciport_rcvd_fis_dma_handle);
6322 6316 }
6323 6317
6324 6318 /*
6325 6319 * Allocates memory for the Command List, which contains up to 32 entries.
6326 6320 * Each entry contains a command header, which is a 32-byte structure that
6327 6321 * includes the pointer to the command table.
6328 6322 */
6329 6323 static int
6330 6324 ahci_alloc_cmd_list(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6331 6325 {
6332 6326 size_t cmd_list_size;
6333 6327 size_t ret_len;
6334 6328 uint_t cookie_count;
6335 6329
6336 6330 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6337 6331
6338 6332 cmd_list_size =
6339 6333 ahci_ctlp->ahcictl_num_cmd_slots * sizeof (ahci_cmd_header_t);
6340 6334
6341 6335 /* allocate cmd list dma handle. */
6342 6336 if (ddi_dma_alloc_handle(ahci_ctlp->ahcictl_dip,
6343 6337 &ahci_ctlp->ahcictl_cmd_list_dma_attr,
6344 6338 DDI_DMA_SLEEP,
6345 6339 NULL,
6346 6340 &ahci_portp->ahciport_cmd_list_dma_handle) != DDI_SUCCESS) {
6347 6341
6348 6342 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6349 6343 "cmd list dma handle alloc failed", NULL);
6350 6344 return (AHCI_FAILURE);
6351 6345 }
6352 6346
6353 6347 if (ddi_dma_mem_alloc(ahci_portp->ahciport_cmd_list_dma_handle,
6354 6348 cmd_list_size,
6355 6349 &accattr,
6356 6350 DDI_DMA_CONSISTENT,
6357 6351 DDI_DMA_SLEEP,
6358 6352 NULL,
6359 6353 (caddr_t *)&ahci_portp->ahciport_cmd_list,
6360 6354 &ret_len,
6361 6355 &ahci_portp->ahciport_cmd_list_acc_handle) != NULL) {
6362 6356
6363 6357 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6364 6358 "cmd list dma mem alloc fail", NULL);
6365 6359 /* error.. free the dma handle. */
6366 6360 ddi_dma_free_handle(&ahci_portp->ahciport_cmd_list_dma_handle);
6367 6361 return (AHCI_FAILURE);
6368 6362 }
6369 6363
6370 6364 if (ddi_dma_addr_bind_handle(ahci_portp->ahciport_cmd_list_dma_handle,
6371 6365 NULL,
6372 6366 (caddr_t)ahci_portp->ahciport_cmd_list,
6373 6367 cmd_list_size,
6374 6368 DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
6375 6369 DDI_DMA_SLEEP,
6376 6370 NULL,
6377 6371 &ahci_portp->ahciport_cmd_list_dma_cookie,
6378 6372 &cookie_count) != DDI_DMA_MAPPED) {
6379 6373
6380 6374 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6381 6375 "cmd list dma handle bind fail", NULL);
6382 6376 /* error.. free the dma handle & free the memory. */
6383 6377 ddi_dma_mem_free(&ahci_portp->ahciport_cmd_list_acc_handle);
6384 6378 ddi_dma_free_handle(&ahci_portp->ahciport_cmd_list_dma_handle);
6385 6379 return (AHCI_FAILURE);
6386 6380 }
6387 6381
6388 6382 bzero((void *)ahci_portp->ahciport_cmd_list, cmd_list_size);
6389 6383
6390 6384 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "64-bit, dma address: 0x%llx",
6391 6385 ahci_portp->ahciport_cmd_list_dma_cookie.dmac_laddress);
6392 6386
6393 6387 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "32-bit, dma address: 0x%x",
6394 6388 ahci_portp->ahciport_cmd_list_dma_cookie.dmac_address);
6395 6389
6396 6390 if (ahci_alloc_cmd_tables(ahci_ctlp, ahci_portp) != AHCI_SUCCESS) {
6397 6391 goto err_out;
6398 6392 }
6399 6393
6400 6394 return (AHCI_SUCCESS);
6401 6395
6402 6396 err_out:
6403 6397 /* Unbind the cmd list dma handle first. */
6404 6398 (void) ddi_dma_unbind_handle(ahci_portp->ahciport_cmd_list_dma_handle);
6405 6399
6406 6400 /* Then free the underlying memory. */
6407 6401 ddi_dma_mem_free(&ahci_portp->ahciport_cmd_list_acc_handle);
6408 6402
6409 6403 /* Now free the handle itself. */
6410 6404 ddi_dma_free_handle(&ahci_portp->ahciport_cmd_list_dma_handle);
6411 6405
6412 6406 return (AHCI_FAILURE);
6413 6407 }
6414 6408
6415 6409 /*
6416 6410 * Deallocates the Command List
6417 6411 */
6418 6412 static void
6419 6413 ahci_dealloc_cmd_list(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6420 6414 {
6421 6415 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6422 6416
6423 6417 /* First dealloc command table */
6424 6418 ahci_dealloc_cmd_tables(ahci_ctlp, ahci_portp);
6425 6419
6426 6420 /* Unbind the cmd list dma handle first. */
6427 6421 (void) ddi_dma_unbind_handle(ahci_portp->ahciport_cmd_list_dma_handle);
6428 6422
6429 6423 /* Then free the underlying memory. */
6430 6424 ddi_dma_mem_free(&ahci_portp->ahciport_cmd_list_acc_handle);
6431 6425
6432 6426 /* Now free the handle itself. */
6433 6427 ddi_dma_free_handle(&ahci_portp->ahciport_cmd_list_dma_handle);
6434 6428 }
6435 6429
6436 6430 /*
6437 6431 * Allocates memory for all Command Tables, which contains Command FIS,
6438 6432 * ATAPI Command and Physical Region Descriptor Table.
6439 6433 */
6440 6434 static int
6441 6435 ahci_alloc_cmd_tables(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6442 6436 {
6443 6437 size_t ret_len;
6444 6438 ddi_dma_cookie_t cmd_table_dma_cookie;
6445 6439 uint_t cookie_count;
6446 6440 int slot;
6447 6441
6448 6442 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6449 6443
6450 6444 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
6451 6445 "ahci_alloc_cmd_tables: port %d enter",
6452 6446 ahci_portp->ahciport_port_num);
6453 6447
6454 6448 for (slot = 0; slot < ahci_ctlp->ahcictl_num_cmd_slots; slot++) {
6455 6449 /* Allocate cmd table dma handle. */
6456 6450 if (ddi_dma_alloc_handle(ahci_ctlp->ahcictl_dip,
6457 6451 &ahci_ctlp->ahcictl_cmd_table_dma_attr,
6458 6452 DDI_DMA_SLEEP,
6459 6453 NULL,
6460 6454 &ahci_portp->ahciport_cmd_tables_dma_handle[slot]) !=
6461 6455 DDI_SUCCESS) {
6462 6456
6463 6457 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6464 6458 "cmd table dma handle alloc failed", NULL);
6465 6459
6466 6460 goto err_out;
6467 6461 }
6468 6462
6469 6463 if (ddi_dma_mem_alloc(
6470 6464 ahci_portp->ahciport_cmd_tables_dma_handle[slot],
6471 6465 ahci_cmd_table_size,
6472 6466 &accattr,
6473 6467 DDI_DMA_CONSISTENT,
6474 6468 DDI_DMA_SLEEP,
6475 6469 NULL,
6476 6470 (caddr_t *)&ahci_portp->ahciport_cmd_tables[slot],
6477 6471 &ret_len,
6478 6472 &ahci_portp->ahciport_cmd_tables_acc_handle[slot]) !=
6479 6473 NULL) {
6480 6474
6481 6475 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6482 6476 "cmd table dma mem alloc fail", NULL);
6483 6477
6484 6478 /* error.. free the dma handle. */
6485 6479 ddi_dma_free_handle(
6486 6480 &ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6487 6481 goto err_out;
6488 6482 }
6489 6483
6490 6484 if (ddi_dma_addr_bind_handle(
6491 6485 ahci_portp->ahciport_cmd_tables_dma_handle[slot],
6492 6486 NULL,
6493 6487 (caddr_t)ahci_portp->ahciport_cmd_tables[slot],
6494 6488 ahci_cmd_table_size,
6495 6489 DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
6496 6490 DDI_DMA_SLEEP,
6497 6491 NULL,
6498 6492 &cmd_table_dma_cookie,
6499 6493 &cookie_count) != DDI_DMA_MAPPED) {
6500 6494
6501 6495 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6502 6496 "cmd table dma handle bind fail", NULL);
6503 6497 /* error.. free the dma handle & free the memory. */
6504 6498 ddi_dma_mem_free(
6505 6499 &ahci_portp->ahciport_cmd_tables_acc_handle[slot]);
6506 6500 ddi_dma_free_handle(
6507 6501 &ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6508 6502 goto err_out;
6509 6503 }
6510 6504
6511 6505 bzero((void *)ahci_portp->ahciport_cmd_tables[slot],
6512 6506 ahci_cmd_table_size);
6513 6507
6514 6508 /* Config Port Command Table Base Address */
6515 6509 SET_COMMAND_TABLE_BASE_ADDR(
6516 6510 (&ahci_portp->ahciport_cmd_list[slot]),
6517 6511 cmd_table_dma_cookie.dmac_laddress & 0xffffffffull);
6518 6512
6519 6513 #ifndef __lock_lint
6520 6514 SET_COMMAND_TABLE_BASE_ADDR_UPPER(
6521 6515 (&ahci_portp->ahciport_cmd_list[slot]),
6522 6516 cmd_table_dma_cookie.dmac_laddress >> 32);
6523 6517 #endif
6524 6518 }
6525 6519
6526 6520 return (AHCI_SUCCESS);
6527 6521 err_out:
6528 6522
6529 6523 for (slot--; slot >= 0; slot--) {
6530 6524 /* Unbind the cmd table dma handle first */
6531 6525 (void) ddi_dma_unbind_handle(
6532 6526 ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6533 6527
6534 6528 /* Then free the underlying memory */
6535 6529 ddi_dma_mem_free(
6536 6530 &ahci_portp->ahciport_cmd_tables_acc_handle[slot]);
6537 6531
6538 6532 /* Now free the handle itself */
6539 6533 ddi_dma_free_handle(
6540 6534 &ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6541 6535 }
6542 6536
6543 6537 return (AHCI_FAILURE);
6544 6538 }
6545 6539
6546 6540 /*
6547 6541 * Deallocates memory for all Command Tables.
6548 6542 */
6549 6543 static void
6550 6544 ahci_dealloc_cmd_tables(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6551 6545 {
6552 6546 int slot;
6553 6547
6554 6548 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6555 6549
6556 6550 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
6557 6551 "ahci_dealloc_cmd_tables: %d enter",
6558 6552 ahci_portp->ahciport_port_num);
6559 6553
6560 6554 for (slot = 0; slot < ahci_ctlp->ahcictl_num_cmd_slots; slot++) {
6561 6555 /* Unbind the cmd table dma handle first. */
6562 6556 (void) ddi_dma_unbind_handle(
6563 6557 ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6564 6558
6565 6559 /* Then free the underlying memory. */
6566 6560 ddi_dma_mem_free(
6567 6561 &ahci_portp->ahciport_cmd_tables_acc_handle[slot]);
6568 6562
6569 6563 /* Now free the handle itself. */
6570 6564 ddi_dma_free_handle(
6571 6565 &ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6572 6566 }
6573 6567 }
6574 6568
6575 6569 /*
6576 6570 * Update SATA registers at controller ports
6577 6571 */
6578 6572 static void
6579 6573 ahci_update_sata_registers(ahci_ctl_t *ahci_ctlp, uint8_t port,
6580 6574 sata_device_t *sd)
6581 6575 {
6582 6576 ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
6583 6577
6584 6578 sd->satadev_scr.sstatus =
6585 6579 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6586 6580 (uint32_t *)(AHCI_PORT_PxSSTS(ahci_ctlp, port)));
6587 6581 sd->satadev_scr.serror =
6588 6582 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6589 6583 (uint32_t *)(AHCI_PORT_PxSERR(ahci_ctlp, port)));
6590 6584 sd->satadev_scr.scontrol =
6591 6585 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6592 6586 (uint32_t *)(AHCI_PORT_PxSCTL(ahci_ctlp, port)));
6593 6587 sd->satadev_scr.sactive =
6594 6588 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6595 6589 (uint32_t *)(AHCI_PORT_PxSACT(ahci_ctlp, port)));
6596 6590 }
6597 6591
6598 6592 /*
6599 6593 * For poll mode, ahci_port_intr will be called to emulate the interrupt
6600 6594 */
6601 6595 static void
6602 6596 ahci_port_intr(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp, uint8_t port)
6603 6597 {
6604 6598 uint32_t port_intr_status;
6605 6599 uint32_t port_intr_enable;
6606 6600
6607 6601 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY, ahci_ctlp,
6608 6602 "ahci_port_intr enter: port %d", port);
6609 6603
6610 6604 mutex_enter(&ahci_portp->ahciport_mutex);
6611 6605 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_POLLING) {
6612 6606 /* For SATA_OPMODE_POLLING commands */
6613 6607 port_intr_enable =
6614 6608 (AHCI_INTR_STATUS_DHRS |
6615 6609 AHCI_INTR_STATUS_PSS |
6616 6610 AHCI_INTR_STATUS_SDBS |
6617 6611 AHCI_INTR_STATUS_UFS |
6618 6612 AHCI_INTR_STATUS_PCS |
6619 6613 AHCI_INTR_STATUS_PRCS |
6620 6614 AHCI_INTR_STATUS_OFS |
6621 6615 AHCI_INTR_STATUS_INFS |
6622 6616 AHCI_INTR_STATUS_IFS |
6623 6617 AHCI_INTR_STATUS_HBDS |
6624 6618 AHCI_INTR_STATUS_HBFS |
6625 6619 AHCI_INTR_STATUS_TFES);
6626 6620 } else {
6627 6621 /*
6628 6622 * port_intr_enable indicates that the corresponding interrrupt
6629 6623 * reporting is enabled.
6630 6624 */
6631 6625 port_intr_enable = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6632 6626 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port));
6633 6627 }
6634 6628
6635 6629 /* IPMS error in port reset should be ignored according AHCI spec. */
6636 6630 if (!(ahci_portp->ahciport_flags & AHCI_PORT_FLAG_IGNORE_IPMS))
6637 6631 port_intr_enable |= AHCI_INTR_STATUS_IPMS;
6638 6632 mutex_exit(&ahci_portp->ahciport_mutex);
6639 6633
6640 6634 /*
6641 6635 * port_intr_stats indicates that the corresponding interrupt
6642 6636 * condition is active.
6643 6637 */
6644 6638 port_intr_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6645 6639 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port));
6646 6640
6647 6641 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
6648 6642 "ahci_port_intr: port %d, port_intr_status = 0x%x, "
6649 6643 "port_intr_enable = 0x%x",
6650 6644 port, port_intr_status, port_intr_enable);
6651 6645
6652 6646 port_intr_status &= port_intr_enable;
6653 6647
6654 6648 /*
6655 6649 * Pending interrupt events are indicated by the PxIS register.
6656 6650 * Make sure we don't miss any event.
6657 6651 */
6658 6652 if (ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) {
6659 6653 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
6660 6654 DDI_SERVICE_UNAFFECTED);
6661 6655 ddi_fm_acc_err_clear(ahci_ctlp->ahcictl_ahci_acc_handle,
6662 6656 DDI_FME_VERSION);
6663 6657 return;
6664 6658 }
6665 6659
6666 6660 /* First clear the port interrupts status */
6667 6661 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6668 6662 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port),
6669 6663 port_intr_status);
6670 6664
6671 6665 /* Check the completed non-queued commands */
6672 6666 if (port_intr_status & (AHCI_INTR_STATUS_DHRS |
6673 6667 AHCI_INTR_STATUS_PSS)) {
6674 6668 (void) ahci_intr_cmd_cmplt(ahci_ctlp,
6675 6669 ahci_portp, port);
6676 6670 }
6677 6671
6678 6672 /* Check the completed queued commands */
6679 6673 if (port_intr_status & AHCI_INTR_STATUS_SDBS) {
6680 6674 (void) ahci_intr_set_device_bits(ahci_ctlp,
6681 6675 ahci_portp, port);
6682 6676 }
6683 6677
6684 6678 /* Check the port connect change status interrupt bit */
6685 6679 if (port_intr_status & AHCI_INTR_STATUS_PCS) {
6686 6680 (void) ahci_intr_port_connect_change(ahci_ctlp,
6687 6681 ahci_portp, port);
6688 6682 }
6689 6683
6690 6684 /* Check the device mechanical presence status interrupt bit */
6691 6685 if (port_intr_status & AHCI_INTR_STATUS_DMPS) {
6692 6686 (void) ahci_intr_device_mechanical_presence_status(
6693 6687 ahci_ctlp, ahci_portp, port);
6694 6688 }
6695 6689
6696 6690 /* Check the PhyRdy change status interrupt bit */
6697 6691 if (port_intr_status & AHCI_INTR_STATUS_PRCS) {
6698 6692 (void) ahci_intr_phyrdy_change(ahci_ctlp, ahci_portp,
6699 6693 port);
6700 6694 }
6701 6695
6702 6696 /*
6703 6697 * Check the non-fatal error interrupt bits, there are four
6704 6698 * kinds of non-fatal errors at the time being:
6705 6699 *
6706 6700 * PxIS.UFS - Unknown FIS Error
6707 6701 * PxIS.OFS - Overflow Error
6708 6702 * PxIS.INFS - Interface Non-Fatal Error
6709 6703 * PxIS.IPMS - Incorrect Port Multiplier Status Error
6710 6704 *
6711 6705 * For these non-fatal errors, the HBA can continue to operate,
6712 6706 * so the driver just log the error messages.
6713 6707 */
6714 6708 if (port_intr_status & (AHCI_INTR_STATUS_UFS |
6715 6709 AHCI_INTR_STATUS_OFS |
6716 6710 AHCI_INTR_STATUS_IPMS |
6717 6711 AHCI_INTR_STATUS_INFS)) {
6718 6712 (void) ahci_intr_non_fatal_error(ahci_ctlp, ahci_portp,
6719 6713 port, port_intr_status);
6720 6714 }
6721 6715
6722 6716 /*
6723 6717 * Check the fatal error interrupt bits, there are four kinds
6724 6718 * of fatal errors for AHCI controllers:
6725 6719 *
6726 6720 * PxIS.HBFS - Host Bus Fatal Error
6727 6721 * PxIS.HBDS - Host Bus Data Error
6728 6722 * PxIS.IFS - Interface Fatal Error
6729 6723 * PxIS.TFES - Task File Error
6730 6724 *
6731 6725 * The fatal error means the HBA can not recover from it by
6732 6726 * itself, and it will try to abort the transfer, and the software
6733 6727 * must intervene to restart the port.
6734 6728 */
6735 6729 if (port_intr_status & (AHCI_INTR_STATUS_IFS |
6736 6730 AHCI_INTR_STATUS_HBDS |
6737 6731 AHCI_INTR_STATUS_HBFS |
6738 6732 AHCI_INTR_STATUS_TFES))
6739 6733 (void) ahci_intr_fatal_error(ahci_ctlp, ahci_portp,
6740 6734 port, port_intr_status);
6741 6735
6742 6736 /* Check the cold port detect interrupt bit */
6743 6737 if (port_intr_status & AHCI_INTR_STATUS_CPDS) {
6744 6738 (void) ahci_intr_cold_port_detect(ahci_ctlp, ahci_portp, port);
6745 6739 }
6746 6740
6747 6741 /* Second clear the corresponding bit in IS.IPS */
6748 6742 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6749 6743 (uint32_t *)AHCI_GLOBAL_IS(ahci_ctlp), (0x1 << port));
6750 6744
6751 6745 /* Try to recover at the end of the interrupt handler. */
6752 6746 if (ahci_check_acc_handle(ahci_ctlp->ahcictl_ahci_acc_handle) !=
6753 6747 DDI_FM_OK) {
6754 6748 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
6755 6749 DDI_SERVICE_UNAFFECTED);
6756 6750 ddi_fm_acc_err_clear(ahci_ctlp->ahcictl_ahci_acc_handle,
6757 6751 DDI_FME_VERSION);
6758 6752 }
6759 6753 }
6760 6754
6761 6755 /*
6762 6756 * Interrupt service handler
6763 6757 */
6764 6758 static uint_t
6765 6759 ahci_intr(caddr_t arg1, caddr_t arg2)
6766 6760 {
6767 6761 #ifndef __lock_lint
6768 6762 _NOTE(ARGUNUSED(arg2))
6769 6763 #endif
6770 6764 /* LINTED */
6771 6765 ahci_ctl_t *ahci_ctlp = (ahci_ctl_t *)arg1;
6772 6766 ahci_port_t *ahci_portp;
6773 6767 int32_t global_intr_status;
6774 6768 uint8_t port;
6775 6769
6776 6770 /*
6777 6771 * global_intr_status indicates that the corresponding port has
6778 6772 * an interrupt pending.
6779 6773 */
6780 6774 global_intr_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6781 6775 (uint32_t *)AHCI_GLOBAL_IS(ahci_ctlp));
6782 6776
6783 6777 if (!(global_intr_status & ahci_ctlp->ahcictl_ports_implemented)) {
6784 6778 /* The interrupt is not ours */
6785 6779 return (DDI_INTR_UNCLAIMED);
6786 6780 }
6787 6781
6788 6782 /*
6789 6783 * Check the handle after reading global_intr_status - we don't want
6790 6784 * to miss any port with pending interrupts.
6791 6785 */
6792 6786 if (ahci_check_acc_handle(ahci_ctlp->ahcictl_ahci_acc_handle) !=
6793 6787 DDI_FM_OK) {
6794 6788 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
6795 6789 DDI_SERVICE_UNAFFECTED);
6796 6790 ddi_fm_acc_err_clear(ahci_ctlp->ahcictl_ahci_acc_handle,
6797 6791 DDI_FME_VERSION);
6798 6792 return (DDI_INTR_UNCLAIMED);
6799 6793 }
6800 6794
6801 6795 /* Loop for all the ports */
6802 6796 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
6803 6797 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
6804 6798 continue;
6805 6799 }
6806 6800 if (!((0x1 << port) & global_intr_status)) {
6807 6801 continue;
6808 6802 }
6809 6803
6810 6804 ahci_portp = ahci_ctlp->ahcictl_ports[port];
6811 6805
6812 6806 /* Call ahci_port_intr */
6813 6807 ahci_port_intr(ahci_ctlp, ahci_portp, port);
6814 6808 }
6815 6809
6816 6810 return (DDI_INTR_CLAIMED);
6817 6811 }
6818 6812
6819 6813 /*
6820 6814 * For non-queued commands, when the corresponding bit in the PxCI register
6821 6815 * is cleared, it means the command is completed successfully. And according
6822 6816 * to the HBA state machine, there are three conditions which possibly will
6823 6817 * try to clear the PxCI register bit.
6824 6818 * 1. Receive one D2H Register FIS which is with 'I' bit set
6825 6819 * 2. Update PIO Setup FIS
6826 6820 * 3. Transmit a command and receive R_OK if CTBA.C is set (software reset)
6827 6821 *
6828 6822 * Process completed non-queued commands when the interrupt status bit -
6829 6823 * AHCI_INTR_STATUS_DHRS or AHCI_INTR_STATUS_PSS is set.
6830 6824 *
6831 6825 * AHCI_INTR_STATUS_DHRS means a D2H Register FIS has been received
6832 6826 * with the 'I' bit set. And the following commands will send thus
6833 6827 * FIS with 'I' bit set upon the successful completion:
6834 6828 * 1. Non-data commands
6835 6829 * 2. DMA data-in command
6836 6830 * 3. DMA data-out command
6837 6831 * 4. PIO data-out command
6838 6832 * 5. PACKET non-data commands
6839 6833 * 6. PACKET PIO data-in command
6840 6834 * 7. PACKET PIO data-out command
6841 6835 * 8. PACKET DMA data-in command
6842 6836 * 9. PACKET DMA data-out command
6843 6837 *
6844 6838 * AHCI_INTR_STATUS_PSS means a PIO Setup FIS has been received
6845 6839 * with the 'I' bit set. And the following commands will send this
6846 6840 * FIS upon the successful completion:
6847 6841 * 1. PIO data-in command
6848 6842 */
6849 6843 static int
6850 6844 ahci_intr_cmd_cmplt(ahci_ctl_t *ahci_ctlp,
6851 6845 ahci_port_t *ahci_portp, uint8_t port)
6852 6846 {
6853 6847 uint32_t port_cmd_issue = 0;
6854 6848 uint32_t finished_tags;
6855 6849 int finished_slot;
6856 6850 sata_pkt_t *satapkt;
6857 6851 ahci_fis_d2h_register_t *rcvd_fisp;
6858 6852 #if AHCI_DEBUG
6859 6853 ahci_cmd_header_t *cmd_header;
6860 6854 uint32_t cmd_dmacount;
6861 6855 #endif
6862 6856
6863 6857 mutex_enter(&ahci_portp->ahciport_mutex);
6864 6858
6865 6859 if (!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&
6866 6860 !RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp) &&
6867 6861 !NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
6868 6862 /*
6869 6863 * Spurious interrupt. Nothing to be done.
6870 6864 */
6871 6865 mutex_exit(&ahci_portp->ahciport_mutex);
6872 6866 return (AHCI_SUCCESS);
6873 6867 }
6874 6868
6875 6869 port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6876 6870 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
6877 6871
6878 6872 /* If the PxCI corrupts, don't complete the commmands. */
6879 6873 if (ahci_check_acc_handle(ahci_ctlp->ahcictl_ahci_acc_handle)
6880 6874 != DDI_FM_OK) {
6881 6875 mutex_exit(&ahci_portp->ahciport_mutex);
6882 6876 return (AHCI_FAILURE);
6883 6877 }
6884 6878
6885 6879 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
6886 6880 /* Slot 0 is always used during error recovery */
6887 6881 finished_tags = 0x1 & ~port_cmd_issue;
6888 6882 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
6889 6883 "ahci_intr_cmd_cmplt: port %d the sata pkt for error "
6890 6884 "retrieval is finished, and finished_tags = 0x%x",
6891 6885 port, finished_tags);
6892 6886 } else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
6893 6887 finished_tags = 0x1 & ~port_cmd_issue;
6894 6888 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
6895 6889 "ahci_intr_cmd_cmplt: port %d the sata pkt for r/w "
6896 6890 "port multiplier is finished, and finished_tags = 0x%x",
6897 6891 port, finished_tags);
6898 6892
6899 6893 } else {
6900 6894
6901 6895 finished_tags = ahci_portp->ahciport_pending_tags &
6902 6896 ~port_cmd_issue & AHCI_SLOT_MASK(ahci_ctlp);
6903 6897 }
6904 6898
6905 6899 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
6906 6900 "ahci_intr_cmd_cmplt: pending_tags = 0x%x, "
6907 6901 "port_cmd_issue = 0x%x finished_tags = 0x%x",
6908 6902 ahci_portp->ahciport_pending_tags, port_cmd_issue,
6909 6903 finished_tags);
6910 6904
6911 6905 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&
6912 6906 (finished_tags == 0x1)) {
6913 6907 satapkt = ahci_portp->ahciport_err_retri_pkt;
6914 6908 ASSERT(satapkt != NULL);
6915 6909
6916 6910 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
6917 6911 "ahci_intr_cmd_cmplt: sending up pkt 0x%p "
6918 6912 "with SATA_PKT_COMPLETED", (void *)satapkt);
6919 6913
6920 6914 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
6921 6915 goto out;
6922 6916 }
6923 6917
6924 6918 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp) &&
6925 6919 (finished_tags == 0x1)) {
6926 6920 satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
6927 6921 ASSERT(satapkt != NULL);
6928 6922
6929 6923 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
6930 6924 "ahci_intr_cmd_cmplt: sending up pkt 0x%p "
6931 6925 "with SATA_PKT_COMPLETED", (void *)satapkt);
6932 6926
6933 6927 /* READ PORTMULT need copy out FIS content. */
6934 6928 if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
6935 6929 rcvd_fisp = &(ahci_portp->ahciport_rcvd_fis->
6936 6930 ahcirf_d2h_register_fis);
6937 6931 satapkt->satapkt_cmd.satacmd_status_reg =
6938 6932 GET_RFIS_STATUS(rcvd_fisp);
6939 6933 ahci_copy_out_regs(&satapkt->satapkt_cmd, rcvd_fisp);
6940 6934 }
6941 6935
6942 6936 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
6943 6937 goto out;
6944 6938 }
6945 6939
6946 6940 while (finished_tags) {
6947 6941 finished_slot = ddi_ffs(finished_tags) - 1;
6948 6942 if (finished_slot == -1) {
6949 6943 goto out;
6950 6944 }
6951 6945
6952 6946 satapkt = ahci_portp->ahciport_slot_pkts[finished_slot];
6953 6947 ASSERT(satapkt != NULL);
6954 6948 #if AHCI_DEBUG
6955 6949 /*
6956 6950 * For non-native queued commands, the PRD byte count field
6957 6951 * shall contain an accurate count of the number of bytes
6958 6952 * transferred for the command before the PxCI bit is cleared
6959 6953 * to '0' for the command.
6960 6954 *
6961 6955 * The purpose of this field is to let software know how many
6962 6956 * bytes transferred for a given operation in order to
6963 6957 * determine if underflow occurred. When issuing native command
6964 6958 * queuing commands, this field should not be used and is not
6965 6959 * required to be valid since in this case underflow is always
6966 6960 * illegal.
6967 6961 *
6968 6962 * For data reads, the HBA will update its PRD byte count with
6969 6963 * the total number of bytes received from the last FIS, and
6970 6964 * may be able to continue normally. For data writes, the
6971 6965 * device will detect an error, and HBA most likely will get
6972 6966 * a fatal error.
6973 6967 *
6974 6968 * Therefore, here just put code to debug part. And please
6975 6969 * refer to the comment above ahci_intr_fatal_error for the
6976 6970 * definition of underflow error.
6977 6971 */
6978 6972 cmd_dmacount =
6979 6973 ahci_portp->ahciport_prd_bytecounts[finished_slot];
6980 6974 if (cmd_dmacount) {
6981 6975 cmd_header =
6982 6976 &ahci_portp->ahciport_cmd_list[finished_slot];
6983 6977 AHCIDBG(AHCIDBG_INTR|AHCIDBG_PRDT, ahci_ctlp,
6984 6978 "ahci_intr_cmd_cmplt: port %d, "
6985 6979 "PRD Byte Count = 0x%x, "
6986 6980 "ahciport_prd_bytecounts = 0x%x", port,
6987 6981 cmd_header->ahcich_prd_byte_count,
6988 6982 cmd_dmacount);
6989 6983
6990 6984 if (cmd_header->ahcich_prd_byte_count != cmd_dmacount) {
6991 6985 AHCIDBG(AHCIDBG_UNDERFLOW, ahci_ctlp,
6992 6986 "ahci_intr_cmd_cmplt: port %d, "
6993 6987 "an underflow occurred", port);
6994 6988 }
6995 6989 }
6996 6990 #endif
6997 6991
6998 6992 /*
6999 6993 * For SATAC_SMART command with SATA_SMART_RETURN_STATUS
7000 6994 * feature, sata_special_regs flag will be set, and the
7001 6995 * driver should copy the status and the other corresponding
7002 6996 * register values in the D2H Register FIS received (It's
7003 6997 * working on Non-data protocol) from the device back to
7004 6998 * the sata_cmd.
7005 6999 *
7006 7000 * For every AHCI port, there is only one Received FIS
7007 7001 * structure, which contains the FISes received from the
7008 7002 * device, So we're trying to copy the content of D2H
7009 7003 * Register FIS in the Received FIS structure back to
7010 7004 * the sata_cmd.
7011 7005 */
7012 7006 if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
7013 7007 rcvd_fisp = &(ahci_portp->ahciport_rcvd_fis->
7014 7008 ahcirf_d2h_register_fis);
7015 7009 satapkt->satapkt_cmd.satacmd_status_reg =
7016 7010 GET_RFIS_STATUS(rcvd_fisp);
7017 7011 ahci_copy_out_regs(&satapkt->satapkt_cmd, rcvd_fisp);
7018 7012 }
7019 7013
7020 7014 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7021 7015 "ahci_intr_cmd_cmplt: sending up pkt 0x%p "
7022 7016 "with SATA_PKT_COMPLETED", (void *)satapkt);
7023 7017
7024 7018 CLEAR_BIT(ahci_portp->ahciport_pending_tags, finished_slot);
7025 7019 CLEAR_BIT(finished_tags, finished_slot);
7026 7020 ahci_portp->ahciport_slot_pkts[finished_slot] = NULL;
7027 7021
7028 7022 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
7029 7023 }
7030 7024 out:
7031 7025 AHCIDBG(AHCIDBG_PKTCOMP, ahci_ctlp,
7032 7026 "ahci_intr_cmd_cmplt: pending_tags = 0x%x",
7033 7027 ahci_portp->ahciport_pending_tags);
7034 7028
7035 7029 ahci_flush_doneq(ahci_portp);
7036 7030
7037 7031 mutex_exit(&ahci_portp->ahciport_mutex);
7038 7032
7039 7033 return (AHCI_SUCCESS);
7040 7034 }
7041 7035
7042 7036 /*
7043 7037 * AHCI_INTR_STATUS_SDBS means a Set Device Bits FIS has been received
7044 7038 * with the 'I' bit set and has been copied into system memory. It will
7045 7039 * be sent under the following situations:
7046 7040 *
7047 7041 * 1. NCQ command is completed
7048 7042 *
7049 7043 * The completion of NCQ commands (READ/WRITE FPDMA QUEUED) is performed
7050 7044 * via the Set Device Bits FIS. When such event is generated, the software
7051 7045 * needs to read PxSACT register and compares the current value to the
7052 7046 * list of commands previously issue by software. ahciport_pending_ncq_tags
7053 7047 * keeps the tags of previously issued commands.
7054 7048 *
7055 7049 * 2. Asynchronous Notification
7056 7050 *
7057 7051 * Asynchronous Notification is a feature in SATA spec 2.6.
7058 7052 *
7059 7053 * 1) ATAPI device will send a signal to the host when media is inserted or
7060 7054 * removed and avoids polling the device for media changes. The signal
7061 7055 * sent to the host is a Set Device Bits FIS with the 'I' and 'N' bits
7062 7056 * set to '1'. At the moment, it's not supported yet.
7063 7057 *
7064 7058 * 2) Port multiplier will send a signal to the host when a hot plug event
7065 7059 * has occured on a port multiplier port. It is used when command based
7066 7060 * switching is employed. This is handled by ahci_intr_pmult_sntf_events()
7067 7061 */
7068 7062 static int
7069 7063 ahci_intr_set_device_bits(ahci_ctl_t *ahci_ctlp,
7070 7064 ahci_port_t *ahci_portp, uint8_t port)
7071 7065 {
7072 7066 ahci_addr_t addr;
7073 7067
7074 7068 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
7075 7069 "ahci_intr_set_device_bits enter: port %d", port);
7076 7070
7077 7071 /* Initialize HBA port address */
7078 7072 AHCI_ADDR_SET_PORT(&addr, port);
7079 7073
7080 7074 /* NCQ plug handler */
7081 7075 (void) ahci_intr_ncq_events(ahci_ctlp, ahci_portp, &addr);
7082 7076
7083 7077 /* Check port multiplier's asynchronous notification events */
7084 7078 if (ahci_ctlp->ahcictl_cap & AHCI_CAP_SNTF) {
7085 7079 (void) ahci_intr_pmult_sntf_events(ahci_ctlp,
7086 7080 ahci_portp, port);
7087 7081 }
7088 7082
7089 7083 /* ATAPI events is not supported yet */
7090 7084
7091 7085 return (AHCI_SUCCESS);
7092 7086 }
7093 7087 /*
7094 7088 * NCQ interrupt handler. Called upon a NCQ command is completed.
7095 7089 * Only be called from ahci_intr_set_device_bits().
7096 7090 */
7097 7091 static int
7098 7092 ahci_intr_ncq_events(ahci_ctl_t *ahci_ctlp,
7099 7093 ahci_port_t *ahci_portp, ahci_addr_t *addrp)
7100 7094 {
7101 7095 uint32_t port_sactive;
7102 7096 uint32_t port_cmd_issue;
7103 7097 uint32_t issued_tags;
7104 7098 int issued_slot;
7105 7099 uint32_t finished_tags;
7106 7100 int finished_slot;
7107 7101 uint8_t port = addrp->aa_port;
7108 7102 sata_pkt_t *satapkt;
7109 7103
7110 7104 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7111 7105 "ahci_intr_set_device_bits enter: port %d", port);
7112 7106
7113 7107 mutex_enter(&ahci_portp->ahciport_mutex);
7114 7108 if (!NCQ_CMD_IN_PROGRESS(ahci_portp)) {
7115 7109 mutex_exit(&ahci_portp->ahciport_mutex);
7116 7110 return (AHCI_SUCCESS);
7117 7111 }
7118 7112
7119 7113 /*
7120 7114 * First the handler got which commands are finished by checking
7121 7115 * PxSACT register
7122 7116 */
7123 7117 port_sactive = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7124 7118 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
7125 7119
7126 7120 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
7127 7121 ~port_sactive & AHCI_NCQ_SLOT_MASK(ahci_portp);
7128 7122
7129 7123 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7130 7124 "ahci_intr_set_device_bits: port %d pending_ncq_tags = 0x%x "
7131 7125 "port_sactive = 0x%x", port,
7132 7126 ahci_portp->ahciport_pending_ncq_tags, port_sactive);
7133 7127
7134 7128 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7135 7129 "ahci_intr_set_device_bits: finished_tags = 0x%x", finished_tags);
7136 7130
7137 7131 /*
7138 7132 * For NCQ commands, the software can determine which command has
7139 7133 * already been transmitted to the device by checking PxCI register.
7140 7134 */
7141 7135 port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7142 7136 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
7143 7137
7144 7138 issued_tags = ahci_portp->ahciport_pending_tags &
7145 7139 ~port_cmd_issue & AHCI_SLOT_MASK(ahci_ctlp);
7146 7140
7147 7141 /* If the PxSACT/PxCI corrupts, don't complete the NCQ commmands. */
7148 7142 if (ahci_check_acc_handle(ahci_ctlp->ahcictl_ahci_acc_handle)
7149 7143 != DDI_FM_OK) {
7150 7144 mutex_exit(&ahci_portp->ahciport_mutex);
7151 7145 return (AHCI_FAILURE);
7152 7146 }
7153 7147
7154 7148 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7155 7149 "ahci_intr_set_device_bits: port %d pending_tags = 0x%x "
7156 7150 "port_cmd_issue = 0x%x", port,
7157 7151 ahci_portp->ahciport_pending_tags, port_cmd_issue);
7158 7152
7159 7153 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7160 7154 "ahci_intr_set_device_bits: issued_tags = 0x%x", issued_tags);
7161 7155
7162 7156 /*
7163 7157 * Clear ahciport_pending_tags bit when the corresponding command
7164 7158 * is already sent down to the device.
7165 7159 */
7166 7160 while (issued_tags) {
7167 7161 issued_slot = ddi_ffs(issued_tags) - 1;
7168 7162 if (issued_slot == -1) {
7169 7163 goto next;
7170 7164 }
7171 7165 CLEAR_BIT(ahci_portp->ahciport_pending_tags, issued_slot);
7172 7166 CLEAR_BIT(issued_tags, issued_slot);
7173 7167 }
7174 7168
7175 7169 next:
7176 7170 while (finished_tags) {
7177 7171 finished_slot = ddi_ffs(finished_tags) - 1;
7178 7172 if (finished_slot == -1) {
7179 7173 goto out;
7180 7174 }
7181 7175
7182 7176 /* The command is certainly transmitted to the device */
7183 7177 ASSERT(!(ahci_portp->ahciport_pending_tags &
7184 7178 (0x1 << finished_slot)));
7185 7179
7186 7180 satapkt = ahci_portp->ahciport_slot_pkts[finished_slot];
7187 7181 ASSERT(satapkt != NULL);
7188 7182
7189 7183 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7190 7184 "ahci_intr_set_device_bits: sending up pkt 0x%p "
7191 7185 "with SATA_PKT_COMPLETED", (void *)satapkt);
7192 7186
7193 7187 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags, finished_slot);
7194 7188 CLEAR_BIT(finished_tags, finished_slot);
7195 7189 ahci_portp->ahciport_slot_pkts[finished_slot] = NULL;
7196 7190
7197 7191 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
7198 7192 }
7199 7193 out:
7200 7194 AHCIDBG(AHCIDBG_PKTCOMP|AHCIDBG_NCQ, ahci_ctlp,
7201 7195 "ahci_intr_set_device_bits: port %d "
7202 7196 "pending_ncq_tags = 0x%x pending_tags = 0x%x",
7203 7197 port, ahci_portp->ahciport_pending_ncq_tags,
7204 7198 ahci_portp->ahciport_pending_tags);
7205 7199
7206 7200 ahci_flush_doneq(ahci_portp);
7207 7201
7208 7202 mutex_exit(&ahci_portp->ahciport_mutex);
7209 7203
7210 7204 return (AHCI_SUCCESS);
7211 7205 }
7212 7206
7213 7207 /*
7214 7208 * Port multiplier asynchronous notification event handler. Called upon a
7215 7209 * device is hot plugged/pulled.
7216 7210 *
7217 7211 * The async-notification event will only be recorded by ahcipmi_snotif_tags
7218 7212 * here and will be handled by ahci_probe_pmult().
7219 7213 *
7220 7214 * NOTE: called only from ahci_port_intr().
7221 7215 */
7222 7216 static int
7223 7217 ahci_intr_pmult_sntf_events(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
7224 7218 uint8_t port)
7225 7219 {
7226 7220 sata_device_t sdevice;
7227 7221
7228 7222 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
7229 7223 "ahci_intr_pmult_sntf_events enter: port %d ", port);
7230 7224
7231 7225 /* no hot-plug while attaching process */
7232 7226 mutex_enter(&ahci_ctlp->ahcictl_mutex);
7233 7227 if (ahci_ctlp->ahcictl_flags & AHCI_ATTACH) {
7234 7228 mutex_exit(&ahci_ctlp->ahcictl_mutex);
7235 7229 return (AHCI_SUCCESS);
7236 7230 }
7237 7231 mutex_exit(&ahci_ctlp->ahcictl_mutex);
7238 7232
7239 7233 mutex_enter(&ahci_portp->ahciport_mutex);
7240 7234 if (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) {
7241 7235 mutex_exit(&ahci_portp->ahciport_mutex);
7242 7236 return (AHCI_SUCCESS);
7243 7237 }
7244 7238
7245 7239 ASSERT(ahci_portp->ahciport_pmult_info != NULL);
7246 7240
7247 7241 ahci_portp->ahciport_pmult_info->ahcipmi_snotif_tags =
7248 7242 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7249 7243 (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp, port));
7250 7244 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
7251 7245 (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp, port),
7252 7246 AHCI_SNOTIF_CLEAR_ALL);
7253 7247
7254 7248 if (ahci_portp->ahciport_pmult_info->ahcipmi_snotif_tags == 0) {
7255 7249 mutex_exit(&ahci_portp->ahciport_mutex);
7256 7250 return (AHCI_SUCCESS);
7257 7251 }
7258 7252
7259 7253 /* Port Multiplier sub-device hot-plug handler */
7260 7254 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
7261 7255 mutex_exit(&ahci_portp->ahciport_mutex);
7262 7256 return (AHCI_SUCCESS);
7263 7257 }
7264 7258
7265 7259 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_PMULT_SNTF) {
7266 7260 /* Not allowed to re-enter. */
7267 7261 mutex_exit(&ahci_portp->ahciport_mutex);
7268 7262 return (AHCI_SUCCESS);
7269 7263 }
7270 7264
7271 7265 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_PMULT_SNTF;
7272 7266
7273 7267 /*
7274 7268 * NOTE:
7275 7269 * Even if Asynchronous Notification is supported (and enabled) by
7276 7270 * both controller and the port multiplier, the content of PxSNTF
7277 7271 * register is always set to 0x8000 by async notification event. We
7278 7272 * need to check GSCR[32] on the port multiplier to find out the
7279 7273 * owner of this event.
7280 7274 * This is not accord with SATA spec 2.6 and needs further
7281 7275 * clarification.
7282 7276 */
7283 7277 /* hot-plug will not reported while reseting. */
7284 7278 if (ahci_portp->ahciport_reset_in_progress == 1) {
7285 7279 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
7286 7280 "port %d snotif event ignored", port);
7287 7281 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_PMULT_SNTF;
7288 7282 mutex_exit(&ahci_portp->ahciport_mutex);
7289 7283 return (AHCI_SUCCESS);
7290 7284 }
7291 7285
7292 7286 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
7293 7287 "PxSNTF is set to 0x%x by port multiplier",
7294 7288 ahci_portp->ahciport_pmult_info->ahcipmi_snotif_tags);
7295 7289
7296 7290 /*
7297 7291 * Now we need do some necessary operation and inform SATA framework
7298 7292 * that link/device events has happened.
7299 7293 */
7300 7294 bzero((void *)&sdevice, sizeof (sata_device_t));
7301 7295 sdevice.satadev_addr.cport = ahci_ctlp->
7302 7296 ahcictl_port_to_cport[port];
7303 7297 sdevice.satadev_addr.pmport = SATA_PMULT_HOSTPORT;
7304 7298 sdevice.satadev_addr.qual = SATA_ADDR_PMULT;
7305 7299 sdevice.satadev_state = SATA_PSTATE_PWRON;
7306 7300
7307 7301 /* Just reject packets, do not stop that port. */
7308 7302 ahci_reject_all_abort_pkts(ahci_ctlp, ahci_portp, port);
7309 7303
7310 7304 mutex_exit(&ahci_portp->ahciport_mutex);
7311 7305 sata_hba_event_notify(
7312 7306 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
7313 7307 &sdevice,
7314 7308 SATA_EVNT_PMULT_LINK_CHANGED);
7315 7309 mutex_enter(&ahci_portp->ahciport_mutex);
7316 7310
7317 7311 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_PMULT_SNTF;
7318 7312 mutex_exit(&ahci_portp->ahciport_mutex);
7319 7313
7320 7314 return (AHCI_SUCCESS);
7321 7315 }
7322 7316
7323 7317 /*
7324 7318 * 1=Change in Current Connect Status. 0=No change in Current Connect Status.
7325 7319 * This bit reflects the state of PxSERR.DIAG.X. This bit is only cleared
7326 7320 * when PxSERR.DIAG.X is cleared. When PxSERR.DIAG.X is set to one, it
7327 7321 * indicates a COMINIT signal was received.
7328 7322 *
7329 7323 * Hot plug insertion is detected by reception of a COMINIT signal from the
7330 7324 * device. On reception of unsolicited COMINIT, the HBA shall generate a
7331 7325 * COMRESET. If the COMINIT is in responce to a COMRESET, then the HBA shall
7332 7326 * begin the normal communication negotiation sequence as outlined in the
7333 7327 * Serial ATA 1.0a specification. When a COMRESET is sent to the device the
7334 7328 * PxSSTS.DET field shall be cleared to 0h. When a COMINIT is received, the
7335 7329 * PxSSTS.DET field shall be set to 1h. When the communication negotiation
7336 7330 * sequence is complete and PhyRdy is true the PxSSTS.DET field shall be set
7337 7331 * to 3h. Therefore, at the moment the ahci driver is going to check PhyRdy
7338 7332 * to handle hot plug insertion. In this interrupt handler, just do nothing
7339 7333 * but print some log message and clear the bit.
7340 7334 */
7341 7335 static int
7342 7336 ahci_intr_port_connect_change(ahci_ctl_t *ahci_ctlp,
7343 7337 ahci_port_t *ahci_portp, uint8_t port)
7344 7338 {
7345 7339 #if AHCI_DEBUG
7346 7340 uint32_t port_serror;
7347 7341 #endif
7348 7342
7349 7343 mutex_enter(&ahci_portp->ahciport_mutex);
7350 7344
7351 7345 #if AHCI_DEBUG
7352 7346 port_serror = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7353 7347 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port));
7354 7348
7355 7349 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY, ahci_ctlp,
7356 7350 "ahci_intr_port_connect_change: port %d, "
7357 7351 "port_serror = 0x%x", port, port_serror);
7358 7352 #endif
7359 7353
7360 7354 /* Clear PxSERR.DIAG.X to clear the interrupt bit */
7361 7355 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
7362 7356 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
7363 7357 SERROR_EXCHANGED_ERR);
7364 7358
7365 7359 mutex_exit(&ahci_portp->ahciport_mutex);
7366 7360
7367 7361 return (AHCI_SUCCESS);
7368 7362 }
7369 7363
7370 7364 /*
7371 7365 * Hot Plug Operation for platforms that support Mechanical Presence
7372 7366 * Switches.
7373 7367 *
7374 7368 * When set, it indicates that a mechanical presence switch attached to this
7375 7369 * port has been opened or closed, which may lead to a change in the connection
7376 7370 * state of the device. This bit is only valid if both CAP.SMPS and PxCMD.MPSP
7377 7371 * are set to '1'.
7378 7372 *
7379 7373 * At the moment, this interrupt is not needed and disabled and we just log
7380 7374 * the debug message.
7381 7375 */
7382 7376 static int
7383 7377 ahci_intr_device_mechanical_presence_status(ahci_ctl_t *ahci_ctlp,
7384 7378 ahci_port_t *ahci_portp, uint8_t port)
7385 7379 {
7386 7380 uint32_t cap_status, port_cmd_status;
7387 7381
7388 7382 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY, ahci_ctlp,
7389 7383 "ahci_intr_device_mechanical_presence_status enter, "
7390 7384 "port %d", port);
7391 7385
7392 7386 cap_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7393 7387 (uint32_t *)AHCI_GLOBAL_CAP(ahci_ctlp));
7394 7388
7395 7389 mutex_enter(&ahci_portp->ahciport_mutex);
7396 7390 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7397 7391 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
7398 7392
7399 7393 if (!(cap_status & AHCI_HBA_CAP_SMPS) ||
7400 7394 !(port_cmd_status & AHCI_CMD_STATUS_MPSP)) {
7401 7395 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7402 7396 "CAP.SMPS or PxCMD.MPSP is not set, so just ignore "
7403 7397 "the interrupt: cap_status = 0x%x, "
7404 7398 "port_cmd_status = 0x%x", cap_status, port_cmd_status);
7405 7399 mutex_exit(&ahci_portp->ahciport_mutex);
7406 7400
7407 7401 return (AHCI_SUCCESS);
7408 7402 }
7409 7403
7410 7404 #if AHCI_DEBUG
7411 7405 if (port_cmd_status & AHCI_CMD_STATUS_MPSS) {
7412 7406 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7413 7407 "The mechanical presence switch is open: "
7414 7408 "port %d, port_cmd_status = 0x%x",
7415 7409 port, port_cmd_status);
7416 7410 } else {
7417 7411 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7418 7412 "The mechanical presence switch is close: "
7419 7413 "port %d, port_cmd_status = 0x%x",
7420 7414 port, port_cmd_status);
7421 7415 }
7422 7416 #endif
7423 7417
7424 7418 mutex_exit(&ahci_portp->ahciport_mutex);
7425 7419
7426 7420 return (AHCI_SUCCESS);
7427 7421 }
7428 7422
7429 7423 /*
7430 7424 * Native Hot Plug Support.
7431 7425 *
7432 7426 * When set, it indicates that the internal PHYRDY signal changed state.
7433 7427 * This bit reflects the state of PxSERR.DIAG.N.
7434 7428 *
7435 7429 * There are three kinds of conditions to generate this interrupt event:
7436 7430 * 1. a device is inserted
7437 7431 * 2. a device is disconnected
7438 7432 * 3. when the link enters/exits a Partial or Slumber interface power
7439 7433 * management state
7440 7434 *
7441 7435 * If inteface power management is enabled for a port, the PxSERR.DIAG.N
7442 7436 * bit may be set due to the link entering the Partial or Slumber power
7443 7437 * management state, rather than due to a hot plug insertion or removal
7444 7438 * event. So far, the interface power management is disabled, so the
7445 7439 * driver can reliably get removal detection notification via the
7446 7440 * PxSERR.DIAG.N bit.
7447 7441 */
7448 7442 static int
7449 7443 ahci_intr_phyrdy_change(ahci_ctl_t *ahci_ctlp,
7450 7444 ahci_port_t *ahci_portp, uint8_t port)
7451 7445 {
7452 7446 uint32_t port_sstatus = 0; /* No dev present & PHY not established. */
7453 7447 sata_device_t sdevice;
7454 7448 int dev_exists_now = 0;
7455 7449 int dev_existed_previously = 0;
7456 7450 ahci_addr_t port_addr;
7457 7451
7458 7452 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY, ahci_ctlp,
7459 7453 "ahci_intr_phyrdy_change enter, port %d", port);
7460 7454
7461 7455 /* Clear PxSERR.DIAG.N to clear the interrupt bit */
7462 7456 mutex_enter(&ahci_portp->ahciport_mutex);
7463 7457 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
7464 7458 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
7465 7459 SERROR_PHY_RDY_CHG);
7466 7460 mutex_exit(&ahci_portp->ahciport_mutex);
7467 7461
7468 7462 mutex_enter(&ahci_ctlp->ahcictl_mutex);
7469 7463 if ((ahci_ctlp->ahcictl_sata_hba_tran == NULL) ||
7470 7464 (ahci_portp == NULL)) {
7471 7465 /* The whole controller setup is not yet done. */
7472 7466 mutex_exit(&ahci_ctlp->ahcictl_mutex);
7473 7467 return (AHCI_SUCCESS);
7474 7468 }
7475 7469 mutex_exit(&ahci_ctlp->ahcictl_mutex);
7476 7470
7477 7471 mutex_enter(&ahci_portp->ahciport_mutex);
7478 7472
7479 7473 /* SStatus tells the presence of device. */
7480 7474 port_sstatus = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7481 7475 (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp, port));
7482 7476
7483 7477 if (SSTATUS_GET_DET(port_sstatus) == SSTATUS_DET_DEVPRE_PHYCOM) {
7484 7478 dev_exists_now = 1;
7485 7479 }
7486 7480
7487 7481 if (ahci_portp->ahciport_device_type != SATA_DTYPE_NONE) {
7488 7482 dev_existed_previously = 1;
7489 7483 }
7490 7484
7491 7485 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_NODEV) {
7492 7486 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_NODEV;
7493 7487 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
7494 7488 "ahci_intr_phyrdy_change: port %d "
7495 7489 "AHCI_PORT_FLAG_NODEV is cleared", port);
7496 7490 if (dev_exists_now == 0)
7497 7491 dev_existed_previously = 1;
7498 7492 }
7499 7493
7500 7494 bzero((void *)&sdevice, sizeof (sata_device_t));
7501 7495 sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
7502 7496 sdevice.satadev_addr.qual = SATA_ADDR_CPORT;
7503 7497 sdevice.satadev_addr.pmport = 0;
7504 7498 sdevice.satadev_state = SATA_PSTATE_PWRON;
7505 7499 ahci_portp->ahciport_port_state = SATA_PSTATE_PWRON;
7506 7500
7507 7501 AHCI_ADDR_SET_PORT(&port_addr, port);
7508 7502
7509 7503 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_HOTPLUG;
7510 7504 if (dev_exists_now) {
7511 7505 if (dev_existed_previously) { /* 1 -> 1 */
7512 7506 /* Things are fine now. The loss was temporary. */
7513 7507 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
7514 7508 "ahci_intr_phyrdy_change port %d "
7515 7509 "device link lost/established", port);
7516 7510
7517 7511 mutex_exit(&ahci_portp->ahciport_mutex);
7518 7512 sata_hba_event_notify(
7519 7513 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
7520 7514 &sdevice,
7521 7515 SATA_EVNT_LINK_LOST|SATA_EVNT_LINK_ESTABLISHED);
7522 7516 mutex_enter(&ahci_portp->ahciport_mutex);
7523 7517
7524 7518 } else { /* 0 -> 1 */
7525 7519 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
7526 7520 "ahci_intr_phyrdy_change: port %d "
7527 7521 "device link established", port);
7528 7522
7529 7523 /*
7530 7524 * A new device has been detected. The new device
7531 7525 * might be a port multiplier instead of a drive, so
7532 7526 * we cannot update the signature directly.
7533 7527 */
7534 7528 (void) ahci_initialize_port(ahci_ctlp,
7535 7529 ahci_portp, &port_addr);
7536 7530
7537 7531 /* Try to start the port */
7538 7532 if (ahci_start_port(ahci_ctlp, ahci_portp, port)
7539 7533 != AHCI_SUCCESS) {
7540 7534 sdevice.satadev_state |= SATA_PSTATE_FAILED;
7541 7535 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
7542 7536 "ahci_intr_phyrdy_change: port %d failed "
7543 7537 "at start port", port);
7544 7538 }
7545 7539
7546 7540 /* Clear the max queue depth for inserted device */
7547 7541 ahci_portp->ahciport_max_ncq_tags = 0;
7548 7542
7549 7543 mutex_exit(&ahci_portp->ahciport_mutex);
7550 7544 sata_hba_event_notify(
7551 7545 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
7552 7546 &sdevice,
7553 7547 SATA_EVNT_LINK_ESTABLISHED);
7554 7548 mutex_enter(&ahci_portp->ahciport_mutex);
7555 7549
7556 7550 }
7557 7551 } else { /* No device exists now */
7558 7552
7559 7553 if (dev_existed_previously) { /* 1 -> 0 */
7560 7554 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
7561 7555 "ahci_intr_phyrdy_change: port %d "
7562 7556 "device link lost", port);
7563 7557
7564 7558 ahci_reject_all_abort_pkts(ahci_ctlp, ahci_portp, port);
7565 7559 (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
7566 7560 ahci_portp, port);
7567 7561
7568 7562 if (ahci_portp->ahciport_device_type ==
7569 7563 SATA_DTYPE_PMULT) {
7570 7564 ahci_dealloc_pmult(ahci_ctlp, ahci_portp);
7571 7565 }
7572 7566
7573 7567 /* An existing device is lost. */
7574 7568 ahci_portp->ahciport_device_type = SATA_DTYPE_NONE;
7575 7569 ahci_portp->ahciport_port_state = SATA_STATE_UNKNOWN;
7576 7570
7577 7571 mutex_exit(&ahci_portp->ahciport_mutex);
7578 7572 sata_hba_event_notify(
7579 7573 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
7580 7574 &sdevice,
7581 7575 SATA_EVNT_LINK_LOST);
7582 7576 mutex_enter(&ahci_portp->ahciport_mutex);
7583 7577 }
7584 7578 }
7585 7579 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_HOTPLUG;
7586 7580
7587 7581 mutex_exit(&ahci_portp->ahciport_mutex);
7588 7582
7589 7583 return (AHCI_SUCCESS);
7590 7584 }
7591 7585
7592 7586 /*
7593 7587 * PxIS.UFS - Unknown FIS Error
7594 7588 *
7595 7589 * This interrupt event means an unknown FIS was received and has been
7596 7590 * copied into system memory. An unknown FIS is not considered an illegal
7597 7591 * FIS, unless the length received is more than 64 bytes. If an unknown
7598 7592 * FIS arrives with length <= 64 bytes, it is posted and the HBA continues
7599 7593 * normal operation. If the unknown FIS is more than 64 bytes, then it
7600 7594 * won't be posted to memory and PxSERR.ERR.P will be set, which is then
7601 7595 * a fatal error.
7602 7596 *
7603 7597 * PxIS.IPMS - Incorrect Port Multiplier Status
7604 7598 *
7605 7599 * IPMS Indicates that the HBA received a FIS from a device that did not
7606 7600 * have a command outstanding. The IPMS bit may be set during enumeration
7607 7601 * of devices on a Port Multiplier due to the normal Port Multiplier
7608 7602 * enumeration process. It is recommended that IPMS only be used after
7609 7603 * enumeration is complete on the Port Multiplier (copied from spec).
7610 7604 *
7611 7605 * PxIS.OFS - Overflow Error
7612 7606 *
7613 7607 * Command list overflow is defined as software building a command table
7614 7608 * that has fewer total bytes than the transaction given to the device.
7615 7609 * On device writes, the HBA will run out of data, and on reads, there
7616 7610 * will be no room to put the data.
7617 7611 *
7618 7612 * For an overflow on data read, either PIO or DMA, the HBA will set
7619 7613 * PxIS.OFS, and the HBA will do a best effort to continue, and it's a
7620 7614 * non-fatal error when the HBA can continues. Sometimes, it will cause
7621 7615 * a fatal error and need the software to do something.
7622 7616 *
7623 7617 * For an overflow on data write, setting PxIS.OFS is optional for both
7624 7618 * DMA and PIO, and it's a fatal error, and a COMRESET is required by
7625 7619 * software to clean up from this serious error.
7626 7620 *
7627 7621 * PxIS.INFS - Interface Non-Fatal Error
7628 7622 *
7629 7623 * This interrupt event indicates that the HBA encountered an error on
7630 7624 * the Serial ATA interface but was able to continue operation. The kind
7631 7625 * of error usually occurred during a non-Data FIS, and under this condition
7632 7626 * the FIS will be re-transmitted by HBA automatically.
7633 7627 *
7634 7628 * When the FMA is implemented, there should be a stat structure to
7635 7629 * record how many every kind of error happens.
7636 7630 */
7637 7631 static int
7638 7632 ahci_intr_non_fatal_error(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
7639 7633 uint8_t port, uint32_t intr_status)
7640 7634 {
7641 7635 uint32_t port_serror;
7642 7636 #if AHCI_DEBUG
7643 7637 uint32_t port_cmd_status;
7644 7638 uint32_t port_cmd_issue;
7645 7639 uint32_t port_sactive;
7646 7640 int current_slot;
7647 7641 uint32_t current_tags;
7648 7642 sata_pkt_t *satapkt;
7649 7643 ahci_cmd_header_t *cmd_header;
7650 7644 uint32_t cmd_dmacount;
7651 7645 #endif
7652 7646
7653 7647 mutex_enter(&ahci_portp->ahciport_mutex);
7654 7648
7655 7649 port_serror = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7656 7650 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port));
7657 7651
7658 7652 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY|AHCIDBG_ERRS, ahci_ctlp,
7659 7653 "ahci_intr_non_fatal_error: port %d, "
7660 7654 "PxSERR = 0x%x, PxIS = 0x%x ", port, port_serror, intr_status);
7661 7655
7662 7656 ahci_log_serror_message(ahci_ctlp, port, port_serror, 1);
7663 7657
7664 7658 if (intr_status & AHCI_INTR_STATUS_UFS) {
7665 7659 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
7666 7660 "ahci port %d has unknown FIS error", port);
7667 7661
7668 7662 /* Clear the interrupt bit by clearing PxSERR.DIAG.F */
7669 7663 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
7670 7664 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
7671 7665 SERROR_FIS_TYPE);
7672 7666 }
7673 7667
7674 7668 #if AHCI_DEBUG
7675 7669 if (intr_status & AHCI_INTR_STATUS_IPMS) {
7676 7670 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci port %d "
7677 7671 "has Incorrect Port Multiplier Status error", port);
7678 7672 }
7679 7673
7680 7674 if (intr_status & AHCI_INTR_STATUS_OFS) {
7681 7675 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7682 7676 "ahci port %d has overflow error", port);
7683 7677 }
7684 7678
7685 7679 if (intr_status & AHCI_INTR_STATUS_INFS) {
7686 7680 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7687 7681 "ahci port %d has interface non fatal error", port);
7688 7682 }
7689 7683
7690 7684 /*
7691 7685 * Record the error occurred command's slot.
7692 7686 */
7693 7687 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp) ||
7694 7688 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
7695 7689 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7696 7690 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
7697 7691
7698 7692 current_slot = (port_cmd_status & AHCI_CMD_STATUS_CCS) >>
7699 7693 AHCI_CMD_STATUS_CCS_SHIFT;
7700 7694
7701 7695 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
7702 7696 satapkt = ahci_portp->ahciport_err_retri_pkt;
7703 7697 ASSERT(satapkt != NULL);
7704 7698 ASSERT(current_slot == 0);
7705 7699 } else {
7706 7700 satapkt = ahci_portp->ahciport_slot_pkts[current_slot];
7707 7701 }
7708 7702
7709 7703 if (satapkt != NULL) {
7710 7704 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7711 7705 "ahci_intr_non_fatal_error: pending_tags = 0x%x "
7712 7706 "cmd 0x%x", ahci_portp->ahciport_pending_tags,
7713 7707 satapkt->satapkt_cmd.satacmd_cmd_reg);
7714 7708
7715 7709 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7716 7710 "ahci_intr_non_fatal_error: port %d, "
7717 7711 "satapkt 0x%p is being processed when error occurs",
7718 7712 port, (void *)satapkt);
7719 7713
7720 7714 /*
7721 7715 * PRD Byte Count field of command header is not
7722 7716 * required to reflect the total number of bytes
7723 7717 * transferred when an overflow occurs, so here
7724 7718 * just log the value.
7725 7719 */
7726 7720 cmd_dmacount =
7727 7721 ahci_portp->ahciport_prd_bytecounts[current_slot];
7728 7722 if (cmd_dmacount) {
7729 7723 cmd_header = &ahci_portp->
7730 7724 ahciport_cmd_list[current_slot];
7731 7725 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7732 7726 "ahci_intr_non_fatal_error: port %d, "
7733 7727 "PRD Byte Count = 0x%x, "
7734 7728 "ahciport_prd_bytecounts = 0x%x", port,
7735 7729 cmd_header->ahcich_prd_byte_count,
7736 7730 cmd_dmacount);
7737 7731 }
7738 7732 }
7739 7733 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
7740 7734 /*
7741 7735 * For queued command, list those command which have already
7742 7736 * been transmitted to the device and still not completed.
7743 7737 */
7744 7738 port_sactive = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7745 7739 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
7746 7740
7747 7741 port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7748 7742 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
7749 7743
7750 7744 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ|AHCIDBG_ERRS, ahci_ctlp,
7751 7745 "ahci_intr_non_fatal_error: pending_ncq_tags = 0x%x "
7752 7746 "port_sactive = 0x%x port_cmd_issue = 0x%x",
7753 7747 ahci_portp->ahciport_pending_ncq_tags,
7754 7748 port_sactive, port_cmd_issue);
7755 7749
7756 7750 current_tags = ahci_portp->ahciport_pending_ncq_tags &
7757 7751 port_sactive & ~port_cmd_issue &
7758 7752 AHCI_NCQ_SLOT_MASK(ahci_portp);
7759 7753
7760 7754 while (current_tags) {
7761 7755 current_slot = ddi_ffs(current_tags) - 1;
7762 7756 if (current_slot == -1) {
7763 7757 goto out;
7764 7758 }
7765 7759
7766 7760 satapkt = ahci_portp->ahciport_slot_pkts[current_slot];
7767 7761 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ|AHCIDBG_ERRS,
7768 7762 ahci_ctlp, "ahci_intr_non_fatal_error: "
7769 7763 "port %d, satapkt 0x%p is outstanding when "
7770 7764 "error occurs", port, (void *)satapkt);
7771 7765
7772 7766 CLEAR_BIT(current_tags, current_slot);
7773 7767 }
7774 7768 }
7775 7769 out:
7776 7770 #endif
7777 7771 mutex_exit(&ahci_portp->ahciport_mutex);
7778 7772
7779 7773 return (AHCI_SUCCESS);
7780 7774 }
7781 7775
7782 7776 /*
7783 7777 * According to the AHCI spec, the error types include system memory
7784 7778 * errors, interface errors, port multiplier errors, device errors,
7785 7779 * command list overflow, command list underflow, native command
7786 7780 * queuing tag errors and pio data transfer errors.
7787 7781 *
7788 7782 * System memory errors such as target abort, master abort, and parity
7789 7783 * may cause the host to stop, and they are serious errors and needed
7790 7784 * to be recovered with software intervention. When system software
7791 7785 * has given a pointer to the HBA that doesn't exist in physical memory,
7792 7786 * a master/target abort error occurs, and PxIS.HBFS will be set. A
7793 7787 * data error such as CRC or parity occurs, the HBA aborts the transfer
7794 7788 * (if necessary) and PxIS.HBDS will be set.
7795 7789 *
7796 7790 * Interface errors are errors that occur due to electrical issues on
7797 7791 * the interface, or protocol miscommunication between the device and
7798 7792 * HBA, and the respective PxSERR register bit will be set. And PxIS.IFS
7799 7793 * (fatal) or PxIS.INFS (non-fatal) will be set. The conditions that
7800 7794 * causes PxIS.IFS/PxIS.INFS to be set are
7801 7795 * 1. in PxSERR.ERR, P bit is set to '1'
7802 7796 * 2. in PxSERR.DIAG, C or H bit is set to '1'
7803 7797 * 3. PhyRdy drop unexpectly, N bit is set to '1'
7804 7798 * If the error occurred during a non-data FIS, the FIS must be
7805 7799 * retransmitted, and the error is non-fatal and PxIS.INFS is set. If
7806 7800 * the error occurred during a data FIS, the transfer will stop, so
7807 7801 * the error is fatal and PxIS.IFS is set.
7808 7802 *
7809 7803 * When a FIS arrives that updates the taskfile, the HBA checks to see
7810 7804 * if PxTFD.STS.ERR is set. If yes, PxIS.TFES will be set and the HBA
7811 7805 * stops processing any more commands.
7812 7806 *
7813 7807 * Command list overflow is defined as software building a command table
7814 7808 * that has fewer total bytes than the transaction given to the device.
7815 7809 * On device writes, the HBA will run out of data, and on reads, there
7816 7810 * will be no room to put the data. For an overflow on data read, either
7817 7811 * PIO or DMA, the HBA will set PxIS.OFS, and it's a non-fatal error.
7818 7812 * For an overflow on data write, setting PxIS.OFS is optional for both
7819 7813 * DMA and PIO, and a COMRESET is required by software to clean up from
7820 7814 * this serious error.
7821 7815 *
7822 7816 * Command list underflow is defined as software building a command
7823 7817 * table that has more total bytes than the transaction given to the
7824 7818 * device. For data writes, both PIO and DMA, the device will detect
7825 7819 * an error and end the transfer. And these errors are most likely going
7826 7820 * to be fatal errors that will cause the port to be restarted. For
7827 7821 * data reads, the HBA updates its PRD byte count, and may be
7828 7822 * able to continue normally, but is not required to. And The HBA is
7829 7823 * not required to detect underflow conditions for native command
7830 7824 * queuing command.
7831 7825 *
7832 7826 * The HBA does not actively check incoming DMA Setup FISes to ensure
7833 7827 * that the PxSACT register bit for that slot is set. Existing error
7834 7828 * mechanisms, such as host bus failure, or bad protocol, are used to
7835 7829 * recover from this case.
7836 7830 *
7837 7831 * In accordance with Serial ATA 1.0a, DATA FISes prior to the final
7838 7832 * DATA FIS must be an integral number of Dwords. If the HBA receives
7839 7833 * a request which is not an integral number of Dwords, the HBA
7840 7834 * set PxSERR.ERR.P to '1', set PxIS.IFS to '1' and stop running until
7841 7835 * software restarts the port. And the HBA ensures that the size
7842 7836 * of the DATA FIS received during a PIO command matches the size in
7843 7837 * the Transfer Cound field of the preceding PIO Setup FIS, if not, the
7844 7838 * HBA sets PxSERR.ERR.P to '1', set PxIS.IFS to '1', and then
7845 7839 * stop running until software restarts the port.
7846 7840 */
7847 7841 /*
7848 7842 * the fatal errors include PxIS.IFS, PxIS.HBDS, PxIS.HBFS and PxIS.TFES.
7849 7843 *
7850 7844 * PxIS.IFS indicates that the hba encountered an error on the serial ata
7851 7845 * interface which caused the transfer to stop.
7852 7846 *
7853 7847 * PxIS.HBDS indicates that the hba encountered a data error
7854 7848 * (uncorrectable ecc/parity) when reading from or writing to system memory.
7855 7849 *
7856 7850 * PxIS.HBFS indicates that the hba encountered a host bus error that it
7857 7851 * cannot recover from, such as a bad software pointer.
7858 7852 *
7859 7853 * PxIS.TFES is set whenever the status register is updated by the device
7860 7854 * and the error bit (bit 0) is set.
7861 7855 */
7862 7856 static int
7863 7857 ahci_intr_fatal_error(ahci_ctl_t *ahci_ctlp,
7864 7858 ahci_port_t *ahci_portp, uint8_t port, uint32_t intr_status)
7865 7859 {
7866 7860 uint32_t port_cmd_status;
7867 7861 uint32_t port_serror;
7868 7862 uint32_t task_file_status;
7869 7863 int failed_slot;
7870 7864 sata_pkt_t *spkt = NULL;
7871 7865 uint8_t err_byte;
7872 7866 ahci_event_arg_t *args;
7873 7867 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
7874 7868 uint32_t failed_tags = 0;
7875 7869 int task_fail_flag = 0, task_abort_flag = 0;
7876 7870 uint32_t slot_status;
7877 7871
7878 7872 mutex_enter(&ahci_portp->ahciport_mutex);
7879 7873
7880 7874 /*
7881 7875 * ahci_intr_phyrdy_change() may have rendered it to
7882 7876 * SATA_DTYPE_NONE.
7883 7877 */
7884 7878 if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
7885 7879 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
7886 7880 "ahci_intr_fatal_error: port %d no device attached, "
7887 7881 "and just return without doing anything", port);
7888 7882 goto out0;
7889 7883 }
7890 7884
7891 7885 if (intr_status & AHCI_INTR_STATUS_TFES) {
7892 7886 task_file_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7893 7887 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
7894 7888 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7895 7889 "ahci_intr_fatal_error: port %d "
7896 7890 "task_file_status = 0x%x", port, task_file_status);
7897 7891 task_fail_flag = 1;
7898 7892
7899 7893 err_byte = (task_file_status & AHCI_TFD_ERR_MASK)
7900 7894 >> AHCI_TFD_ERR_SHIFT;
7901 7895 if (err_byte == SATA_ERROR_ABORT)
7902 7896 task_abort_flag = 1;
7903 7897 }
7904 7898
7905 7899 /*
7906 7900 * Here we just log the fatal error info in interrupt context.
7907 7901 * Misc recovery processing will be handled in task queue.
7908 7902 */
7909 7903 if (task_fail_flag == 1) {
7910 7904 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
7911 7905 /*
7912 7906 * Read PxCMD.CCS to determine the slot that the HBA
7913 7907 * was processing when the error occurred.
7914 7908 */
7915 7909 port_cmd_status = ddi_get32(
7916 7910 ahci_ctlp->ahcictl_ahci_acc_handle,
7917 7911 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
7918 7912 failed_slot = (port_cmd_status & AHCI_CMD_STATUS_CCS) >>
7919 7913 AHCI_CMD_STATUS_CCS_SHIFT;
7920 7914 failed_tags = 0x1 << failed_slot;
7921 7915
7922 7916 spkt = ahci_portp->ahciport_slot_pkts[failed_slot];
7923 7917 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7924 7918 "ahci_intr_fatal_error: spkt 0x%p is being "
7925 7919 "processed when fatal error occurred for port %d",
↓ open down ↓ |
1729 lines elided |
↑ open up ↑ |
7926 7920 spkt, port);
7927 7921
7928 7922 /*
7929 7923 * Won't emit the error message if it is an IDENTIFY
7930 7924 * DEVICE command sent to an ATAPI device.
7931 7925 */
7932 7926 if ((spkt != NULL) &&
7933 7927 (spkt->satapkt_cmd.satacmd_cmd_reg ==
7934 7928 SATAC_ID_DEVICE) &&
7935 7929 (task_abort_flag == 1))
7936 - goto out1;
7930 + goto out1;
7937 7931
7938 7932 /*
7939 7933 * Won't emit the error message if it is an ATAPI PACKET
7940 7934 * command
7941 7935 */
7942 7936 if ((spkt != NULL) &&
7943 7937 (spkt->satapkt_cmd.satacmd_cmd_reg == SATAC_PACKET))
7944 7938 goto out1;
7945 7939
7946 7940 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
7947 7941 slot_status = ddi_get32(
7948 7942 ahci_ctlp->ahcictl_ahci_acc_handle,
7949 7943 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
7950 7944 failed_tags = slot_status &
7951 7945 AHCI_NCQ_SLOT_MASK(ahci_portp);
7952 7946 }
7953 7947 }
7954 7948
7955 7949 /* print the fatal error type */
7956 7950 ahci_log_fatal_error_message(ahci_ctlp, port, intr_status);
7957 7951 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_ERRPRINT;
7958 7952
7959 7953 port_serror = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7960 7954 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port));
7961 7955
7962 7956 /* print PxSERR related error message */
7963 7957 ahci_log_serror_message(ahci_ctlp, port, port_serror, 0);
7964 7958
7965 7959 /* print task file register value */
7966 7960 if (task_fail_flag == 1) {
7967 7961 cmn_err(CE_WARN, "!ahci%d: ahci port %d task_file_status "
7968 7962 "= 0x%x", instance, port, task_file_status);
7969 7963 if (task_abort_flag == 1) {
7970 7964 cmn_err(CE_WARN, "!ahci%d: the below command (s) on "
7971 7965 "port %d are aborted", instance, port);
7972 7966 ahci_dump_commands(ahci_ctlp, port, failed_tags);
7973 7967 }
7974 7968 }
7975 7969
7976 7970 out1:
7977 7971 /* Prepare the argument for the taskq */
7978 7972 args = ahci_portp->ahciport_event_args;
7979 7973 args->ahciea_ctlp = (void *)ahci_ctlp;
7980 7974 args->ahciea_portp = (void *)ahci_portp;
7981 7975 args->ahciea_event = intr_status;
7982 7976 AHCI_ADDR_SET_PORT((ahci_addr_t *)args->ahciea_addrp, port);
7983 7977
7984 7978 /* Start the taskq to handle error recovery */
7985 7979 if ((ddi_taskq_dispatch(ahci_portp->ahciport_event_taskq,
7986 7980 ahci_events_handler,
7987 7981 (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) {
7988 7982 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_ERRPRINT;
7989 7983 cmn_err(CE_WARN, "!ahci%d: start taskq for error recovery "
7990 7984 "port %d failed", instance, port);
7991 7985 }
7992 7986 out0:
7993 7987 mutex_exit(&ahci_portp->ahciport_mutex);
7994 7988
7995 7989 return (AHCI_SUCCESS);
7996 7990 }
7997 7991
7998 7992 /*
7999 7993 * Hot Plug Operation for platforms that support Cold Presence Detect.
8000 7994 *
8001 7995 * When set, a device status has changed as detected by the cold presence
8002 7996 * detect logic. This bit can either be set due to a non-connected port
8003 7997 * receiving a device, or a connected port having its device removed.
8004 7998 * This bit is only valid if the port supports cold presence detect as
8005 7999 * indicated by PxCMD.CPD set to '1'.
8006 8000 *
8007 8001 * At the moment, this interrupt is not needed and disabled and we just
8008 8002 * log the debug message.
8009 8003 */
8010 8004 static int
8011 8005 ahci_intr_cold_port_detect(ahci_ctl_t *ahci_ctlp,
8012 8006 ahci_port_t *ahci_portp, uint8_t port)
8013 8007 {
8014 8008 uint32_t port_cmd_status;
8015 8009 sata_device_t sdevice;
8016 8010
8017 8011 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8018 8012 "ahci_intr_cold_port_detect enter, port %d", port);
8019 8013
8020 8014 mutex_enter(&ahci_portp->ahciport_mutex);
8021 8015
8022 8016 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8023 8017 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
8024 8018 if (!(port_cmd_status & AHCI_CMD_STATUS_CPD)) {
8025 8019 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8026 8020 "port %d does not support cold presence detect, so "
8027 8021 "we just ignore this interrupt", port);
8028 8022 mutex_exit(&ahci_portp->ahciport_mutex);
8029 8023 return (AHCI_SUCCESS);
8030 8024 }
8031 8025
8032 8026 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8033 8027 "port %d device status has changed", port);
8034 8028
8035 8029 bzero((void *)&sdevice, sizeof (sata_device_t));
8036 8030 sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
8037 8031 sdevice.satadev_addr.qual = SATA_ADDR_CPORT;
8038 8032 sdevice.satadev_addr.pmport = 0;
8039 8033 sdevice.satadev_state = SATA_PSTATE_PWRON;
8040 8034
8041 8035 if (port_cmd_status & AHCI_CMD_STATUS_CPS) {
8042 8036 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8043 8037 "port %d: a device is hot plugged", port);
8044 8038 mutex_exit(&ahci_portp->ahciport_mutex);
8045 8039 sata_hba_event_notify(
8046 8040 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
8047 8041 &sdevice,
8048 8042 SATA_EVNT_DEVICE_ATTACHED);
8049 8043 mutex_enter(&ahci_portp->ahciport_mutex);
8050 8044
8051 8045 } else {
8052 8046 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8053 8047 "port %d: a device is hot unplugged", port);
8054 8048 mutex_exit(&ahci_portp->ahciport_mutex);
8055 8049 sata_hba_event_notify(
8056 8050 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
8057 8051 &sdevice,
8058 8052 SATA_EVNT_DEVICE_DETACHED);
8059 8053 mutex_enter(&ahci_portp->ahciport_mutex);
8060 8054 }
8061 8055
8062 8056 mutex_exit(&ahci_portp->ahciport_mutex);
8063 8057
8064 8058 return (AHCI_SUCCESS);
8065 8059 }
8066 8060
8067 8061 /*
8068 8062 * Enable the interrupts for a particular port.
8069 8063 */
8070 8064 static void
8071 8065 ahci_enable_port_intrs(ahci_ctl_t *ahci_ctlp, uint8_t port)
8072 8066 {
8073 8067 ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
8074 8068
8075 8069 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
8076 8070 "ahci_enable_port_intrs enter, port %d", port);
8077 8071
8078 8072 /*
8079 8073 * Clear port interrupt status before enabling interrupt
8080 8074 */
8081 8075 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8082 8076 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port),
8083 8077 AHCI_PORT_INTR_MASK);
8084 8078
8085 8079 /*
8086 8080 * Clear the pending bit from IS.IPS
8087 8081 */
8088 8082 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8089 8083 (uint32_t *)AHCI_GLOBAL_IS(ahci_ctlp), (1 << port));
8090 8084
8091 8085 /*
8092 8086 * Enable the following interrupts:
8093 8087 * Device to Host Register FIS Interrupt (DHRS)
8094 8088 * PIO Setup FIS Interrupt (PSS)
8095 8089 * Set Device Bits Interrupt (SDBS)
8096 8090 * Unknown FIS Interrupt (UFS)
8097 8091 * Port Connect Change Status (PCS)
8098 8092 * PhyRdy Change Status (PRCS)
8099 8093 * Overflow Status (OFS)
8100 8094 * Interface Non-fatal Error Status (INFS)
8101 8095 * Interface Fatal Error Status (IFS)
8102 8096 * Host Bus Data Error Status (HBDS)
8103 8097 * Host Bus Fatal Error Status (HBFS)
8104 8098 * Task File Error Status (TFES)
8105 8099 */
8106 8100 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8107 8101 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port),
8108 8102 (AHCI_INTR_STATUS_DHRS |
8109 8103 AHCI_INTR_STATUS_PSS |
8110 8104 AHCI_INTR_STATUS_SDBS |
8111 8105 AHCI_INTR_STATUS_UFS |
8112 8106 AHCI_INTR_STATUS_DPS |
8113 8107 AHCI_INTR_STATUS_PCS |
8114 8108 AHCI_INTR_STATUS_PRCS |
8115 8109 AHCI_INTR_STATUS_OFS |
8116 8110 AHCI_INTR_STATUS_INFS |
8117 8111 AHCI_INTR_STATUS_IFS |
8118 8112 AHCI_INTR_STATUS_HBDS |
8119 8113 AHCI_INTR_STATUS_HBFS |
8120 8114 AHCI_INTR_STATUS_TFES));
8121 8115 }
8122 8116
8123 8117 /*
8124 8118 * Enable interrupts for all the ports.
8125 8119 */
8126 8120 static void
8127 8121 ahci_enable_all_intrs(ahci_ctl_t *ahci_ctlp)
8128 8122 {
8129 8123 uint32_t ghc_control;
8130 8124
8131 8125 ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_mutex));
8132 8126
8133 8127 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_enable_all_intrs enter", NULL);
8134 8128
8135 8129 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8136 8130 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
8137 8131
8138 8132 ghc_control |= AHCI_HBA_GHC_IE;
8139 8133
8140 8134 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8141 8135 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
8142 8136 }
8143 8137
8144 8138 /*
8145 8139 * Disable interrupts for a particular port.
8146 8140 */
8147 8141 static void
8148 8142 ahci_disable_port_intrs(ahci_ctl_t *ahci_ctlp, uint8_t port)
8149 8143 {
8150 8144 ASSERT(ahci_ctlp->ahcictl_flags & AHCI_QUIESCE ||
8151 8145 MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
8152 8146
8153 8147 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
8154 8148 "ahci_disable_port_intrs enter, port %d", port);
8155 8149
8156 8150 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8157 8151 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port), 0);
8158 8152 }
8159 8153
8160 8154 /*
8161 8155 * Disable interrupts for the whole HBA.
8162 8156 *
8163 8157 * The global bit is cleared, then all interrupt sources from all
8164 8158 * ports are disabled.
8165 8159 */
8166 8160 static void
8167 8161 ahci_disable_all_intrs(ahci_ctl_t *ahci_ctlp)
8168 8162 {
8169 8163 uint32_t ghc_control;
8170 8164
8171 8165 ASSERT(ahci_ctlp->ahcictl_flags & (AHCI_ATTACH | AHCI_QUIESCE) ||
8172 8166 MUTEX_HELD(&ahci_ctlp->ahcictl_mutex));
8173 8167
8174 8168 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_disable_all_intrs enter",
8175 8169 NULL);
8176 8170
8177 8171 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8178 8172 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
8179 8173
8180 8174 ghc_control &= ~AHCI_HBA_GHC_IE;
8181 8175
8182 8176 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8183 8177 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
8184 8178 }
8185 8179
8186 8180 /*
8187 8181 * Handle FIXED or MSI interrupts.
8188 8182 */
8189 8183 /*
8190 8184 * According to AHCI spec, the HBA may support several interrupt modes:
8191 8185 * * pin based interrupts (FIXED)
8192 8186 * * single MSI message interrupts
8193 8187 * * multiple MSI based message interrupts
8194 8188 *
8195 8189 * For pin based interrupts, the software interrupt handler need to check IS
8196 8190 * register to find out which port has pending interrupts. And then check
8197 8191 * PxIS register to find out which interrupt events happened on that port.
8198 8192 *
8199 8193 * For single MSI message interrupts, MSICAP.MC.MSIE is set with '1', and
8200 8194 * MSICAP.MC.MME is set with '0'. This mode is similar to pin based interrupts
8201 8195 * in that software interrupt handler need to check IS register to determine
8202 8196 * which port triggered the interrupts since it uses a single message for all
8203 8197 * port interrupts.
8204 8198 *
8205 8199 * HBA may optionally support multiple MSI message for better performance. In
8206 8200 * this mode, each port may have its own interrupt message, and thus generation
8207 8201 * of interrupts is no longer controlled through the IS register. MSICAP.MC.MMC
8208 8202 * represents a power-of-2 wrapper on the number of implemented ports, and
8209 8203 * the mapping of ports to interrupts is done in a 1-1 relationship, up to the
8210 8204 * maximum number of assigned interrupts. When the number of MSI messages
8211 8205 * allocated is less than the number requested, then hardware may have two
8212 8206 * implementation behaviors:
8213 8207 * * assign each ports its own interrupt and then force all additional
8214 8208 * ports to share the last interrupt message, and this condition is
8215 8209 * indicated by clearing GHC.MRSM to '0'
8216 8210 * * revert to single MSI mode, indicated by setting GHC.MRSM to '1'
8217 8211 * When multiple-message MSI is enabled, hardware will still set IS register
8218 8212 * as single message case. And this IS register may be used by software when
8219 8213 * fewer than the requested number of messages is granted in order to determine
8220 8214 * which port had the interrupt.
8221 8215 *
8222 8216 * Note: The current ahci driver only supports the first two interrupt modes:
8223 8217 * pin based interrupts and single MSI message interrupts, and the reason
8224 8218 * is indicated in below code.
8225 8219 */
8226 8220 static int
8227 8221 ahci_add_intrs(ahci_ctl_t *ahci_ctlp, int intr_type)
8228 8222 {
8229 8223 dev_info_t *dip = ahci_ctlp->ahcictl_dip;
8230 8224 int count, avail, actual;
8231 8225 int i, rc;
8232 8226
8233 8227 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
8234 8228 "ahci_add_intrs enter interrupt type 0x%x", intr_type);
8235 8229
8236 8230 /* get number of interrupts. */
8237 8231 rc = ddi_intr_get_nintrs(dip, intr_type, &count);
8238 8232 if ((rc != DDI_SUCCESS) || (count == 0)) {
8239 8233 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8240 8234 "ddi_intr_get_nintrs() failed, "
8241 8235 "rc %d count %d\n", rc, count);
8242 8236 return (DDI_FAILURE);
8243 8237 }
8244 8238
8245 8239 /* get number of available interrupts. */
8246 8240 rc = ddi_intr_get_navail(dip, intr_type, &avail);
8247 8241 if ((rc != DDI_SUCCESS) || (avail == 0)) {
8248 8242 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8249 8243 "ddi_intr_get_navail() failed, "
8250 8244 "rc %d avail %d\n", rc, avail);
8251 8245 return (DDI_FAILURE);
8252 8246 }
8253 8247
8254 8248 #if AHCI_DEBUG
8255 8249 if (avail < count) {
8256 8250 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8257 8251 "ddi_intr_get_nintrs returned %d, navail() returned %d",
8258 8252 count, avail);
8259 8253 }
8260 8254 #endif
8261 8255
8262 8256 /*
8263 8257 * Note: So far Solaris restricts the maximum number of messages for
8264 8258 * x86 to 2, that is avail is 2, so here we set the count with 1 to
8265 8259 * force the driver to use single MSI message interrupt. In future if
8266 8260 * Solaris remove the restriction, then we need to delete the below
8267 8261 * code and try to use multiple interrupt routine to gain better
8268 8262 * performance.
8269 8263 */
8270 8264 if ((intr_type == DDI_INTR_TYPE_MSI) && (count > 1)) {
8271 8265 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8272 8266 "force to use one interrupt routine though the "
8273 8267 "HBA supports %d interrupt", count);
8274 8268 count = 1;
8275 8269 }
8276 8270
8277 8271 /* Allocate an array of interrupt handles. */
8278 8272 ahci_ctlp->ahcictl_intr_size = count * sizeof (ddi_intr_handle_t);
8279 8273 ahci_ctlp->ahcictl_intr_htable =
8280 8274 kmem_alloc(ahci_ctlp->ahcictl_intr_size, KM_SLEEP);
8281 8275
8282 8276 /* call ddi_intr_alloc(). */
8283 8277 rc = ddi_intr_alloc(dip, ahci_ctlp->ahcictl_intr_htable,
8284 8278 intr_type, 0, count, &actual, DDI_INTR_ALLOC_NORMAL);
8285 8279
8286 8280 if ((rc != DDI_SUCCESS) || (actual == 0)) {
8287 8281 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8288 8282 "ddi_intr_alloc() failed, rc %d count %d actual %d "
8289 8283 "avail %d\n", rc, count, actual, avail);
8290 8284 kmem_free(ahci_ctlp->ahcictl_intr_htable,
8291 8285 ahci_ctlp->ahcictl_intr_size);
8292 8286 return (DDI_FAILURE);
8293 8287 }
8294 8288
8295 8289 /* use interrupt count returned */
8296 8290 #if AHCI_DEBUG
8297 8291 if (actual < count) {
8298 8292 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8299 8293 "Requested: %d, Received: %d", count, actual);
8300 8294 }
8301 8295 #endif
8302 8296
8303 8297 ahci_ctlp->ahcictl_intr_cnt = actual;
8304 8298
8305 8299 /*
8306 8300 * Get priority for first, assume remaining are all the same.
8307 8301 */
8308 8302 if (ddi_intr_get_pri(ahci_ctlp->ahcictl_intr_htable[0],
8309 8303 &ahci_ctlp->ahcictl_intr_pri) != DDI_SUCCESS) {
8310 8304 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8311 8305 "ddi_intr_get_pri() failed", NULL);
8312 8306
8313 8307 /* Free already allocated intr. */
8314 8308 for (i = 0; i < actual; i++) {
8315 8309 (void) ddi_intr_free(ahci_ctlp->ahcictl_intr_htable[i]);
8316 8310 }
8317 8311
8318 8312 kmem_free(ahci_ctlp->ahcictl_intr_htable,
8319 8313 ahci_ctlp->ahcictl_intr_size);
8320 8314 return (DDI_FAILURE);
8321 8315 }
8322 8316
8323 8317 /* Test for high level interrupt. */
8324 8318 if (ahci_ctlp->ahcictl_intr_pri >= ddi_intr_get_hilevel_pri()) {
8325 8319 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8326 8320 "ahci_add_intrs: Hi level intr not supported", NULL);
8327 8321
8328 8322 /* Free already allocated intr. */
8329 8323 for (i = 0; i < actual; i++) {
8330 8324 (void) ddi_intr_free(ahci_ctlp->ahcictl_intr_htable[i]);
8331 8325 }
8332 8326
8333 8327 kmem_free(ahci_ctlp->ahcictl_intr_htable,
8334 8328 sizeof (ddi_intr_handle_t));
8335 8329
8336 8330 return (DDI_FAILURE);
8337 8331 }
8338 8332
8339 8333 /* Call ddi_intr_add_handler(). */
8340 8334 for (i = 0; i < actual; i++) {
8341 8335 if (ddi_intr_add_handler(ahci_ctlp->ahcictl_intr_htable[i],
8342 8336 ahci_intr, (caddr_t)ahci_ctlp, NULL) != DDI_SUCCESS) {
8343 8337 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8344 8338 "ddi_intr_add_handler() failed", NULL);
8345 8339
8346 8340 /* Free already allocated intr. */
8347 8341 for (i = 0; i < actual; i++) {
8348 8342 (void) ddi_intr_free(
8349 8343 ahci_ctlp->ahcictl_intr_htable[i]);
8350 8344 }
8351 8345
8352 8346 kmem_free(ahci_ctlp->ahcictl_intr_htable,
8353 8347 ahci_ctlp->ahcictl_intr_size);
8354 8348 return (DDI_FAILURE);
8355 8349 }
8356 8350 }
8357 8351
8358 8352 if (ddi_intr_get_cap(ahci_ctlp->ahcictl_intr_htable[0],
8359 8353 &ahci_ctlp->ahcictl_intr_cap) != DDI_SUCCESS) {
8360 8354 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8361 8355 "ddi_intr_get_cap() failed", NULL);
8362 8356
8363 8357 /* Free already allocated intr. */
8364 8358 for (i = 0; i < actual; i++) {
8365 8359 (void) ddi_intr_free(
8366 8360 ahci_ctlp->ahcictl_intr_htable[i]);
8367 8361 }
8368 8362
8369 8363 kmem_free(ahci_ctlp->ahcictl_intr_htable,
8370 8364 ahci_ctlp->ahcictl_intr_size);
8371 8365 return (DDI_FAILURE);
8372 8366 }
8373 8367
8374 8368 if (ahci_ctlp->ahcictl_intr_cap & DDI_INTR_FLAG_BLOCK) {
8375 8369 /* Call ddi_intr_block_enable() for MSI. */
8376 8370 (void) ddi_intr_block_enable(ahci_ctlp->ahcictl_intr_htable,
8377 8371 ahci_ctlp->ahcictl_intr_cnt);
8378 8372 } else {
8379 8373 /* Call ddi_intr_enable() for FIXED or MSI non block enable. */
8380 8374 for (i = 0; i < ahci_ctlp->ahcictl_intr_cnt; i++) {
8381 8375 (void) ddi_intr_enable(
8382 8376 ahci_ctlp->ahcictl_intr_htable[i]);
8383 8377 }
8384 8378 }
8385 8379
8386 8380 return (DDI_SUCCESS);
8387 8381 }
8388 8382
8389 8383 /*
8390 8384 * Removes the registered interrupts irrespective of whether they
8391 8385 * were legacy or MSI.
8392 8386 *
8393 8387 * NOTE: The controller interrupts must be disabled before calling
8394 8388 * this routine.
8395 8389 */
8396 8390 static void
8397 8391 ahci_rem_intrs(ahci_ctl_t *ahci_ctlp)
8398 8392 {
8399 8393 int x;
8400 8394
8401 8395 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_rem_intrs entered", NULL);
8402 8396
8403 8397 /* Disable all interrupts. */
8404 8398 if ((ahci_ctlp->ahcictl_intr_type == DDI_INTR_TYPE_MSI) &&
8405 8399 (ahci_ctlp->ahcictl_intr_cap & DDI_INTR_FLAG_BLOCK)) {
8406 8400 /* Call ddi_intr_block_disable(). */
8407 8401 (void) ddi_intr_block_disable(ahci_ctlp->ahcictl_intr_htable,
8408 8402 ahci_ctlp->ahcictl_intr_cnt);
8409 8403 } else {
8410 8404 for (x = 0; x < ahci_ctlp->ahcictl_intr_cnt; x++) {
8411 8405 (void) ddi_intr_disable(
8412 8406 ahci_ctlp->ahcictl_intr_htable[x]);
8413 8407 }
8414 8408 }
8415 8409
8416 8410 /* Call ddi_intr_remove_handler(). */
8417 8411 for (x = 0; x < ahci_ctlp->ahcictl_intr_cnt; x++) {
8418 8412 (void) ddi_intr_remove_handler(
8419 8413 ahci_ctlp->ahcictl_intr_htable[x]);
8420 8414 (void) ddi_intr_free(ahci_ctlp->ahcictl_intr_htable[x]);
8421 8415 }
8422 8416
8423 8417 kmem_free(ahci_ctlp->ahcictl_intr_htable, ahci_ctlp->ahcictl_intr_size);
8424 8418 }
8425 8419
8426 8420 /*
8427 8421 * This routine tries to put port into P:NotRunning state by clearing
8428 8422 * PxCMD.ST. HBA will clear PxCI to 0h, PxSACT to 0h, PxCMD.CCS to 0h
8429 8423 * and PxCMD.CR to '0'.
8430 8424 */
8431 8425 static int
8432 8426 ahci_put_port_into_notrunning_state(ahci_ctl_t *ahci_ctlp,
8433 8427 ahci_port_t *ahci_portp, uint8_t port)
8434 8428 {
8435 8429 uint32_t port_cmd_status;
8436 8430 int loop_count;
8437 8431
8438 8432 ASSERT(ahci_ctlp->ahcictl_flags & AHCI_QUIESCE ||
8439 8433 MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
8440 8434
8441 8435 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
8442 8436 "ahci_put_port_into_notrunning_state enter: port %d", port);
8443 8437
8444 8438 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8445 8439 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
8446 8440
8447 8441 port_cmd_status &= ~AHCI_CMD_STATUS_ST;
8448 8442 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8449 8443 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port), port_cmd_status);
8450 8444
8451 8445 /* Wait until PxCMD.CR is cleared */
8452 8446 loop_count = 0;
8453 8447 do {
8454 8448 port_cmd_status =
8455 8449 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8456 8450 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
8457 8451
8458 8452 if (loop_count++ > AHCI_POLLRATE_PORT_IDLE) {
8459 8453 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
8460 8454 "clearing port %d CMD.CR timeout, "
8461 8455 "port_cmd_status = 0x%x", port,
8462 8456 port_cmd_status);
8463 8457 /*
8464 8458 * We are effectively timing out after 0.5 sec.
8465 8459 * This value is specified in AHCI spec.
8466 8460 */
8467 8461 break;
8468 8462 }
8469 8463
8470 8464 /* Wait for 10 millisec */
8471 8465 drv_usecwait(AHCI_10MS_USECS);
8472 8466 } while (port_cmd_status & AHCI_CMD_STATUS_CR);
8473 8467
8474 8468 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_STARTED;
8475 8469
8476 8470 if (port_cmd_status & AHCI_CMD_STATUS_CR) {
8477 8471 AHCIDBG(AHCIDBG_INIT|AHCIDBG_POLL_LOOP, ahci_ctlp,
8478 8472 "ahci_put_port_into_notrunning_state: failed to clear "
8479 8473 "PxCMD.CR to '0' after loop count: %d, and "
8480 8474 "port_cmd_status = 0x%x", loop_count, port_cmd_status);
8481 8475 return (AHCI_FAILURE);
8482 8476 } else {
8483 8477 AHCIDBG(AHCIDBG_INIT|AHCIDBG_POLL_LOOP, ahci_ctlp,
8484 8478 "ahci_put_port_into_notrunning_state: succeeded to clear "
8485 8479 "PxCMD.CR to '0' after loop count: %d, and "
8486 8480 "port_cmd_status = 0x%x", loop_count, port_cmd_status);
8487 8481 return (AHCI_SUCCESS);
8488 8482 }
8489 8483 }
8490 8484
8491 8485 /*
8492 8486 * First clear PxCMD.ST, and then check PxTFD. If both PxTFD.STS.BSY
8493 8487 * and PxTFD.STS.DRQ cleared to '0', it means the device is in a
8494 8488 * stable state, then set PxCMD.ST to '1' to start the port directly.
8495 8489 * If PxTFD.STS.BSY or PxTFD.STS.DRQ is set to '1', then issue a
8496 8490 * COMRESET to the device to put it in an idle state.
8497 8491 *
8498 8492 * The fifth argument returns whether the port reset is involved during
8499 8493 * the process.
8500 8494 *
8501 8495 * The routine will be called under following scenarios:
8502 8496 * + To reset the HBA
8503 8497 * + To abort the packet(s)
8504 8498 * + To reset the port
8505 8499 * + To activate the port
8506 8500 * + Fatal error recovery
8507 8501 * + To abort the timeout packet(s)
8508 8502 *
8509 8503 * NOTES!!! During this procedure, PxSERR register will be cleared, and
8510 8504 * according to the spec, the clearance of three bits will also clear
8511 8505 * three interrupt status bits.
8512 8506 * 1. PxSERR.DIAG.F will clear PxIS.UFS
8513 8507 * 2. PxSERR.DIAG.X will clear PxIS.PCS
8514 8508 * 3. PxSERR.DIAG.N will clear PxIS.PRCS
8515 8509 *
8516 8510 * Among these three interrupt events, the driver needs to take care of
8517 8511 * PxIS.PRCS, which is the hot plug event. When the driver found out
8518 8512 * a device was unplugged, it will call the interrupt handler.
8519 8513 */
8520 8514 static int
8521 8515 ahci_restart_port_wait_till_ready(ahci_ctl_t *ahci_ctlp,
8522 8516 ahci_port_t *ahci_portp, uint8_t port, int flag, int *reset_flag)
8523 8517 {
8524 8518 uint32_t port_sstatus;
8525 8519 uint32_t task_file_status;
8526 8520 sata_device_t sdevice;
8527 8521 int rval;
8528 8522 ahci_addr_t addr_port;
8529 8523 ahci_pmult_info_t *pminfo = NULL;
8530 8524 int dev_exists_begin = 0;
8531 8525 int dev_exists_end = 0;
8532 8526 uint32_t previous_dev_type = ahci_portp->ahciport_device_type;
8533 8527 int npmport = 0;
8534 8528 uint8_t cport = ahci_ctlp->ahcictl_port_to_cport[port];
8535 8529
8536 8530 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
8537 8531
8538 8532 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
8539 8533 "ahci_restart_port_wait_till_ready: port %d enter", port);
8540 8534
8541 8535 AHCI_ADDR_SET_PORT(&addr_port, port);
8542 8536
8543 8537 if (ahci_portp->ahciport_device_type != SATA_DTYPE_NONE)
8544 8538 dev_exists_begin = 1;
8545 8539
8546 8540 /* First clear PxCMD.ST */
8547 8541 rval = ahci_put_port_into_notrunning_state(ahci_ctlp, ahci_portp,
8548 8542 port);
8549 8543 if (rval != AHCI_SUCCESS)
8550 8544 /*
8551 8545 * If PxCMD.CR does not clear within a reasonable time, it
8552 8546 * may assume the interface is in a hung condition and may
8553 8547 * continue with issuing the port reset.
8554 8548 */
8555 8549 goto reset;
8556 8550
8557 8551 /* Then clear PxSERR */
8558 8552 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8559 8553 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
8560 8554 AHCI_SERROR_CLEAR_ALL);
8561 8555
8562 8556 /* Then get PxTFD */
8563 8557 task_file_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8564 8558 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
8565 8559
8566 8560 /*
8567 8561 * Check whether the device is in a stable status, if yes,
8568 8562 * then start the port directly. However for ahci_tran_reset_dport,
8569 8563 * we may have to perform a port reset.
8570 8564 */
8571 8565 if (!(task_file_status & (AHCI_TFD_STS_BSY | AHCI_TFD_STS_DRQ)) &&
8572 8566 !(flag & AHCI_PORT_RESET))
8573 8567 goto out;
8574 8568
8575 8569 reset:
8576 8570 /*
8577 8571 * If PxTFD.STS.BSY or PxTFD.STS.DRQ is set to '1', then issue
8578 8572 * a COMRESET to the device
8579 8573 */
8580 8574 ahci_disable_port_intrs(ahci_ctlp, port);
8581 8575 rval = ahci_port_reset(ahci_ctlp, ahci_portp, &addr_port);
8582 8576 ahci_enable_port_intrs(ahci_ctlp, port);
8583 8577
8584 8578 #ifdef AHCI_DEBUG
8585 8579 if (rval != AHCI_SUCCESS)
8586 8580 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8587 8581 "ahci_restart_port_wait_till_ready: port %d failed",
8588 8582 port);
8589 8583 #endif
8590 8584
8591 8585 if (reset_flag != NULL)
8592 8586 *reset_flag = 1;
8593 8587
8594 8588 /* Indicate to the framework that a reset has happened. */
8595 8589 if ((ahci_portp->ahciport_device_type != SATA_DTYPE_NONE) &&
8596 8590 (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) &&
8597 8591 !(flag & AHCI_RESET_NO_EVENTS_UP)) {
8598 8592 /* Set the reset in progress flag */
8599 8593 ahci_portp->ahciport_reset_in_progress = 1;
8600 8594
8601 8595 bzero((void *)&sdevice, sizeof (sata_device_t));
8602 8596 sdevice.satadev_addr.cport =
8603 8597 ahci_ctlp->ahcictl_port_to_cport[port];
8604 8598 sdevice.satadev_addr.pmport = 0;
8605 8599 sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
8606 8600
8607 8601 sdevice.satadev_state = SATA_DSTATE_RESET |
8608 8602 SATA_DSTATE_PWR_ACTIVE;
8609 8603 if (ahci_ctlp->ahcictl_sata_hba_tran) {
8610 8604 mutex_exit(&ahci_portp->ahciport_mutex);
8611 8605 sata_hba_event_notify(
8612 8606 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
8613 8607 &sdevice,
8614 8608 SATA_EVNT_DEVICE_RESET);
8615 8609 mutex_enter(&ahci_portp->ahciport_mutex);
8616 8610 }
8617 8611
8618 8612 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
8619 8613 "port %d sending event up: SATA_EVNT_DEVICE_RESET", port);
8620 8614 } else {
8621 8615 ahci_portp->ahciport_reset_in_progress = 0;
8622 8616 }
8623 8617
8624 8618 out:
8625 8619 (void) ahci_start_port(ahci_ctlp, ahci_portp, port);
8626 8620
8627 8621 /* SStatus tells the presence of device. */
8628 8622 port_sstatus = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8629 8623 (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp, port));
8630 8624
8631 8625 if (SSTATUS_GET_DET(port_sstatus) == SSTATUS_DET_DEVPRE_PHYCOM) {
8632 8626 dev_exists_end = 1;
8633 8627 }
8634 8628
8635 8629 if (dev_exists_begin == 0 && dev_exists_end == 0) /* 0 -> 0 */
8636 8630 return (rval);
8637 8631
8638 8632 /* Check whether a hot plug event happened */
8639 8633 if (dev_exists_begin == 1 && dev_exists_end == 0) { /* 1 -> 0 */
8640 8634 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8641 8635 "ahci_restart_port_wait_till_ready: port %d "
8642 8636 "device is removed", port);
8643 8637 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_NODEV;
8644 8638 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8645 8639 "ahci_restart_port_wait_till_ready: port %d "
8646 8640 "AHCI_PORT_FLAG_NODEV flag is set", port);
8647 8641 mutex_exit(&ahci_portp->ahciport_mutex);
8648 8642 (void) ahci_intr_phyrdy_change(ahci_ctlp, ahci_portp, port);
8649 8643 mutex_enter(&ahci_portp->ahciport_mutex);
8650 8644
8651 8645 return (rval);
8652 8646 }
8653 8647
8654 8648
8655 8649 /* 0/1 -> 1 : device may change */
8656 8650 /*
8657 8651 * May be called by ahci_fatal_error_recovery_handler, so
8658 8652 * don't issue software if the previous device is ATAPI.
8659 8653 */
8660 8654 if (ahci_portp->ahciport_device_type == SATA_DTYPE_ATAPI)
8661 8655 return (rval);
8662 8656
8663 8657 /*
8664 8658 * The COMRESET will make port multiplier enter legacy mode.
8665 8659 * Issue a software reset to make it work again.
8666 8660 */
8667 8661 ahci_disable_port_intrs(ahci_ctlp, port);
8668 8662 ahci_find_dev_signature(ahci_ctlp, ahci_portp, &addr_port);
8669 8663 ahci_enable_port_intrs(ahci_ctlp, port);
8670 8664
8671 8665 /*
8672 8666 * Following codes are specific for the port multiplier
8673 8667 */
8674 8668 if (previous_dev_type != SATA_DTYPE_PMULT &&
8675 8669 ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) {
8676 8670 /* in case previous_dev_type is corrupt */
8677 8671 ahci_dealloc_pmult(ahci_ctlp, ahci_portp);
8678 8672 (void) ahci_start_port(ahci_ctlp, ahci_portp, port);
8679 8673 return (rval);
8680 8674 }
8681 8675
8682 8676 /* Device change: PMult -> Non-PMult */
8683 8677 if (previous_dev_type == SATA_DTYPE_PMULT &&
8684 8678 ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) {
8685 8679 /*
8686 8680 * This might happen because
8687 8681 * 1. Software reset failed. Port multiplier is not correctly
8688 8682 * enumerated.
8689 8683 * 2. Another non-port-multiplier device is attached. Perhaps
8690 8684 * the port multiplier was replaced by another device by
8691 8685 * whatever reason, but AHCI driver missed hot-plug event.
8692 8686 *
8693 8687 * Now that the port has been initialized, we just need to
8694 8688 * update the port structure according new device, then report
8695 8689 * and wait SATA framework to probe new device.
8696 8690 */
8697 8691
8698 8692 /* Force to release pmult resource */
8699 8693 ahci_dealloc_pmult(ahci_ctlp, ahci_portp);
8700 8694 (void) ahci_start_port(ahci_ctlp, ahci_portp, port);
8701 8695
8702 8696 bzero((void *)&sdevice, sizeof (sata_device_t));
8703 8697 sdevice.satadev_addr.cport =
8704 8698 ahci_ctlp->ahcictl_port_to_cport[port];
8705 8699 sdevice.satadev_addr.pmport = 0;
8706 8700 sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
8707 8701
8708 8702 sdevice.satadev_state = SATA_DSTATE_RESET |
8709 8703 SATA_DSTATE_PWR_ACTIVE;
8710 8704
8711 8705 mutex_exit(&ahci_portp->ahciport_mutex);
8712 8706 sata_hba_event_notify(
8713 8707 ahci_ctlp->ahcictl_dip,
8714 8708 &sdevice,
8715 8709 SATA_EVNT_DEVICE_RESET);
8716 8710 mutex_enter(&ahci_portp->ahciport_mutex);
8717 8711
8718 8712 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8719 8713 "Port multiplier is [Gone] at port %d ", port);
8720 8714 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
8721 8715 "port %d sending event up: SATA_EVNT_DEVICE_RESET", port);
8722 8716
8723 8717 return (AHCI_SUCCESS);
8724 8718 }
8725 8719
8726 8720 /* Device change: Non-PMult -> PMult */
8727 8721 if (ahci_portp->ahciport_device_type == SATA_DTYPE_PMULT) {
8728 8722
8729 8723 /* NOTE: The PxCMD.PMA may be cleared by HBA reset. */
8730 8724 ahci_alloc_pmult(ahci_ctlp, ahci_portp);
8731 8725
8732 8726 (void) ahci_start_port(ahci_ctlp, ahci_portp, port);
8733 8727 }
8734 8728 pminfo = ahci_portp->ahciport_pmult_info;
8735 8729 ASSERT(pminfo != NULL);
8736 8730
8737 8731 /* Device (may) change: PMult -> PMult */
8738 8732 /*
8739 8733 * First initialize port multiplier. Set state to READY and wait for
8740 8734 * probe entry point to initialize it
8741 8735 */
8742 8736 ahci_portp->ahciport_port_state = SATA_STATE_READY;
8743 8737
8744 8738 /*
8745 8739 * It's a little complicated while target is a port multiplier. we
8746 8740 * need to COMRESET all pmports behind that PMult otherwise those
8747 8741 * sub-links between the PMult and the sub-devices will be in an
8748 8742 * inactive state (indicated by PSCR0/PxSSTS) and the following access
8749 8743 * to those sub-devices will be rejected by Link-Fatal-Error.
8750 8744 */
8751 8745 /*
8752 8746 * The PxSNTF will be set soon after the pmult is plugged. While the
8753 8747 * pmult itself is attaching, sata_hba_event_notfiy will fail. so we
8754 8748 * simply mark every sub-port as 'unknown', then ahci_probe_pmport
8755 8749 * will initialized it.
8756 8750 */
8757 8751 for (npmport = 0; npmport < pminfo->ahcipmi_num_dev_ports; npmport++)
8758 8752 pminfo->ahcipmi_port_state[npmport] = SATA_STATE_UNKNOWN;
8759 8753
8760 8754 /* Report reset event. */
8761 8755 ahci_portp->ahciport_reset_in_progress = 1;
8762 8756
8763 8757 bzero((void *)&sdevice, sizeof (sata_device_t));
8764 8758 sdevice.satadev_addr.cport = cport;
8765 8759 sdevice.satadev_addr.pmport = SATA_PMULT_HOSTPORT;
8766 8760 sdevice.satadev_addr.qual = SATA_ADDR_PMULT;
8767 8761 sdevice.satadev_state = SATA_DSTATE_RESET | SATA_DSTATE_PWR_ACTIVE;
8768 8762 sata_hba_event_notify(ahci_ctlp->ahcictl_dip, &sdevice,
8769 8763 SATA_EVNT_DEVICE_RESET);
8770 8764
8771 8765 return (rval);
8772 8766 }
8773 8767
8774 8768 /*
8775 8769 * This routine may be called under four scenarios:
8776 8770 * a) do the recovery from fatal error
8777 8771 * b) or we need to timeout some commands
8778 8772 * c) or we need to abort some commands
8779 8773 * d) or we need reset device/port/controller
8780 8774 *
8781 8775 * In all these scenarios, we need to send any pending unfinished
8782 8776 * commands up to sata framework.
8783 8777 */
8784 8778 static void
8785 8779 ahci_mop_commands(ahci_ctl_t *ahci_ctlp,
8786 8780 ahci_port_t *ahci_portp,
8787 8781 uint32_t slot_status,
8788 8782 uint32_t failed_tags,
8789 8783 uint32_t timeout_tags,
8790 8784 uint32_t aborted_tags,
8791 8785 uint32_t reset_tags)
8792 8786 {
8793 8787 uint32_t finished_tags = 0;
8794 8788 uint32_t unfinished_tags = 0;
8795 8789 int tmp_slot;
8796 8790 sata_pkt_t *satapkt;
8797 8791 int ncq_cmd_in_progress = 0;
8798 8792 int err_retri_cmd_in_progress = 0;
8799 8793 int rdwr_pmult_cmd_in_progress = 0;
8800 8794
8801 8795 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
8802 8796
8803 8797 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_ENTRY, ahci_ctlp,
8804 8798 "ahci_mop_commands entered: port: %d slot_status: 0x%x",
8805 8799 ahci_portp->ahciport_port_num, slot_status);
8806 8800
8807 8801 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_ENTRY, ahci_ctlp,
8808 8802 "ahci_mop_commands: failed_tags: 0x%x, "
8809 8803 "timeout_tags: 0x%x aborted_tags: 0x%x, "
8810 8804 "reset_tags: 0x%x", failed_tags,
8811 8805 timeout_tags, aborted_tags, reset_tags);
8812 8806
8813 8807 #ifdef AHCI_DEBUG
8814 8808 if (ahci_debug_flags & AHCIDBG_ERRS) {
8815 8809 int i;
8816 8810 char msg_buf[200] = {0, };
8817 8811 for (i = 0x1f; i >= 0; i--) {
8818 8812 if (ahci_portp->ahciport_slot_pkts[i] != NULL)
8819 8813 msg_buf[i] = 'X';
8820 8814 else
8821 8815 msg_buf[i] = '.';
8822 8816 }
8823 8817 msg_buf[0x20] = '\0';
8824 8818 cmn_err(CE_NOTE, "port[%d] slots: %s",
8825 8819 ahci_portp->ahciport_port_num, msg_buf);
8826 8820 cmn_err(CE_NOTE, "[ERR-RT] %p [RW-PM] %p ",
8827 8821 (void *)ahci_portp->ahciport_err_retri_pkt,
8828 8822 (void *)ahci_portp->ahciport_rdwr_pmult_pkt);
8829 8823 }
8830 8824 #endif
8831 8825
8832 8826 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
8833 8827 finished_tags = ahci_portp->ahciport_pending_tags &
8834 8828 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
8835 8829
8836 8830 unfinished_tags = slot_status &
8837 8831 AHCI_SLOT_MASK(ahci_ctlp) &
8838 8832 ~failed_tags &
8839 8833 ~aborted_tags &
8840 8834 ~reset_tags &
8841 8835 ~timeout_tags;
8842 8836 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
8843 8837 ncq_cmd_in_progress = 1;
8844 8838 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
8845 8839 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
8846 8840
8847 8841 unfinished_tags = slot_status &
8848 8842 AHCI_NCQ_SLOT_MASK(ahci_portp) &
8849 8843 ~failed_tags &
8850 8844 ~aborted_tags &
8851 8845 ~reset_tags &
8852 8846 ~timeout_tags;
8853 8847 } else if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
8854 8848
8855 8849 /*
8856 8850 * When AHCI_PORT_FLAG_RQSENSE or AHCI_PORT_FLAG_RDLOGEXT is
8857 8851 * set, it means REQUEST SENSE or READ LOG EXT command doesn't
8858 8852 * complete successfully due to one of the following three
8859 8853 * conditions:
8860 8854 *
8861 8855 * 1. Fatal error - failed_tags includes its slot
8862 8856 * 2. Timed out - timeout_tags includes its slot
8863 8857 * 3. Aborted when hot unplug - aborted_tags includes its
8864 8858 * slot
8865 8859 *
8866 8860 * Please note that the command is always sent down in Slot 0
8867 8861 */
8868 8862 err_retri_cmd_in_progress = 1;
8869 8863 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_NCQ, ahci_ctlp,
8870 8864 "ahci_mop_commands is called for port %d while "
8871 8865 "REQUEST SENSE or READ LOG EXT for error retrieval "
8872 8866 "is being executed slot_status = 0x%x",
8873 8867 ahci_portp->ahciport_port_num, slot_status);
8874 8868 ASSERT(ahci_portp->ahciport_mop_in_progress > 1);
8875 8869 ASSERT(slot_status == 0x1);
8876 8870 } else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
8877 8871 rdwr_pmult_cmd_in_progress = 1;
8878 8872 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
8879 8873 "ahci_mop_commands is called for port %d while "
8880 8874 "READ/WRITE PORTMULT command is being executed",
8881 8875 ahci_portp->ahciport_port_num);
8882 8876
8883 8877 ASSERT(slot_status == 0x1);
8884 8878 }
8885 8879
8886 8880 #ifdef AHCI_DEBUG
8887 8881 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_ENTRY, ahci_ctlp,
8888 8882 "ahci_mop_commands: finished_tags: 0x%x, "
8889 8883 "unfinished_tags 0x%x", finished_tags, unfinished_tags);
8890 8884 #endif
8891 8885
8892 8886 /* Send up finished packets with SATA_PKT_COMPLETED */
8893 8887 while (finished_tags) {
8894 8888 tmp_slot = ddi_ffs(finished_tags) - 1;
8895 8889 if (tmp_slot == -1) {
8896 8890 break;
8897 8891 }
8898 8892
8899 8893 satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
8900 8894 ASSERT(satapkt != NULL);
8901 8895
8902 8896 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "ahci_mop_commands: "
8903 8897 "sending up pkt 0x%p with SATA_PKT_COMPLETED",
8904 8898 (void *)satapkt);
8905 8899
8906 8900 /*
8907 8901 * Cannot fetch the return register content since the port
8908 8902 * was restarted, so the corresponding tag will be set to
8909 8903 * aborted tags.
8910 8904 */
8911 8905 if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
8912 8906 CLEAR_BIT(finished_tags, tmp_slot);
8913 8907 aborted_tags |= tmp_slot;
8914 8908 continue;
8915 8909 }
8916 8910
8917 8911 if (ncq_cmd_in_progress)
8918 8912 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
8919 8913 tmp_slot);
8920 8914 CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
8921 8915 CLEAR_BIT(finished_tags, tmp_slot);
8922 8916 ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
8923 8917
8924 8918 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
8925 8919 }
8926 8920
8927 8921 /* Send up failed packets with SATA_PKT_DEV_ERROR. */
8928 8922 while (failed_tags) {
8929 8923 if (err_retri_cmd_in_progress) {
8930 8924 satapkt = ahci_portp->ahciport_err_retri_pkt;
8931 8925 ASSERT(satapkt != NULL);
8932 8926 ASSERT(failed_tags == 0x1);
8933 8927
8934 8928 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
8935 8929 "sending up pkt 0x%p with SATA_PKT_DEV_ERROR",
8936 8930 (void *)satapkt);
8937 8931 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_DEV_ERROR);
8938 8932 break;
8939 8933 }
8940 8934 if (rdwr_pmult_cmd_in_progress) {
8941 8935 satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
8942 8936 ASSERT(satapkt != NULL);
8943 8937 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8944 8938 "ahci_mop_commands: sending up "
8945 8939 "rdwr pmult pkt 0x%p with SATA_PKT_DEV_ERROR",
8946 8940 (void *)satapkt);
8947 8941 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_DEV_ERROR);
8948 8942 break;
8949 8943 }
8950 8944
8951 8945 tmp_slot = ddi_ffs(failed_tags) - 1;
8952 8946 if (tmp_slot == -1) {
8953 8947 break;
8954 8948 }
8955 8949
8956 8950 satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
8957 8951 ASSERT(satapkt != NULL);
8958 8952
8959 8953 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
8960 8954 "sending up pkt 0x%p with SATA_PKT_DEV_ERROR",
8961 8955 (void *)satapkt);
8962 8956
8963 8957 if (ncq_cmd_in_progress)
8964 8958 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
8965 8959 tmp_slot);
8966 8960 CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
8967 8961 CLEAR_BIT(failed_tags, tmp_slot);
8968 8962 ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
8969 8963
8970 8964 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_DEV_ERROR);
8971 8965 }
8972 8966
8973 8967 /* Send up timeout packets with SATA_PKT_TIMEOUT. */
8974 8968 while (timeout_tags) {
8975 8969 if (err_retri_cmd_in_progress) {
8976 8970 satapkt = ahci_portp->ahciport_err_retri_pkt;
8977 8971 ASSERT(satapkt != NULL);
8978 8972 ASSERT(timeout_tags == 0x1);
8979 8973
8980 8974 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
8981 8975 "sending up pkt 0x%p with SATA_PKT_TIMEOUT",
8982 8976 (void *)satapkt);
8983 8977 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_TIMEOUT);
8984 8978 break;
8985 8979 }
8986 8980 if (rdwr_pmult_cmd_in_progress) {
8987 8981 satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
8988 8982 ASSERT(satapkt != NULL);
8989 8983 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8990 8984 "ahci_mop_commands: sending up "
8991 8985 "rdwr pmult pkt 0x%p with SATA_PKT_TIMEOUT",
8992 8986 (void *)satapkt);
8993 8987 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_TIMEOUT);
8994 8988 break;
8995 8989 }
8996 8990
8997 8991 tmp_slot = ddi_ffs(timeout_tags) - 1;
8998 8992 if (tmp_slot == -1) {
8999 8993 break;
9000 8994 }
9001 8995
9002 8996 satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9003 8997 ASSERT(satapkt != NULL);
9004 8998
9005 8999 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
9006 9000 "sending up pkt 0x%p with SATA_PKT_TIMEOUT",
9007 9001 (void *)satapkt);
9008 9002
9009 9003 if (ncq_cmd_in_progress)
9010 9004 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
9011 9005 tmp_slot);
9012 9006 CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
9013 9007 CLEAR_BIT(timeout_tags, tmp_slot);
9014 9008 ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
9015 9009
9016 9010 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_TIMEOUT);
9017 9011 }
9018 9012
9019 9013 /* Send up aborted packets with SATA_PKT_ABORTED */
9020 9014 while (aborted_tags) {
9021 9015 if (err_retri_cmd_in_progress) {
9022 9016 satapkt = ahci_portp->ahciport_err_retri_pkt;
9023 9017 ASSERT(satapkt != NULL);
9024 9018 ASSERT(aborted_tags == 0x1);
9025 9019
9026 9020 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
9027 9021 "sending up pkt 0x%p with SATA_PKT_ABORTED",
9028 9022 (void *)satapkt);
9029 9023 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_ABORTED);
9030 9024 break;
9031 9025 }
9032 9026 if (rdwr_pmult_cmd_in_progress) {
9033 9027 satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
9034 9028 ASSERT(satapkt != NULL);
9035 9029 ASSERT(aborted_tags == 0x1);
9036 9030 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9037 9031 "ahci_mop_commands: sending up "
9038 9032 "rdwr pmult pkt 0x%p with SATA_PKT_ABORTED",
9039 9033 (void *)satapkt);
9040 9034 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_ABORTED);
9041 9035 break;
9042 9036 }
9043 9037
9044 9038 tmp_slot = ddi_ffs(aborted_tags) - 1;
9045 9039 if (tmp_slot == -1) {
9046 9040 break;
9047 9041 }
9048 9042
9049 9043 satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9050 9044 ASSERT(satapkt != NULL);
9051 9045
9052 9046 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
9053 9047 "sending up pkt 0x%p with SATA_PKT_ABORTED",
9054 9048 (void *)satapkt);
9055 9049
9056 9050 if (ncq_cmd_in_progress)
9057 9051 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
9058 9052 tmp_slot);
9059 9053 CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
9060 9054 CLEAR_BIT(aborted_tags, tmp_slot);
9061 9055 ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
9062 9056
9063 9057 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_ABORTED);
9064 9058 }
9065 9059
9066 9060 /* Send up reset packets with SATA_PKT_RESET. */
9067 9061 while (reset_tags) {
9068 9062 if (rdwr_pmult_cmd_in_progress) {
9069 9063 satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
9070 9064 ASSERT(satapkt != NULL);
9071 9065 ASSERT(aborted_tags == 0x1);
9072 9066 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9073 9067 "ahci_mop_commands: sending up "
9074 9068 "rdwr pmult pkt 0x%p with SATA_PKT_RESET",
9075 9069 (void *)satapkt);
9076 9070 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_RESET);
9077 9071 break;
9078 9072 }
9079 9073
9080 9074 tmp_slot = ddi_ffs(reset_tags) - 1;
9081 9075 if (tmp_slot == -1) {
9082 9076 break;
9083 9077 }
9084 9078
9085 9079 satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9086 9080 ASSERT(satapkt != NULL);
9087 9081
9088 9082 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
9089 9083 "sending up pkt 0x%p with SATA_PKT_RESET",
9090 9084 (void *)satapkt);
9091 9085
9092 9086 if (ncq_cmd_in_progress)
9093 9087 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
9094 9088 tmp_slot);
9095 9089 CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
9096 9090 CLEAR_BIT(reset_tags, tmp_slot);
9097 9091 ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
9098 9092
9099 9093 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_RESET);
9100 9094 }
9101 9095
9102 9096 /* Send up unfinished packets with SATA_PKT_RESET */
9103 9097 while (unfinished_tags) {
9104 9098 tmp_slot = ddi_ffs(unfinished_tags) - 1;
9105 9099 if (tmp_slot == -1) {
9106 9100 break;
9107 9101 }
9108 9102
9109 9103 satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9110 9104 ASSERT(satapkt != NULL);
9111 9105
9112 9106 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
9113 9107 "sending up pkt 0x%p with SATA_PKT_RESET",
9114 9108 (void *)satapkt);
9115 9109
9116 9110 if (ncq_cmd_in_progress)
9117 9111 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
9118 9112 tmp_slot);
9119 9113 CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
9120 9114 CLEAR_BIT(unfinished_tags, tmp_slot);
9121 9115 ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
9122 9116
9123 9117 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_RESET);
9124 9118 }
9125 9119
9126 9120 ahci_portp->ahciport_mop_in_progress--;
9127 9121 ASSERT(ahci_portp->ahciport_mop_in_progress >= 0);
9128 9122
9129 9123 if (ahci_portp->ahciport_mop_in_progress == 0)
9130 9124 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_MOPPING;
9131 9125
9132 9126 ahci_flush_doneq(ahci_portp);
9133 9127 }
9134 9128
9135 9129 /*
9136 9130 * This routine is going to first request a READ LOG EXT sata pkt from sata
9137 9131 * module, and then deliver it to the HBA to get the ncq failure context.
9138 9132 * The return value is the exactly failed tags.
9139 9133 */
9140 9134 static uint32_t
9141 9135 ahci_get_rdlogext_data(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
9142 9136 uint8_t port)
9143 9137 {
9144 9138 sata_device_t sdevice;
9145 9139 sata_pkt_t *rdlog_spkt, *spkt;
9146 9140 ddi_dma_handle_t buf_dma_handle;
9147 9141 ahci_addr_t addr;
9148 9142 int loop_count;
9149 9143 int rval;
9150 9144 int failed_slot;
9151 9145 uint32_t failed_tags = 0;
9152 9146 struct sata_ncq_error_recovery_page *ncq_err_page;
9153 9147
9154 9148 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_NCQ, ahci_ctlp,
9155 9149 "ahci_get_rdlogext_data enter: port %d", port);
9156 9150
9157 9151 /* Prepare the sdevice data */
9158 9152 bzero((void *)&sdevice, sizeof (sata_device_t));
9159 9153 sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
9160 9154
9161 9155 sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
9162 9156 sdevice.satadev_addr.pmport = 0;
9163 9157
9164 9158 /* Translate sata_device.satadev_addr -> ahci_addr */
9165 9159 ahci_get_ahci_addr(ahci_ctlp, &sdevice, &addr);
9166 9160
9167 9161 /*
9168 9162 * Call the sata hba interface to get a rdlog spkt
9169 9163 */
9170 9164 loop_count = 0;
9171 9165 loop:
9172 9166 rdlog_spkt = sata_get_error_retrieval_pkt(ahci_ctlp->ahcictl_dip,
9173 9167 &sdevice, SATA_ERR_RETR_PKT_TYPE_NCQ);
9174 9168 if (rdlog_spkt == NULL) {
9175 9169 if (loop_count++ < AHCI_POLLRATE_GET_SPKT) {
9176 9170 /* Sleep for a while */
9177 9171 drv_usecwait(AHCI_10MS_USECS);
9178 9172 goto loop;
9179 9173 }
9180 9174 /* Timed out after 1s */
9181 9175 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9182 9176 "failed to get rdlog spkt for port %d", port);
9183 9177 return (failed_tags);
9184 9178 }
9185 9179
9186 9180 ASSERT(rdlog_spkt->satapkt_op_mode & SATA_OPMODE_SYNCH);
9187 9181
9188 9182 /*
9189 9183 * This flag is used to handle the specific error recovery when the
9190 9184 * READ LOG EXT command gets a failure (fatal error or time-out).
9191 9185 */
9192 9186 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_RDLOGEXT;
9193 9187
9194 9188 /*
9195 9189 * This start is not supposed to fail because after port is restarted,
9196 9190 * the whole command list is empty.
9197 9191 */
9198 9192 ahci_portp->ahciport_err_retri_pkt = rdlog_spkt;
9199 9193 (void) ahci_do_sync_start(ahci_ctlp, ahci_portp, &addr, rdlog_spkt);
9200 9194 ahci_portp->ahciport_err_retri_pkt = NULL;
9201 9195
9202 9196 /* Remove the flag after READ LOG EXT command is completed */
9203 9197 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_RDLOGEXT;
9204 9198
9205 9199 if (rdlog_spkt->satapkt_reason == SATA_PKT_COMPLETED) {
9206 9200 /* Update the request log data */
9207 9201 buf_dma_handle = *(ddi_dma_handle_t *)
9208 9202 (rdlog_spkt->satapkt_cmd.satacmd_err_ret_buf_handle);
9209 9203 rval = ddi_dma_sync(buf_dma_handle, 0, 0,
9210 9204 DDI_DMA_SYNC_FORKERNEL);
9211 9205 if (rval == DDI_SUCCESS) {
9212 9206 ncq_err_page =
9213 9207 (struct sata_ncq_error_recovery_page *)rdlog_spkt->
9214 9208 satapkt_cmd.satacmd_bp->b_un.b_addr;
9215 9209
9216 9210 /* Get the failed tag */
9217 9211 failed_slot = ncq_err_page->ncq_tag;
9218 9212 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9219 9213 "ahci_get_rdlogext_data: port %d "
9220 9214 "failed slot %d", port, failed_slot);
9221 9215 if (failed_slot & NQ) {
9222 9216 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9223 9217 "the failed slot is not a valid tag", NULL);
9224 9218 goto out;
9225 9219 }
9226 9220
9227 9221 failed_slot &= NCQ_TAG_MASK;
9228 9222 spkt = ahci_portp->ahciport_slot_pkts[failed_slot];
9229 9223 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9230 9224 "ahci_get_rdlogext_data: failed spkt 0x%p",
9231 9225 (void *)spkt);
9232 9226 if (spkt == NULL) {
9233 9227 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9234 9228 "the failed slot spkt is NULL", NULL);
9235 9229 goto out;
9236 9230 }
9237 9231
9238 9232 failed_tags = 0x1 << failed_slot;
9239 9233
9240 9234 /* Fill out the error context */
9241 9235 ahci_copy_ncq_err_page(&spkt->satapkt_cmd,
9242 9236 ncq_err_page);
9243 9237 ahci_update_sata_registers(ahci_ctlp, port,
9244 9238 &spkt->satapkt_device);
9245 9239 }
9246 9240 }
9247 9241 out:
9248 9242 sata_free_error_retrieval_pkt(rdlog_spkt);
9249 9243
9250 9244 return (failed_tags);
9251 9245 }
9252 9246
9253 9247 /*
9254 9248 * This routine is going to first request a REQUEST SENSE sata pkt from sata
9255 9249 * module, and then deliver it to the HBA to get the sense data and copy
9256 9250 * the sense data back to the orignal failed sata pkt, and free the REQUEST
9257 9251 * SENSE sata pkt later.
9258 9252 */
9259 9253 static void
9260 9254 ahci_get_rqsense_data(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
9261 9255 uint8_t port, sata_pkt_t *spkt)
9262 9256 {
9263 9257 sata_device_t sdevice;
9264 9258 sata_pkt_t *rs_spkt;
9265 9259 sata_cmd_t *sata_cmd;
9266 9260 ddi_dma_handle_t buf_dma_handle;
9267 9261 ahci_addr_t addr;
9268 9262 int loop_count;
9269 9263 #if AHCI_DEBUG
9270 9264 struct scsi_extended_sense *rqsense;
9271 9265 #endif
9272 9266
9273 9267 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
9274 9268 "ahci_get_rqsense_data enter: port %d", port);
9275 9269
9276 9270 /* Prepare the sdevice data */
9277 9271 bzero((void *)&sdevice, sizeof (sata_device_t));
9278 9272 sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
9279 9273
9280 9274 sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
9281 9275 sdevice.satadev_addr.pmport = 0;
9282 9276
9283 9277 /* Translate sata_device.satadev_addr -> ahci_addr */
9284 9278 ahci_get_ahci_addr(ahci_ctlp, &sdevice, &addr);
9285 9279
9286 9280 sata_cmd = &spkt->satapkt_cmd;
9287 9281
9288 9282 /*
9289 9283 * Call the sata hba interface to get a rs spkt
9290 9284 */
9291 9285 loop_count = 0;
9292 9286 loop:
9293 9287 rs_spkt = sata_get_error_retrieval_pkt(ahci_ctlp->ahcictl_dip,
9294 9288 &sdevice, SATA_ERR_RETR_PKT_TYPE_ATAPI);
9295 9289 if (rs_spkt == NULL) {
9296 9290 if (loop_count++ < AHCI_POLLRATE_GET_SPKT) {
9297 9291 /* Sleep for a while */
9298 9292 drv_usecwait(AHCI_10MS_USECS);
9299 9293 goto loop;
9300 9294
9301 9295 }
9302 9296 /* Timed out after 1s */
9303 9297 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9304 9298 "failed to get rs spkt for port %d", port);
9305 9299 return;
9306 9300 }
9307 9301
9308 9302 ASSERT(rs_spkt->satapkt_op_mode & SATA_OPMODE_SYNCH);
9309 9303
9310 9304 /*
9311 9305 * This flag is used to handle the specific error recovery when the
9312 9306 * REQUEST SENSE command gets a faiure (fatal error or time-out).
9313 9307 */
9314 9308 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_RQSENSE;
9315 9309
9316 9310 /*
9317 9311 * This start is not supposed to fail because after port is restarted,
9318 9312 * the whole command list is empty.
9319 9313 */
9320 9314 ahci_portp->ahciport_err_retri_pkt = rs_spkt;
9321 9315 (void) ahci_do_sync_start(ahci_ctlp, ahci_portp, &addr, rs_spkt);
9322 9316 ahci_portp->ahciport_err_retri_pkt = NULL;
9323 9317
9324 9318 /* Remove the flag after REQUEST SENSE command is completed */
9325 9319 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_RQSENSE;
9326 9320
9327 9321 if (rs_spkt->satapkt_reason == SATA_PKT_COMPLETED) {
9328 9322 /* Update the request sense data */
9329 9323 buf_dma_handle = *(ddi_dma_handle_t *)
9330 9324 (rs_spkt->satapkt_cmd.satacmd_err_ret_buf_handle);
9331 9325 (void) ddi_dma_sync(buf_dma_handle, 0, 0,
9332 9326 DDI_DMA_SYNC_FORKERNEL);
9333 9327 /* Copy the request sense data */
9334 9328 bcopy(rs_spkt->
9335 9329 satapkt_cmd.satacmd_bp->b_un.b_addr,
9336 9330 &sata_cmd->satacmd_rqsense,
9337 9331 SATA_ATAPI_MIN_RQSENSE_LEN);
9338 9332 #if AHCI_DEBUG
9339 9333 rqsense = (struct scsi_extended_sense *)
9340 9334 sata_cmd->satacmd_rqsense;
9341 9335
9342 9336 /* Dump the sense data */
9343 9337 AHCIDBG(AHCIDBG_SENSEDATA, ahci_ctlp, "\n", NULL);
9344 9338 AHCIDBG(AHCIDBG_SENSEDATA, ahci_ctlp,
9345 9339 "Sense data for satapkt %p ATAPI cmd 0x%x",
9346 9340 spkt, sata_cmd->satacmd_acdb[0]);
9347 9341 AHCIDBG(AHCIDBG_SENSEDATA, ahci_ctlp,
9348 9342 " es_code 0x%x es_class 0x%x "
9349 9343 "es_key 0x%x es_add_code 0x%x "
9350 9344 "es_qual_code 0x%x",
9351 9345 rqsense->es_code, rqsense->es_class,
9352 9346 rqsense->es_key, rqsense->es_add_code,
9353 9347 rqsense->es_qual_code);
9354 9348 #endif
9355 9349 }
9356 9350
9357 9351 sata_free_error_retrieval_pkt(rs_spkt);
9358 9352 }
9359 9353
9360 9354 /*
9361 9355 * Fatal errors will cause the HBA to enter the ERR: Fatal state. To recover,
9362 9356 * the port must be restarted. When the HBA detects thus error, it may try
9363 9357 * to abort a transfer. And if the transfer was aborted, the device is
9364 9358 * expected to send a D2H Register FIS with PxTFD.STS.ERR set to '1' and both
9365 9359 * PxTFD.STS.BSY and PxTFD.STS.DRQ cleared to '0'. Then system software knows
9366 9360 * that the device is in a stable status and transfers may be restarted without
9367 9361 * issuing a COMRESET to the device. If PxTFD.STS.BSY or PxTFD.STS.DRQ is set,
9368 9362 * then the software will send the COMRESET to do the port reset.
9369 9363 *
9370 9364 * Software should perform the appropriate error recovery actions based on
9371 9365 * whether non-queued commands were being issued or natived command queuing
9372 9366 * commands were being issued.
9373 9367 *
9374 9368 * And software will complete the command that had the error with error mark
9375 9369 * to higher level software.
9376 9370 *
9377 9371 * Fatal errors include the following:
9378 9372 * PxIS.IFS - Interface Fatal Error Status
9379 9373 * PxIS.HBDS - Host Bus Data Error Status
9380 9374 * PxIS.HBFS - Host Bus Fatal Error Status
9381 9375 * PxIS.TFES - Task File Error Status
9382 9376 */
9383 9377 static void
9384 9378 ahci_fatal_error_recovery_handler(ahci_ctl_t *ahci_ctlp,
9385 9379 ahci_port_t *ahci_portp, ahci_addr_t *addrp, uint32_t intr_status)
9386 9380 {
9387 9381 uint32_t port_cmd_status;
9388 9382 uint32_t slot_status = 0;
9389 9383 uint32_t failed_tags = 0;
9390 9384 int failed_slot;
9391 9385 int reset_flag = 0, flag = 0;
9392 9386 ahci_fis_d2h_register_t *ahci_rcvd_fisp;
9393 9387 sata_cmd_t *sata_cmd = NULL;
9394 9388 sata_pkt_t *spkt = NULL;
9395 9389 #if AHCI_DEBUG
9396 9390 ahci_cmd_header_t *cmd_header;
9397 9391 #endif
9398 9392 uint8_t port = addrp->aa_port;
9399 9393 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
9400 9394 int rval;
9401 9395
9402 9396 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
9403 9397
9404 9398 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
9405 9399 "ahci_fatal_error_recovery_handler enter: port %d", port);
9406 9400
9407 9401 /* Port multiplier error */
9408 9402 if (ahci_portp->ahciport_device_type == SATA_DTYPE_PMULT) {
9409 9403 /* FBS code is neither completed nor tested. */
9410 9404 ahci_pmult_error_recovery_handler(ahci_ctlp, ahci_portp,
9411 9405 port, intr_status);
9412 9406
9413 9407 /* Force a port reset */
9414 9408 flag = AHCI_PORT_RESET;
9415 9409 }
9416 9410
9417 9411 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp) ||
9418 9412 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9419 9413
9420 9414 /* Read PxCI to see which commands are still outstanding */
9421 9415 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9422 9416 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
9423 9417
9424 9418 /*
9425 9419 * Read PxCMD.CCS to determine the slot that the HBA
9426 9420 * was processing when the error occurred.
9427 9421 */
9428 9422 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9429 9423 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
9430 9424 failed_slot = (port_cmd_status & AHCI_CMD_STATUS_CCS) >>
9431 9425 AHCI_CMD_STATUS_CCS_SHIFT;
9432 9426
9433 9427 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9434 9428 spkt = ahci_portp->ahciport_err_retri_pkt;
9435 9429 ASSERT(spkt != NULL);
9436 9430 } else {
9437 9431 spkt = ahci_portp->ahciport_slot_pkts[failed_slot];
9438 9432 if (spkt == NULL) {
9439 9433 /* May happen when interface errors occur? */
9440 9434 goto next;
9441 9435 }
9442 9436 }
9443 9437
9444 9438 #if AHCI_DEBUG
9445 9439 /*
9446 9440 * Debugging purpose...
9447 9441 */
9448 9442 if (ahci_portp->ahciport_prd_bytecounts[failed_slot]) {
9449 9443 cmd_header =
9450 9444 &ahci_portp->ahciport_cmd_list[failed_slot];
9451 9445 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
9452 9446 "ahci_fatal_error_recovery_handler: port %d, "
9453 9447 "PRD Byte Count = 0x%x, "
9454 9448 "ahciport_prd_bytecounts = 0x%x", port,
9455 9449 cmd_header->ahcich_prd_byte_count,
9456 9450 ahci_portp->ahciport_prd_bytecounts[failed_slot]);
9457 9451 }
9458 9452 #endif
9459 9453
9460 9454 sata_cmd = &spkt->satapkt_cmd;
9461 9455
9462 9456 /* Fill out the status and error registers for PxIS.TFES */
9463 9457 if (intr_status & AHCI_INTR_STATUS_TFES) {
9464 9458 ahci_rcvd_fisp = &(ahci_portp->ahciport_rcvd_fis->
9465 9459 ahcirf_d2h_register_fis);
9466 9460
9467 9461 /* Copy the error context back to the sata_cmd */
9468 9462 ahci_copy_err_cnxt(sata_cmd, ahci_rcvd_fisp);
9469 9463 }
9470 9464
9471 9465 /* The failed command must be one of the outstanding commands */
9472 9466 failed_tags = 0x1 << failed_slot;
9473 9467 ASSERT(failed_tags & slot_status);
9474 9468
9475 9469 /* Update the sata registers, especially PxSERR register */
9476 9470 ahci_update_sata_registers(ahci_ctlp, port,
9477 9471 &spkt->satapkt_device);
9478 9472
9479 9473 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9480 9474 /* Read PxSACT to see which commands are still outstanding */
9481 9475 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9482 9476 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
9483 9477 }
9484 9478 next:
9485 9479
9486 9480 #if AHCI_DEBUG
9487 9481 /*
9488 9482 * When AHCI_PORT_FLAG_RQSENSE or AHCI_PORT_FLAG_RDLOGEXT flag is
9489 9483 * set, it means a fatal error happened after REQUEST SENSE command
9490 9484 * or READ LOG EXT command is delivered to the HBA during the error
9491 9485 * recovery process. At this time, the only outstanding command is
9492 9486 * supposed to be REQUEST SENSE command or READ LOG EXT command.
9493 9487 */
9494 9488 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9495 9489 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9496 9490 "ahci_fatal_error_recovery_handler: port %d REQUEST SENSE "
9497 9491 "command or READ LOG EXT command for error data retrieval "
9498 9492 "failed", port);
9499 9493 ASSERT(slot_status == 0x1);
9500 9494 ASSERT(failed_slot == 0);
9501 9495 ASSERT(spkt->satapkt_cmd.satacmd_acdb[0] ==
9502 9496 SCMD_REQUEST_SENSE ||
9503 9497 spkt->satapkt_cmd.satacmd_cmd_reg ==
9504 9498 SATAC_READ_LOG_EXT);
9505 9499 }
9506 9500 #endif
9507 9501
9508 9502 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
9509 9503 ahci_portp->ahciport_mop_in_progress++;
9510 9504
9511 9505 rval = ahci_restart_port_wait_till_ready(ahci_ctlp, ahci_portp,
9512 9506 port, flag, &reset_flag);
9513 9507
9514 9508 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_ERRPRINT) {
9515 9509 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_ERRPRINT;
9516 9510 if (rval == AHCI_SUCCESS)
9517 9511 cmn_err(CE_WARN, "!ahci%d: error recovery for port %d "
9518 9512 "succeed", instance, port);
9519 9513 else
9520 9514 cmn_err(CE_WARN, "!ahci%d: error recovery for port %d "
9521 9515 "failed", instance, port);
9522 9516 }
9523 9517
9524 9518 /*
9525 9519 * Won't retrieve error information:
9526 9520 * 1. Port reset was involved to recover
9527 9521 * 2. Device is gone
9528 9522 * 3. IDENTIFY DEVICE command sent to ATAPI device
9529 9523 * 4. REQUEST SENSE or READ LOG EXT command during error recovery
9530 9524 */
9531 9525 if (reset_flag ||
9532 9526 ahci_portp->ahciport_device_type == SATA_DTYPE_NONE ||
9533 9527 spkt && spkt->satapkt_cmd.satacmd_cmd_reg == SATAC_ID_DEVICE ||
9534 9528 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
9535 9529 goto out;
9536 9530
9537 9531 /*
9538 9532 * Deliver READ LOG EXT to gather information about the error when
9539 9533 * a COMRESET has not been performed as part of the error recovery
9540 9534 * during NCQ command processing.
9541 9535 */
9542 9536 if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9543 9537 failed_tags = ahci_get_rdlogext_data(ahci_ctlp,
9544 9538 ahci_portp, port);
9545 9539 goto out;
9546 9540 }
9547 9541
9548 9542 /*
9549 9543 * Deliver REQUEST SENSE for ATAPI command to gather information about
9550 9544 * the error when a COMRESET has not been performed as part of the
9551 9545 * error recovery.
9552 9546 */
9553 9547 if (spkt && ahci_portp->ahciport_device_type == SATA_DTYPE_ATAPI)
9554 9548 ahci_get_rqsense_data(ahci_ctlp, ahci_portp, port, spkt);
9555 9549 out:
9556 9550 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9557 9551 "ahci_fatal_error_recovery_handler: port %d fatal error "
9558 9552 "occurred slot_status = 0x%x, pending_tags = 0x%x, "
9559 9553 "pending_ncq_tags = 0x%x failed_tags = 0x%x",
9560 9554 port, slot_status, ahci_portp->ahciport_pending_tags,
9561 9555 ahci_portp->ahciport_pending_ncq_tags, failed_tags);
9562 9556
9563 9557 ahci_mop_commands(ahci_ctlp,
9564 9558 ahci_portp,
9565 9559 slot_status,
9566 9560 failed_tags, /* failed tags */
9567 9561 0, /* timeout tags */
9568 9562 0, /* aborted tags */
9569 9563 0); /* reset tags */
9570 9564 }
9571 9565
9572 9566 /*
9573 9567 * Used to recovery a PMULT pmport fatal error under FIS-based switching.
9574 9568 * 1. device specific.PxFBS.SDE=1
9575 9569 * 2. Non Device specific.
9576 9570 * Nothing will be done when Command-based switching is employed.
9577 9571 *
9578 9572 * Currently code is neither completed nor tested.
9579 9573 */
9580 9574 static void
9581 9575 ahci_pmult_error_recovery_handler(ahci_ctl_t *ahci_ctlp,
9582 9576 ahci_port_t *ahci_portp, uint8_t port, uint32_t intr_status)
9583 9577 {
9584 9578 #ifndef __lock_lint
9585 9579 _NOTE(ARGUNUSED(intr_status))
9586 9580 #endif
9587 9581 uint32_t port_fbs_ctrl;
9588 9582 int loop_count = 0;
9589 9583 ahci_addr_t addr;
9590 9584
9591 9585 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
9592 9586
9593 9587 /* Nothing will be done under Command-based switching. */
9594 9588 if (!(ahci_ctlp->ahcictl_cap & AHCI_CAP_PMULT_FBSS))
9595 9589 return;
9596 9590
9597 9591 port_fbs_ctrl = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9598 9592 (uint32_t *)AHCI_PORT_PxFBS(ahci_ctlp, port));
9599 9593
9600 9594 if (!(port_fbs_ctrl & AHCI_FBS_EN))
9601 9595 /* FBS is not enabled. */
9602 9596 return;
9603 9597
9604 9598 /* Problem's getting complicated now. */
9605 9599 /*
9606 9600 * If FIS-based switching is used, we need to check
9607 9601 * the PxFBS to see the error type.
9608 9602 */
9609 9603 port_fbs_ctrl = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9610 9604 (uint32_t *)AHCI_PORT_PxFBS(ahci_ctlp, port));
9611 9605
9612 9606 /* Refer to spec(v1.2) 9.3.6.1 */
9613 9607 if (port_fbs_ctrl & AHCI_FBS_SDE) {
9614 9608 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9615 9609 "A Device Sepcific Error: port %d", port);
9616 9610 /*
9617 9611 * Controller has paused commands for all other
9618 9612 * sub-devices until PxFBS.DEC is set.
9619 9613 */
9620 9614 ahci_reject_all_abort_pkts(ahci_ctlp,
9621 9615 ahci_portp, 0);
9622 9616
9623 9617 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
9624 9618 (uint32_t *)AHCI_PORT_PxFBS(ahci_ctlp, port),
9625 9619 port_fbs_ctrl | AHCI_FBS_DEC);
9626 9620
9627 9621 /*
9628 9622 * Wait controller clear PxFBS.DEC,
9629 9623 * then we can continue.
9630 9624 */
9631 9625 loop_count = 0;
9632 9626 do {
9633 9627 port_fbs_ctrl = ddi_get32(ahci_ctlp->
9634 9628 ahcictl_ahci_acc_handle, (uint32_t *)
9635 9629 AHCI_PORT_PxFBS(ahci_ctlp, port));
9636 9630
9637 9631 if (loop_count++ > 1000)
9638 9632 /*
9639 9633 * Esclate the error. Follow
9640 9634 * non-device specific error
9641 9635 * procedure.
9642 9636 */
9643 9637 return;
9644 9638
9645 9639 drv_usecwait(AHCI_100US_USECS);
9646 9640 } while (port_fbs_ctrl & AHCI_FBS_DEC);
9647 9641
9648 9642 /*
9649 9643 * Issue a software reset to ensure drive is in
9650 9644 * a known state.
9651 9645 */
9652 9646 (void) ahci_software_reset(ahci_ctlp,
9653 9647 ahci_portp, &addr);
9654 9648
9655 9649 } else {
9656 9650
9657 9651 /* Process Non-Device Specific Error. */
9658 9652 /* This will be handled later on. */
9659 9653 cmn_err(CE_NOTE, "!FBS is not supported now.");
9660 9654 }
9661 9655 }
9662 9656 /*
9663 9657 * Handle events - fatal error recovery
9664 9658 */
9665 9659 static void
9666 9660 ahci_events_handler(void *args)
9667 9661 {
9668 9662 ahci_event_arg_t *ahci_event_arg;
9669 9663 ahci_ctl_t *ahci_ctlp;
9670 9664 ahci_port_t *ahci_portp;
9671 9665 ahci_addr_t *addrp;
9672 9666 uint32_t event;
9673 9667 int instance;
9674 9668
9675 9669 ahci_event_arg = (ahci_event_arg_t *)args;
9676 9670
9677 9671 ahci_ctlp = ahci_event_arg->ahciea_ctlp;
9678 9672 ahci_portp = ahci_event_arg->ahciea_portp;
9679 9673 addrp = ahci_event_arg->ahciea_addrp;
9680 9674 event = ahci_event_arg->ahciea_event;
9681 9675 instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
9682 9676
9683 9677 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
9684 9678 "ahci_events_handler enter: port %d intr_status = 0x%x",
9685 9679 ahci_portp->ahciport_port_num, event);
9686 9680
9687 9681 mutex_enter(&ahci_portp->ahciport_mutex);
9688 9682
9689 9683 /*
9690 9684 * ahci_intr_phyrdy_change() may have rendered it to
9691 9685 * SATA_DTYPE_NONE.
9692 9686 */
9693 9687 if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
9694 9688 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
9695 9689 "ahci_events_handler: port %d no device attached, "
9696 9690 "and just return without doing anything",
9697 9691 ahci_portp->ahciport_port_num);
9698 9692
9699 9693 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_ERRPRINT) {
9700 9694 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_ERRPRINT;
9701 9695 cmn_err(CE_WARN, "!ahci%d: error recovery for port %d "
9702 9696 "succeed", instance, ahci_portp->ahciport_port_num);
9703 9697 }
9704 9698
9705 9699 goto out;
9706 9700 }
9707 9701
9708 9702 if (event & (AHCI_INTR_STATUS_IFS |
9709 9703 AHCI_INTR_STATUS_HBDS |
9710 9704 AHCI_INTR_STATUS_HBFS |
9711 9705 AHCI_INTR_STATUS_TFES))
9712 9706 ahci_fatal_error_recovery_handler(ahci_ctlp, ahci_portp,
9713 9707 addrp, event);
9714 9708
9715 9709 out:
9716 9710 mutex_exit(&ahci_portp->ahciport_mutex);
9717 9711 }
9718 9712
9719 9713 /*
9720 9714 * ahci_watchdog_handler() and ahci_do_sync_start will call us if they
9721 9715 * detect there are some commands which are timed out.
9722 9716 */
9723 9717 static void
9724 9718 ahci_timeout_pkts(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
9725 9719 uint8_t port, uint32_t tmp_timeout_tags)
9726 9720 {
9727 9721 uint32_t slot_status = 0;
9728 9722 uint32_t finished_tags = 0;
9729 9723 uint32_t timeout_tags = 0;
9730 9724
9731 9725 AHCIDBG(AHCIDBG_TIMEOUT|AHCIDBG_ENTRY, ahci_ctlp,
9732 9726 "ahci_timeout_pkts enter: port %d", port);
9733 9727
9734 9728 mutex_enter(&ahci_portp->ahciport_mutex);
9735 9729
9736 9730 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp) ||
9737 9731 RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp) ||
9738 9732 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9739 9733 /* Read PxCI to see which commands are still outstanding */
9740 9734 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9741 9735 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
9742 9736 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9743 9737 /* Read PxSACT to see which commands are still outstanding */
9744 9738 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9745 9739 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
9746 9740 }
9747 9741
9748 9742 #if AHCI_DEBUG
9749 9743 /*
9750 9744 * When AHCI_PORT_FLAG_RQSENSE or AHCI_PORT_FLAG_RDLOGEXT flag is
9751 9745 * set, it means a fatal error happened after REQUEST SENSE command
9752 9746 * or READ LOG EXT command is delivered to the HBA during the error
9753 9747 * recovery process. At this time, the only outstanding command is
9754 9748 * supposed to be REQUEST SENSE command or READ LOG EXT command.
9755 9749 */
9756 9750 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9757 9751 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_TIMEOUT, ahci_ctlp,
9758 9752 "ahci_timeout_pkts called while REQUEST SENSE "
9759 9753 "command or READ LOG EXT command for error recovery "
9760 9754 "timed out timeout_tags = 0x%x, slot_status = 0x%x, "
9761 9755 "pending_tags = 0x%x, pending_ncq_tags = 0x%x",
9762 9756 tmp_timeout_tags, slot_status,
9763 9757 ahci_portp->ahciport_pending_tags,
9764 9758 ahci_portp->ahciport_pending_ncq_tags);
9765 9759 ASSERT(slot_status == 0x1);
9766 9760 } else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
9767 9761 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_TIMEOUT, ahci_ctlp,
9768 9762 "ahci_timeout_pkts called while executing R/W PMULT "
9769 9763 "command timeout_tags = 0x%x, slot_status = 0x%x",
9770 9764 tmp_timeout_tags, slot_status);
9771 9765 ASSERT(slot_status == 0x1);
9772 9766 }
9773 9767 #endif
9774 9768
9775 9769 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
9776 9770 ahci_portp->ahciport_mop_in_progress++;
9777 9771
9778 9772 (void) ahci_restart_port_wait_till_ready(ahci_ctlp, ahci_portp,
9779 9773 port, AHCI_PORT_RESET, NULL);
9780 9774
9781 9775 /*
9782 9776 * Re-identify timeout tags because some previously checked commands
9783 9777 * could already complete.
9784 9778 */
9785 9779 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9786 9780 finished_tags = ahci_portp->ahciport_pending_tags &
9787 9781 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
9788 9782 timeout_tags = tmp_timeout_tags & ~finished_tags;
9789 9783
9790 9784 AHCIDBG(AHCIDBG_TIMEOUT, ahci_ctlp,
9791 9785 "ahci_timeout_pkts: port %d, finished_tags = 0x%x, "
9792 9786 "timeout_tags = 0x%x, port_cmd_issue = 0x%x, "
9793 9787 "pending_tags = 0x%x ",
9794 9788 port, finished_tags, timeout_tags,
9795 9789 slot_status, ahci_portp->ahciport_pending_tags);
9796 9790 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9797 9791 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
9798 9792 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
9799 9793 timeout_tags = tmp_timeout_tags & ~finished_tags;
9800 9794
9801 9795 AHCIDBG(AHCIDBG_TIMEOUT|AHCIDBG_NCQ, ahci_ctlp,
9802 9796 "ahci_timeout_pkts: port %d, finished_tags = 0x%x, "
9803 9797 "timeout_tags = 0x%x, port_sactive = 0x%x, "
9804 9798 "pending_ncq_tags = 0x%x ",
9805 9799 port, finished_tags, timeout_tags,
9806 9800 slot_status, ahci_portp->ahciport_pending_ncq_tags);
9807 9801 } else if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) ||
9808 9802 RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
9809 9803 timeout_tags = tmp_timeout_tags;
9810 9804 }
9811 9805
9812 9806 ahci_mop_commands(ahci_ctlp,
9813 9807 ahci_portp,
9814 9808 slot_status,
9815 9809 0, /* failed tags */
9816 9810 timeout_tags, /* timeout tags */
9817 9811 0, /* aborted tags */
9818 9812 0); /* reset tags */
9819 9813
9820 9814 mutex_exit(&ahci_portp->ahciport_mutex);
9821 9815 }
9822 9816
9823 9817 /*
9824 9818 * Watchdog handler kicks in every 5 seconds to timeout any commands pending
9825 9819 * for long time.
9826 9820 */
9827 9821 static void
9828 9822 ahci_watchdog_handler(ahci_ctl_t *ahci_ctlp)
9829 9823 {
9830 9824 ahci_port_t *ahci_portp;
9831 9825 sata_pkt_t *spkt;
9832 9826 uint32_t pending_tags;
9833 9827 uint32_t timeout_tags;
9834 9828 uint32_t port_cmd_status;
9835 9829 uint32_t port_sactive;
9836 9830 uint8_t port;
9837 9831 int tmp_slot;
9838 9832 int current_slot;
9839 9833 uint32_t current_tags;
9840 9834 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
9841 9835
9842 9836 mutex_enter(&ahci_ctlp->ahcictl_mutex);
9843 9837
9844 9838 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
9845 9839 "ahci_watchdog_handler entered", NULL);
9846 9840
9847 9841 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
9848 9842 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
9849 9843 continue;
9850 9844 }
9851 9845
9852 9846 ahci_portp = ahci_ctlp->ahcictl_ports[port];
9853 9847
9854 9848 mutex_enter(&ahci_portp->ahciport_mutex);
9855 9849 if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
9856 9850 mutex_exit(&ahci_portp->ahciport_mutex);
9857 9851 continue;
9858 9852 }
9859 9853
9860 9854 /* Skip the check for those ports in error recovery */
9861 9855 if ((ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) &&
9862 9856 !(ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))) {
9863 9857 mutex_exit(&ahci_portp->ahciport_mutex);
9864 9858 continue;
9865 9859 }
9866 9860
9867 9861 pending_tags = 0;
9868 9862 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9869 9863 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
9870 9864
9871 9865 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) ||
9872 9866 RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
9873 9867 current_slot = 0;
9874 9868 pending_tags = 0x1;
9875 9869 } else if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9876 9870 current_slot =
9877 9871 (port_cmd_status & AHCI_CMD_STATUS_CCS) >>
9878 9872 AHCI_CMD_STATUS_CCS_SHIFT;
9879 9873 pending_tags = ahci_portp->ahciport_pending_tags;
9880 9874 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9881 9875 port_sactive = ddi_get32(
9882 9876 ahci_ctlp->ahcictl_ahci_acc_handle,
9883 9877 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
9884 9878 current_tags = port_sactive &
9885 9879 ~port_cmd_status &
9886 9880 AHCI_NCQ_SLOT_MASK(ahci_portp);
9887 9881 pending_tags = ahci_portp->ahciport_pending_ncq_tags;
9888 9882 }
9889 9883
9890 9884 timeout_tags = 0;
9891 9885 while (pending_tags) {
9892 9886 tmp_slot = ddi_ffs(pending_tags) - 1;
9893 9887 if (tmp_slot == -1) {
9894 9888 break;
9895 9889 }
9896 9890
9897 9891 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
9898 9892 spkt = ahci_portp->ahciport_err_retri_pkt;
9899 9893 else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp))
9900 9894 spkt = ahci_portp->ahciport_rdwr_pmult_pkt;
9901 9895 else
9902 9896 spkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9903 9897
9904 9898 if ((spkt != NULL) && spkt->satapkt_time &&
9905 9899 !(spkt->satapkt_op_mode & SATA_OPMODE_POLLING)) {
9906 9900 /*
9907 9901 * If a packet has survived for more than it's
9908 9902 * max life cycles, it is a candidate for time
9909 9903 * out.
9910 9904 */
9911 9905 ahci_portp->ahciport_slot_timeout[tmp_slot] -=
9912 9906 ahci_watchdog_timeout;
9913 9907
9914 9908 if (ahci_portp->ahciport_slot_timeout[tmp_slot]
9915 9909 > 0)
9916 9910 goto next;
9917 9911
9918 9912 #if AHCI_DEBUG
9919 9913 if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9920 9914 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_TIMEOUT,
9921 9915 ahci_ctlp, "watchdog: the current "
9922 9916 "tags is 0x%x", current_tags);
9923 9917 } else {
9924 9918 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_TIMEOUT,
9925 9919 ahci_ctlp, "watchdog: the current "
9926 9920 "slot is %d", current_slot);
9927 9921 }
9928 9922 #endif
9929 9923
9930 9924 /*
9931 9925 * We need to check whether the HBA has
9932 9926 * begun to execute the command, if not,
9933 9927 * then re-set the timer of the command.
9934 9928 */
9935 9929 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp) &&
9936 9930 (tmp_slot != current_slot) ||
9937 9931 NCQ_CMD_IN_PROGRESS(ahci_portp) &&
9938 9932 ((0x1 << tmp_slot) & current_tags)) {
9939 9933 ahci_portp->ahciport_slot_timeout \
9940 9934 [tmp_slot] = spkt->satapkt_time;
9941 9935 } else {
9942 9936 timeout_tags |= (0x1 << tmp_slot);
9943 9937 cmn_err(CE_WARN, "!ahci%d: watchdog "
9944 9938 "port %d satapkt 0x%p timed out\n",
9945 9939 instance, port, (void *)spkt);
9946 9940 }
9947 9941 }
9948 9942 next:
9949 9943 CLEAR_BIT(pending_tags, tmp_slot);
9950 9944 }
9951 9945
9952 9946 if (timeout_tags) {
9953 9947 mutex_exit(&ahci_portp->ahciport_mutex);
9954 9948 mutex_exit(&ahci_ctlp->ahcictl_mutex);
9955 9949 ahci_timeout_pkts(ahci_ctlp, ahci_portp,
9956 9950 port, timeout_tags);
9957 9951 mutex_enter(&ahci_ctlp->ahcictl_mutex);
9958 9952 mutex_enter(&ahci_portp->ahciport_mutex);
9959 9953 }
9960 9954
9961 9955 mutex_exit(&ahci_portp->ahciport_mutex);
9962 9956 }
9963 9957
9964 9958 /* Re-install the watchdog timeout handler */
9965 9959 if (ahci_ctlp->ahcictl_timeout_id != 0) {
9966 9960 ahci_ctlp->ahcictl_timeout_id =
9967 9961 timeout((void (*)(void *))ahci_watchdog_handler,
9968 9962 (caddr_t)ahci_ctlp, ahci_watchdog_tick);
9969 9963 }
9970 9964
9971 9965 mutex_exit(&ahci_ctlp->ahcictl_mutex);
9972 9966 }
9973 9967
9974 9968 /*
9975 9969 * Fill the error context into sata_cmd for non-queued command error.
9976 9970 */
9977 9971 static void
9978 9972 ahci_copy_err_cnxt(sata_cmd_t *scmd, ahci_fis_d2h_register_t *rfisp)
9979 9973 {
9980 9974 scmd->satacmd_status_reg = GET_RFIS_STATUS(rfisp);
9981 9975 scmd->satacmd_error_reg = GET_RFIS_ERROR(rfisp);
9982 9976 scmd->satacmd_sec_count_lsb = GET_RFIS_SECTOR_COUNT(rfisp);
9983 9977 scmd->satacmd_lba_low_lsb = GET_RFIS_CYL_LOW(rfisp);
9984 9978 scmd->satacmd_lba_mid_lsb = GET_RFIS_CYL_MID(rfisp);
9985 9979 scmd->satacmd_lba_high_lsb = GET_RFIS_CYL_HI(rfisp);
9986 9980 scmd->satacmd_device_reg = GET_RFIS_DEV_HEAD(rfisp);
9987 9981
9988 9982 if (scmd->satacmd_addr_type == ATA_ADDR_LBA48) {
9989 9983 scmd->satacmd_sec_count_msb = GET_RFIS_SECTOR_COUNT_EXP(rfisp);
9990 9984 scmd->satacmd_lba_low_msb = GET_RFIS_CYL_LOW_EXP(rfisp);
9991 9985 scmd->satacmd_lba_mid_msb = GET_RFIS_CYL_MID_EXP(rfisp);
9992 9986 scmd->satacmd_lba_high_msb = GET_RFIS_CYL_HI_EXP(rfisp);
9993 9987 }
9994 9988 }
9995 9989
9996 9990 /*
9997 9991 * Fill the ncq error page into sata_cmd for queued command error.
9998 9992 */
9999 9993 static void
10000 9994 ahci_copy_ncq_err_page(sata_cmd_t *scmd,
10001 9995 struct sata_ncq_error_recovery_page *ncq_err_page)
10002 9996 {
10003 9997 scmd->satacmd_sec_count_msb = ncq_err_page->ncq_sector_count_ext;
10004 9998 scmd->satacmd_sec_count_lsb = ncq_err_page->ncq_sector_count;
10005 9999 scmd->satacmd_lba_low_msb = ncq_err_page->ncq_sector_number_ext;
10006 10000 scmd->satacmd_lba_low_lsb = ncq_err_page->ncq_sector_number;
10007 10001 scmd->satacmd_lba_mid_msb = ncq_err_page->ncq_cyl_low_ext;
10008 10002 scmd->satacmd_lba_mid_lsb = ncq_err_page->ncq_cyl_low;
10009 10003 scmd->satacmd_lba_high_msb = ncq_err_page->ncq_cyl_high_ext;
10010 10004 scmd->satacmd_lba_high_lsb = ncq_err_page->ncq_cyl_high;
10011 10005 scmd->satacmd_device_reg = ncq_err_page->ncq_dev_head;
10012 10006 scmd->satacmd_status_reg = ncq_err_page->ncq_status;
10013 10007 scmd->satacmd_error_reg = ncq_err_page->ncq_error;
10014 10008 }
10015 10009
10016 10010 /*
10017 10011 * Put the respective register value to sata_cmd_t for satacmd_flags.
10018 10012 */
10019 10013 static void
10020 10014 ahci_copy_out_regs(sata_cmd_t *scmd, ahci_fis_d2h_register_t *rfisp)
10021 10015 {
10022 10016 if (scmd->satacmd_flags.sata_copy_out_sec_count_msb)
10023 10017 scmd->satacmd_sec_count_msb = GET_RFIS_SECTOR_COUNT_EXP(rfisp);
10024 10018 if (scmd->satacmd_flags.sata_copy_out_lba_low_msb)
10025 10019 scmd->satacmd_lba_low_msb = GET_RFIS_CYL_LOW_EXP(rfisp);
10026 10020 if (scmd->satacmd_flags.sata_copy_out_lba_mid_msb)
10027 10021 scmd->satacmd_lba_mid_msb = GET_RFIS_CYL_MID_EXP(rfisp);
10028 10022 if (scmd->satacmd_flags.sata_copy_out_lba_high_msb)
10029 10023 scmd->satacmd_lba_high_msb = GET_RFIS_CYL_HI_EXP(rfisp);
10030 10024 if (scmd->satacmd_flags.sata_copy_out_sec_count_lsb)
10031 10025 scmd->satacmd_sec_count_lsb = GET_RFIS_SECTOR_COUNT(rfisp);
10032 10026 if (scmd->satacmd_flags.sata_copy_out_lba_low_lsb)
10033 10027 scmd->satacmd_lba_low_lsb = GET_RFIS_CYL_LOW(rfisp);
10034 10028 if (scmd->satacmd_flags.sata_copy_out_lba_mid_lsb)
10035 10029 scmd->satacmd_lba_mid_lsb = GET_RFIS_CYL_MID(rfisp);
10036 10030 if (scmd->satacmd_flags.sata_copy_out_lba_high_lsb)
10037 10031 scmd->satacmd_lba_high_lsb = GET_RFIS_CYL_HI(rfisp);
10038 10032 if (scmd->satacmd_flags.sata_copy_out_device_reg)
10039 10033 scmd->satacmd_device_reg = GET_RFIS_DEV_HEAD(rfisp);
10040 10034 if (scmd->satacmd_flags.sata_copy_out_error_reg)
10041 10035 scmd->satacmd_error_reg = GET_RFIS_ERROR(rfisp);
10042 10036 }
10043 10037
10044 10038 static void
10045 10039 ahci_log_fatal_error_message(ahci_ctl_t *ahci_ctlp, uint8_t port,
10046 10040 uint32_t intr_status)
10047 10041 {
10048 10042 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
10049 10043
10050 10044 if (intr_status & AHCI_INTR_STATUS_IFS)
10051 10045 cmn_err(CE_WARN, "!ahci%d: ahci port %d has interface fatal "
10052 10046 "error", instance, port);
10053 10047
10054 10048 if (intr_status & AHCI_INTR_STATUS_HBDS)
10055 10049 cmn_err(CE_WARN, "!ahci%d: ahci port %d has bus data error",
10056 10050 instance, port);
10057 10051
10058 10052 if (intr_status & AHCI_INTR_STATUS_HBFS)
10059 10053 cmn_err(CE_WARN, "!ahci%d: ahci port %d has bus fatal error",
10060 10054 instance, port);
10061 10055
10062 10056 if (intr_status & AHCI_INTR_STATUS_TFES)
10063 10057 cmn_err(CE_WARN, "!ahci%d: ahci port %d has task file error",
10064 10058 instance, port);
10065 10059
10066 10060 cmn_err(CE_WARN, "!ahci%d: ahci port %d is trying to do error "
10067 10061 "recovery", instance, port);
10068 10062 }
10069 10063
10070 10064 static void
10071 10065 ahci_dump_commands(ahci_ctl_t *ahci_ctlp, uint8_t port,
10072 10066 uint32_t slot_tags)
10073 10067 {
10074 10068 ahci_port_t *ahci_portp;
10075 10069 int tmp_slot;
10076 10070 sata_pkt_t *spkt;
10077 10071 sata_cmd_t cmd;
10078 10072
10079 10073 ahci_portp = ahci_ctlp->ahcictl_ports[port];
10080 10074 ASSERT(ahci_portp != NULL);
10081 10075
10082 10076 while (slot_tags) {
10083 10077 tmp_slot = ddi_ffs(slot_tags) - 1;
10084 10078 if (tmp_slot == -1) {
10085 10079 break;
10086 10080 }
10087 10081
10088 10082 spkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
10089 10083 if (spkt != NULL) {
10090 10084 cmd = spkt->satapkt_cmd;
10091 10085
10092 10086 cmn_err(CE_WARN, "!satapkt 0x%p: cmd_reg = 0x%x "
10093 10087 "features_reg = 0x%x sec_count_msb = 0x%x "
10094 10088 "lba_low_msb = 0x%x lba_mid_msb = 0x%x "
10095 10089 "lba_high_msb = 0x%x sec_count_lsb = 0x%x "
10096 10090 "lba_low_lsb = 0x%x lba_mid_lsb = 0x%x "
10097 10091 "lba_high_lsb = 0x%x device_reg = 0x%x "
10098 10092 "addr_type = 0x%x cmd_flags = 0x%x", (void *)spkt,
10099 10093 cmd.satacmd_cmd_reg, cmd.satacmd_features_reg,
10100 10094 cmd.satacmd_sec_count_msb, cmd.satacmd_lba_low_msb,
10101 10095 cmd.satacmd_lba_mid_msb, cmd.satacmd_lba_high_msb,
10102 10096 cmd.satacmd_sec_count_lsb, cmd.satacmd_lba_low_lsb,
10103 10097 cmd.satacmd_lba_mid_lsb, cmd.satacmd_lba_high_lsb,
10104 10098 cmd.satacmd_device_reg, cmd.satacmd_addr_type,
10105 10099 *((uint32_t *)&(cmd.satacmd_flags)));
10106 10100 }
10107 10101
10108 10102 CLEAR_BIT(slot_tags, tmp_slot);
10109 10103 }
10110 10104 }
10111 10105
10112 10106 /*
10113 10107 * Dump the serror message to the log.
10114 10108 */
10115 10109 static void
10116 10110 ahci_log_serror_message(ahci_ctl_t *ahci_ctlp, uint8_t port,
10117 10111 uint32_t port_serror, int debug_only)
10118 10112 {
10119 10113 static char err_buf[512];
10120 10114 static char err_msg_header[16];
10121 10115 char *err_msg = err_buf;
10122 10116
10123 10117 *err_buf = '\0';
10124 10118 *err_msg_header = '\0';
10125 10119
10126 10120 if (port_serror & SERROR_DATA_ERR_FIXED) {
10127 10121 err_msg = strcat(err_msg,
10128 10122 "\tRecovered Data Integrity Error (I)\n");
10129 10123 }
10130 10124
10131 10125 if (port_serror & SERROR_COMM_ERR_FIXED) {
10132 10126 err_msg = strcat(err_msg,
10133 10127 "\tRecovered Communication Error (M)\n");
10134 10128 }
10135 10129
10136 10130 if (port_serror & SERROR_DATA_ERR) {
10137 10131 err_msg = strcat(err_msg,
10138 10132 "\tTransient Data Integrity Error (T)\n");
10139 10133 }
10140 10134
10141 10135 if (port_serror & SERROR_PERSISTENT_ERR) {
10142 10136 err_msg = strcat(err_msg,
10143 10137 "\tPersistent Communication or Data Integrity Error (C)\n");
10144 10138 }
10145 10139
10146 10140 if (port_serror & SERROR_PROTOCOL_ERR) {
10147 10141 err_msg = strcat(err_msg, "\tProtocol Error (P)\n");
10148 10142 }
10149 10143
10150 10144 if (port_serror & SERROR_INT_ERR) {
10151 10145 err_msg = strcat(err_msg, "\tInternal Error (E)\n");
10152 10146 }
10153 10147
10154 10148 if (port_serror & SERROR_PHY_RDY_CHG) {
10155 10149 err_msg = strcat(err_msg, "\tPhyRdy Change (N)\n");
10156 10150 }
10157 10151
10158 10152 if (port_serror & SERROR_PHY_INT_ERR) {
10159 10153 err_msg = strcat(err_msg, "\tPhy Internal Error (I)\n");
10160 10154 }
10161 10155
10162 10156 if (port_serror & SERROR_COMM_WAKE) {
10163 10157 err_msg = strcat(err_msg, "\tComm Wake (W)\n");
10164 10158 }
10165 10159
10166 10160 if (port_serror & SERROR_10B_TO_8B_ERR) {
10167 10161 err_msg = strcat(err_msg, "\t10B to 8B Decode Error (B)\n");
10168 10162 }
10169 10163
10170 10164 if (port_serror & SERROR_DISPARITY_ERR) {
10171 10165 err_msg = strcat(err_msg, "\tDisparity Error (D)\n");
10172 10166 }
10173 10167
10174 10168 if (port_serror & SERROR_CRC_ERR) {
10175 10169 err_msg = strcat(err_msg, "\tCRC Error (C)\n");
10176 10170 }
10177 10171
10178 10172 if (port_serror & SERROR_HANDSHAKE_ERR) {
10179 10173 err_msg = strcat(err_msg, "\tHandshake Error (H)\n");
10180 10174 }
10181 10175
10182 10176 if (port_serror & SERROR_LINK_SEQ_ERR) {
10183 10177 err_msg = strcat(err_msg, "\tLink Sequence Error (S)\n");
10184 10178 }
10185 10179
10186 10180 if (port_serror & SERROR_TRANS_ERR) {
10187 10181 err_msg = strcat(err_msg,
10188 10182 "\tTransport state transition error (T)\n");
10189 10183 }
10190 10184
10191 10185 if (port_serror & SERROR_FIS_TYPE) {
10192 10186 err_msg = strcat(err_msg, "\tUnknown FIS Type (F)\n");
10193 10187 }
10194 10188
10195 10189 if (port_serror & SERROR_EXCHANGED_ERR) {
10196 10190 err_msg = strcat(err_msg, "\tExchanged (X)\n");
10197 10191 }
10198 10192
10199 10193 if (*err_msg == '\0')
10200 10194 return;
10201 10195
10202 10196 if (debug_only) {
10203 10197 (void) sprintf(err_msg_header, "port %d", port);
10204 10198 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, err_msg_header, NULL);
10205 10199 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, err_msg, NULL);
10206 10200 } else if (ahci_ctlp) {
10207 10201 cmn_err(CE_WARN, "!ahci%d: %s %s",
10208 10202 ddi_get_instance(ahci_ctlp->ahcictl_dip),
10209 10203 err_msg_header, err_msg);
10210 10204
10211 10205 /* sata trace debug */
10212 10206 sata_trace_debug(ahci_ctlp->ahcictl_dip,
10213 10207 "ahci%d: %s %s", ddi_get_instance(ahci_ctlp->ahcictl_dip),
10214 10208 err_msg_header, err_msg);
10215 10209 } else {
10216 10210 cmn_err(CE_WARN, "!ahci: %s %s", err_msg_header, err_msg);
10217 10211
10218 10212 /* sata trace debug */
10219 10213 sata_trace_debug(NULL, "ahci: %s %s", err_msg_header, err_msg);
10220 10214 }
10221 10215 }
10222 10216
10223 10217 /*
10224 10218 * Translate the sata_address_t type into the ahci_addr_t type.
10225 10219 * sata_device.satadev_addr structure is used as source.
10226 10220 */
10227 10221 static void
10228 10222 ahci_get_ahci_addr(ahci_ctl_t *ahci_ctlp, sata_device_t *sd,
10229 10223 ahci_addr_t *ahci_addrp)
10230 10224 {
10231 10225 sata_address_t *sata_addrp = &sd->satadev_addr;
10232 10226 ahci_addrp->aa_port =
10233 10227 ahci_ctlp->ahcictl_cport_to_port[sata_addrp->cport];
10234 10228 ahci_addrp->aa_pmport = sata_addrp->pmport;
10235 10229
10236 10230 switch (sata_addrp->qual) {
10237 10231 case SATA_ADDR_DCPORT:
10238 10232 case SATA_ADDR_CPORT:
10239 10233 ahci_addrp->aa_qual = AHCI_ADDR_PORT;
10240 10234 break;
10241 10235 case SATA_ADDR_PMULT:
10242 10236 case SATA_ADDR_PMULT_SPEC:
10243 10237 ahci_addrp->aa_qual = AHCI_ADDR_PMULT;
10244 10238 break;
10245 10239 case SATA_ADDR_DPMPORT:
10246 10240 case SATA_ADDR_PMPORT:
10247 10241 ahci_addrp->aa_qual = AHCI_ADDR_PMPORT;
10248 10242 break;
10249 10243 case SATA_ADDR_NULL:
10250 10244 default:
10251 10245 /* something went wrong */
10252 10246 ahci_addrp->aa_qual = AHCI_ADDR_NULL;
10253 10247 break;
10254 10248 }
10255 10249 }
10256 10250
10257 10251 /*
10258 10252 * This routine is to calculate the total number of ports implemented
10259 10253 * by the HBA.
10260 10254 */
10261 10255 static int
10262 10256 ahci_get_num_implemented_ports(uint32_t ports_implemented)
10263 10257 {
10264 10258 uint8_t i;
10265 10259 int num = 0;
10266 10260
10267 10261 for (i = 0; i < AHCI_MAX_PORTS; i++) {
10268 10262 if (((uint32_t)0x1 << i) & ports_implemented)
10269 10263 num++;
10270 10264 }
10271 10265
10272 10266 return (num);
10273 10267 }
10274 10268
10275 10269 #if AHCI_DEBUG
10276 10270 static void
10277 10271 ahci_log(ahci_ctl_t *ahci_ctlp, uint_t level, char *fmt, ...)
10278 10272 {
10279 10273 static char name[16];
10280 10274 va_list ap;
10281 10275
10282 10276 mutex_enter(&ahci_log_mutex);
10283 10277
10284 10278 va_start(ap, fmt);
10285 10279 if (ahci_ctlp) {
10286 10280 (void) sprintf(name, "ahci%d: ",
10287 10281 ddi_get_instance(ahci_ctlp->ahcictl_dip));
10288 10282 } else {
10289 10283 (void) sprintf(name, "ahci: ");
10290 10284 }
10291 10285
10292 10286 (void) vsprintf(ahci_log_buf, fmt, ap);
10293 10287 va_end(ap);
10294 10288
10295 10289 cmn_err(level, "%s%s", name, ahci_log_buf);
10296 10290
10297 10291 mutex_exit(&ahci_log_mutex);
10298 10292 }
10299 10293 #endif
10300 10294
10301 10295 /*
10302 10296 * quiesce(9E) entry point.
10303 10297 *
10304 10298 * This function is called when the system is single-threaded at high
10305 10299 * PIL with preemption disabled. Therefore, this function must not be
10306 10300 * blocked. Because no taskqs are running, there is no need for us to
10307 10301 * take any action for enclosure services which are running in the
10308 10302 * taskq context, especially as no interrupts are generated by it nor
10309 10303 * are any messages expected to come in.
10310 10304 *
10311 10305 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
10312 10306 * DDI_FAILURE indicates an error condition and should almost never happen.
10313 10307 */
10314 10308 static int
10315 10309 ahci_quiesce(dev_info_t *dip)
10316 10310 {
10317 10311 ahci_ctl_t *ahci_ctlp;
10318 10312 ahci_port_t *ahci_portp;
10319 10313 int instance, port;
10320 10314
10321 10315 instance = ddi_get_instance(dip);
10322 10316 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
10323 10317
10324 10318 if (ahci_ctlp == NULL)
10325 10319 return (DDI_FAILURE);
10326 10320
10327 10321 #if AHCI_DEBUG
10328 10322 ahci_debug_flags = 0;
10329 10323 #endif
10330 10324
10331 10325 ahci_ctlp->ahcictl_flags |= AHCI_QUIESCE;
10332 10326
10333 10327 /* disable all the interrupts. */
10334 10328 ahci_disable_all_intrs(ahci_ctlp);
10335 10329
10336 10330 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
10337 10331 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
10338 10332 continue;
10339 10333 }
10340 10334
10341 10335 ahci_portp = ahci_ctlp->ahcictl_ports[port];
10342 10336
10343 10337 /*
10344 10338 * Stop the port by clearing PxCMD.ST
10345 10339 *
10346 10340 * Here we must disable the port interrupt because
10347 10341 * ahci_disable_all_intrs only clear GHC.IE, and IS
10348 10342 * register will be still set if PxIE is enabled.
10349 10343 * When ahci shares one IRQ with other drivers, the
10350 10344 * intr handler may claim the intr mistakenly.
10351 10345 */
10352 10346 ahci_disable_port_intrs(ahci_ctlp, port);
10353 10347 (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
10354 10348 ahci_portp, port);
10355 10349 }
10356 10350
10357 10351 ahci_ctlp->ahcictl_flags &= ~AHCI_QUIESCE;
10358 10352
10359 10353 return (DDI_SUCCESS);
10360 10354 }
10361 10355
10362 10356 /*
10363 10357 * The function will add a sata packet to the done queue.
10364 10358 */
10365 10359 static void
10366 10360 ahci_add_doneq(ahci_port_t *ahci_portp, sata_pkt_t *satapkt, int reason)
10367 10361 {
10368 10362 ASSERT(satapkt != NULL);
10369 10363 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
10370 10364
10371 10365 /* set the reason for all packets */
10372 10366 satapkt->satapkt_reason = reason;
10373 10367 satapkt->satapkt_hba_driver_private = NULL;
10374 10368
10375 10369 if (! (satapkt->satapkt_op_mode & SATA_OPMODE_SYNCH) &&
10376 10370 satapkt->satapkt_comp) {
10377 10371 /*
10378 10372 * only add to queue when mode is not synch and there is
10379 10373 * completion callback
10380 10374 */
10381 10375 *ahci_portp->ahciport_doneqtail = satapkt;
10382 10376 ahci_portp->ahciport_doneqtail =
10383 10377 (sata_pkt_t **)&(satapkt->satapkt_hba_driver_private);
10384 10378 ahci_portp->ahciport_doneq_len++;
10385 10379
10386 10380 } else if ((satapkt->satapkt_op_mode & SATA_OPMODE_SYNCH) &&
10387 10381 ! (satapkt->satapkt_op_mode & SATA_OPMODE_POLLING))
10388 10382 /*
10389 10383 * for sync/non-poll mode, just call cv_broadcast
10390 10384 */
10391 10385 cv_broadcast(&ahci_portp->ahciport_cv);
10392 10386 }
10393 10387
10394 10388 /*
10395 10389 * The function will call completion callback of sata packet on the
10396 10390 * completed queue
10397 10391 */
10398 10392 static void
10399 10393 ahci_flush_doneq(ahci_port_t *ahci_portp)
10400 10394 {
10401 10395 sata_pkt_t *satapkt, *next;
10402 10396
10403 10397 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
10404 10398
10405 10399 if (ahci_portp->ahciport_doneq) {
10406 10400 satapkt = ahci_portp->ahciport_doneq;
10407 10401
10408 10402 ahci_portp->ahciport_doneq = NULL;
10409 10403 ahci_portp->ahciport_doneqtail = &ahci_portp->ahciport_doneq;
10410 10404 ahci_portp->ahciport_doneq_len = 0;
10411 10405
10412 10406 mutex_exit(&ahci_portp->ahciport_mutex);
10413 10407
10414 10408 while (satapkt != NULL) {
10415 10409 next = satapkt->satapkt_hba_driver_private;
10416 10410 satapkt->satapkt_hba_driver_private = NULL;
10417 10411
10418 10412 /* Call the callback */
10419 10413 (*satapkt->satapkt_comp)(satapkt);
10420 10414
10421 10415 satapkt = next;
10422 10416 }
10423 10417
10424 10418 mutex_enter(&ahci_portp->ahciport_mutex);
10425 10419 }
10426 10420 }
10427 10421
10428 10422 /*
10429 10423 * Sets the state for the specified port on the controller to desired state.
10430 10424 * This must be run in the context of the enclosure taskq which ensures that
10431 10425 * only one event is outstanding at any time.
10432 10426 */
10433 10427 static boolean_t
10434 10428 ahci_em_set_led(ahci_ctl_t *ahci_ctlp, uint8_t port, ahci_em_led_state_t desire)
10435 10429 {
10436 10430 ahci_em_led_msg_t msg;
10437 10431 ahci_em_msg_hdr_t hdr;
10438 10432 uint32_t msgval, hdrval;
10439 10433 uint_t i, max_delay = ahci_em_tx_delay_count;
10440 10434
10441 10435 msg.alm_hba = port;
10442 10436 msg.alm_pminfo = 0;
10443 10437 msg.alm_value = 0;
10444 10438
10445 10439 if (desire & AHCI_EM_LED_IDENT_ENABLE) {
10446 10440 msg.alm_value |= AHCI_LED_ON << AHCI_LED_IDENT_OFF;
10447 10441 }
10448 10442
10449 10443 if (desire & AHCI_EM_LED_FAULT_ENABLE) {
10450 10444 msg.alm_value |= AHCI_LED_ON << AHCI_LED_FAULT_OFF;
10451 10445 }
10452 10446
10453 10447 if ((ahci_ctlp->ahcictl_em_ctl & AHCI_HBA_EM_CTL_ATTR_ALHD) == 0 &&
10454 10448 (desire & AHCI_EM_LED_ACTIVITY_DISABLE) == 0) {
10455 10449 msg.alm_value |= AHCI_LED_ON << AHCI_LED_ACTIVITY_OFF;
10456 10450 }
10457 10451
10458 10452 hdr.aemh_rsvd = 0;
10459 10453 hdr.aemh_mlen = sizeof (ahci_em_led_msg_t);
10460 10454 hdr.aemh_dlen = 0;
10461 10455 hdr.aemh_mtype = AHCI_EM_MSG_TYPE_LED;
10462 10456
10463 10457 bcopy(&msg, &msgval, sizeof (msgval));
10464 10458 bcopy(&hdr, &hdrval, sizeof (hdrval));
10465 10459
10466 10460 /*
10467 10461 * First, make sure we can transmit. We should not have been placed in a
10468 10462 * situation where an outstanding transmission is going on.
10469 10463 */
10470 10464 for (i = 0; i < max_delay; i++) {
10471 10465 uint32_t val;
10472 10466
10473 10467 val = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
10474 10468 (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp));
10475 10469 if ((val & AHCI_HBA_EM_CTL_CTL_TM) == 0)
10476 10470 break;
10477 10471
10478 10472 delay(drv_usectohz(ahci_em_tx_delay_ms * 1000));
10479 10473 }
10480 10474
10481 10475 if (i == max_delay)
10482 10476 return (B_FALSE);
10483 10477
10484 10478 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
10485 10479 (uint32_t *)ahci_ctlp->ahcictl_em_tx_off, hdrval);
10486 10480 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
10487 10481 (uint32_t *)(ahci_ctlp->ahcictl_em_tx_off + 4), msgval);
10488 10482 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
10489 10483 (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp), AHCI_HBA_EM_CTL_CTL_TM);
10490 10484
10491 10485 for (i = 0; i < max_delay; i++) {
10492 10486 uint32_t val;
10493 10487
10494 10488 val = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
10495 10489 (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp));
10496 10490 if ((val & AHCI_HBA_EM_CTL_CTL_TM) == 0)
10497 10491 break;
10498 10492
10499 10493 delay(drv_usectohz(ahci_em_tx_delay_ms * 1000));
10500 10494 }
10501 10495
10502 10496 if (i == max_delay)
10503 10497 return (B_FALSE);
10504 10498
10505 10499 return (B_TRUE);
10506 10500 }
10507 10501
10508 10502 typedef struct ahci_em_led_task_arg {
10509 10503 ahci_ctl_t *aelta_ctl;
10510 10504 uint8_t aelta_port;
10511 10505 uint_t aelta_op;
10512 10506 ahci_em_led_state_t aelta_state;
10513 10507 uint_t aelta_ret;
10514 10508 kcondvar_t aelta_cv;
10515 10509 uint_t aelta_ref;
10516 10510 } ahci_em_led_task_arg_t;
10517 10511
10518 10512 static void
10519 10513 ahci_em_led_task_free(ahci_em_led_task_arg_t *task)
10520 10514 {
10521 10515 ASSERT3U(task->aelta_ref, ==, 0);
10522 10516 cv_destroy(&task->aelta_cv);
10523 10517 kmem_free(task, sizeof (*task));
10524 10518 }
10525 10519
10526 10520 static void
10527 10521 ahci_em_led_task(void *arg)
10528 10522 {
10529 10523 boolean_t ret, cleanup = B_FALSE;
10530 10524 ahci_em_led_task_arg_t *led = arg;
10531 10525 ahci_em_led_state_t state;
10532 10526
10533 10527 mutex_enter(&led->aelta_ctl->ahcictl_mutex);
10534 10528 if (led->aelta_ctl->ahcictl_em_flags != AHCI_EM_USABLE) {
10535 10529 led->aelta_ret = EIO;
10536 10530 mutex_exit(&led->aelta_ctl->ahcictl_mutex);
10537 10531 return;
10538 10532 }
10539 10533
10540 10534 state = led->aelta_ctl->ahcictl_em_state[led->aelta_port];
10541 10535 mutex_exit(&led->aelta_ctl->ahcictl_mutex);
10542 10536
10543 10537 switch (led->aelta_op) {
10544 10538 case AHCI_EM_IOC_SET_OP_ADD:
10545 10539 state |= led->aelta_state;
10546 10540 break;
10547 10541 case AHCI_EM_IOC_SET_OP_REM:
10548 10542 state &= ~led->aelta_state;
10549 10543 break;
10550 10544 case AHCI_EM_IOC_SET_OP_SET:
10551 10545 state = led->aelta_state;
10552 10546 break;
10553 10547 default:
10554 10548 led->aelta_ret = ENOTSUP;
10555 10549 return;
10556 10550 }
10557 10551
10558 10552 ret = ahci_em_set_led(led->aelta_ctl, led->aelta_port, state);
10559 10553
10560 10554 mutex_enter(&led->aelta_ctl->ahcictl_mutex);
10561 10555 if (ret) {
10562 10556 led->aelta_ctl->ahcictl_em_state[led->aelta_port] =
10563 10557 led->aelta_state;
10564 10558 led->aelta_ret = 0;
10565 10559 } else {
10566 10560 led->aelta_ret = EIO;
10567 10561 led->aelta_ctl->ahcictl_em_flags |= AHCI_EM_TIMEOUT;
10568 10562 }
10569 10563 led->aelta_ref--;
10570 10564 if (led->aelta_ref > 0) {
10571 10565 cv_signal(&led->aelta_cv);
10572 10566 } else {
10573 10567 cleanup = B_TRUE;
10574 10568 }
10575 10569 mutex_exit(&led->aelta_ctl->ahcictl_mutex);
10576 10570
10577 10571 if (cleanup) {
10578 10572 ahci_em_led_task_free(led);
10579 10573 }
10580 10574 }
10581 10575
10582 10576 static void
10583 10577 ahci_em_reset(void *arg)
10584 10578 {
10585 10579 uint_t i, max_delay = ahci_em_reset_delay_count;
10586 10580 ahci_ctl_t *ahci_ctlp = arg;
10587 10581
10588 10582 /*
10589 10583 * We've been asked to reset the device. The caller should have set the
10590 10584 * resetting flag. Make sure that we don't have a request to quiesce.
10591 10585 */
10592 10586 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10593 10587 ASSERT(ahci_ctlp->ahcictl_em_flags & AHCI_EM_RESETTING);
10594 10588 if (ahci_ctlp->ahcictl_em_flags & AHCI_EM_QUIESCE) {
10595 10589 ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_RESETTING;
10596 10590 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10597 10591 return;
10598 10592 }
10599 10593 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10600 10594
10601 10595 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
10602 10596 (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp), AHCI_HBA_EM_CTL_CTL_RST);
10603 10597 for (i = 0; i < max_delay; i++) {
10604 10598 uint32_t val;
10605 10599
10606 10600 val = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
10607 10601 (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp));
10608 10602 if ((val & AHCI_HBA_EM_CTL_CTL_RST) == 0)
10609 10603 break;
10610 10604
10611 10605 delay(drv_usectohz(ahci_em_reset_delay_ms * 1000));
10612 10606 }
10613 10607
10614 10608 if (i == max_delay) {
10615 10609 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10616 10610 ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_RESETTING;
10617 10611 ahci_ctlp->ahcictl_em_flags |= AHCI_EM_TIMEOUT;
10618 10612 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10619 10613 cmn_err(CE_WARN, "!ahci%d: enclosure timed out resetting",
10620 10614 ddi_get_instance(ahci_ctlp->ahcictl_dip));
10621 10615 return;
10622 10616 }
10623 10617
10624 10618 for (i = 0; i < ahci_ctlp->ahcictl_num_ports; i++) {
10625 10619
10626 10620 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, i))
10627 10621 continue;
10628 10622
10629 10623 /*
10630 10624 * Try to flush all the LEDs as part of reset. If it fails,
10631 10625 * drive on.
10632 10626 */
10633 10627 if (!ahci_em_set_led(ahci_ctlp, i,
10634 10628 ahci_ctlp->ahcictl_em_state[i])) {
10635 10629 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10636 10630 ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_RESETTING;
10637 10631 ahci_ctlp->ahcictl_em_flags |= AHCI_EM_TIMEOUT;
10638 10632 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10639 10633 cmn_err(CE_WARN, "!ahci%d: enclosure timed out "
10640 10634 "setting port %u",
10641 10635 ddi_get_instance(ahci_ctlp->ahcictl_dip), i);
10642 10636 return;
10643 10637 }
10644 10638 }
10645 10639
10646 10640 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10647 10641 ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_RESETTING;
10648 10642 ahci_ctlp->ahcictl_em_flags |= AHCI_EM_READY;
10649 10643 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10650 10644 }
10651 10645
10652 10646 static boolean_t
10653 10647 ahci_em_init(ahci_ctl_t *ahci_ctlp)
10654 10648 {
10655 10649 char name[128];
10656 10650
10657 10651 /*
10658 10652 * First make sure we actually have enclosure services and if so, that
10659 10653 * we have the hardware support that we care about for this.
10660 10654 */
10661 10655 if (ahci_ctlp->ahcictl_em_loc == 0 ||
10662 10656 (ahci_ctlp->ahcictl_em_ctl & AHCI_HBA_EM_CTL_SUPP_LED) == 0)
10663 10657 return (B_TRUE);
10664 10658
10665 10659 /*
10666 10660 * Next, make sure that the buffer is large enough for us. We need two
10667 10661 * dwords or 8 bytes. The location register is stored in dwords.
10668 10662 */
10669 10663 if ((ahci_ctlp->ahcictl_em_loc & AHCI_HBA_EM_LOC_SZ_MASK) <
10670 10664 AHCI_EM_BUFFER_MIN) {
10671 10665 return (B_TRUE);
10672 10666 }
10673 10667
10674 10668 ahci_ctlp->ahcictl_em_flags |= AHCI_EM_PRESENT;
10675 10669
10676 10670 ahci_ctlp->ahcictl_em_tx_off = ((ahci_ctlp->ahcictl_em_loc &
10677 10671 AHCI_HBA_EM_LOC_OFST_MASK) >> AHCI_HBA_EM_LOC_OFST_SHIFT) * 4;
10678 10672 ahci_ctlp->ahcictl_em_tx_off += ahci_ctlp->ahcictl_ahci_addr;
10679 10673
10680 10674 bzero(ahci_ctlp->ahcictl_em_state,
10681 10675 sizeof (ahci_ctlp->ahcictl_em_state));
10682 10676
10683 10677 (void) snprintf(name, sizeof (name), "ahcti_em_taskq%d",
10684 10678 ddi_get_instance(ahci_ctlp->ahcictl_dip));
10685 10679 if ((ahci_ctlp->ahcictl_em_taskq =
10686 10680 ddi_taskq_create(ahci_ctlp->ahcictl_dip, name, 1,
10687 10681 TASKQ_DEFAULTPRI, 0)) == NULL) {
10688 10682 cmn_err(CE_WARN, "!ahci%d: ddi_tasq_create failed for em "
10689 10683 "services", ddi_get_instance(ahci_ctlp->ahcictl_dip));
10690 10684 return (B_FALSE);
10691 10685 }
10692 10686
10693 10687 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10694 10688 ahci_ctlp->ahcictl_em_flags |= AHCI_EM_RESETTING;
10695 10689 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10696 10690 (void) ddi_taskq_dispatch(ahci_ctlp->ahcictl_em_taskq, ahci_em_reset,
10697 10691 ahci_ctlp, DDI_SLEEP);
10698 10692
10699 10693 return (B_TRUE);
10700 10694 }
10701 10695
10702 10696 static int
10703 10697 ahci_em_ioctl_get(ahci_ctl_t *ahci_ctlp, intptr_t arg)
10704 10698 {
10705 10699 int i;
10706 10700 ahci_ioc_em_get_t get;
10707 10701
10708 10702 bzero(&get, sizeof (get));
10709 10703 get.aiemg_nports = ahci_ctlp->ahcictl_ports_implemented;
10710 10704 if ((ahci_ctlp->ahcictl_em_ctl & AHCI_HBA_EM_CTL_ATTR_ALHD) == 0) {
10711 10705 get.aiemg_flags |= AHCI_EM_FLAG_CONTROL_ACTIVITY;
10712 10706 }
10713 10707
10714 10708 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10715 10709 for (i = 0; i < ahci_ctlp->ahcictl_num_ports; i++) {
10716 10710 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, i)) {
10717 10711 continue;
10718 10712 }
10719 10713 get.aiemg_status[i] = ahci_ctlp->ahcictl_em_state[i];
10720 10714 }
10721 10715 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10722 10716
10723 10717 if (ddi_copyout(&get, (void *)arg, sizeof (get), 0) != 0)
10724 10718 return (EFAULT);
10725 10719
10726 10720 return (0);
10727 10721 }
10728 10722
10729 10723 static int
10730 10724 ahci_em_ioctl_set(ahci_ctl_t *ahci_ctlp, intptr_t arg)
10731 10725 {
10732 10726 int ret;
10733 10727 ahci_ioc_em_set_t set;
10734 10728 ahci_em_led_task_arg_t *task;
10735 10729 boolean_t signal, cleanup;
10736 10730
10737 10731 if (ddi_copyin((void *)arg, &set, sizeof (set), 0) != 0)
10738 10732 return (EFAULT);
10739 10733
10740 10734 if (set.aiems_port > ahci_ctlp->ahcictl_num_ports)
10741 10735 return (EINVAL);
10742 10736
10743 10737 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, set.aiems_port)) {
10744 10738 return (EINVAL);
10745 10739 }
10746 10740
10747 10741 if ((set.aiems_leds & ~(AHCI_EM_LED_IDENT_ENABLE |
10748 10742 AHCI_EM_LED_FAULT_ENABLE |
10749 10743 AHCI_EM_LED_ACTIVITY_DISABLE)) != 0) {
10750 10744 return (EINVAL);
10751 10745 }
10752 10746
10753 10747 switch (set.aiems_op) {
10754 10748 case AHCI_EM_IOC_SET_OP_ADD:
10755 10749 case AHCI_EM_IOC_SET_OP_REM:
10756 10750 case AHCI_EM_IOC_SET_OP_SET:
10757 10751 break;
10758 10752 default:
10759 10753 return (EINVAL);
10760 10754 }
10761 10755
10762 10756 if ((set.aiems_leds & AHCI_EM_LED_ACTIVITY_DISABLE) != 0 &&
10763 10757 ((ahci_ctlp->ahcictl_em_ctl & AHCI_HBA_EM_CTL_ATTR_ALHD) != 0)) {
10764 10758 return (ENOTSUP);
10765 10759 }
10766 10760
10767 10761 task = kmem_alloc(sizeof (*task), KM_NOSLEEP | KM_NORMALPRI);
10768 10762 if (task == NULL) {
10769 10763 return (ENOMEM);
10770 10764 }
10771 10765
10772 10766 task->aelta_ctl = ahci_ctlp;
10773 10767 task->aelta_port = (uint8_t)set.aiems_port;
10774 10768 task->aelta_op = set.aiems_op;
10775 10769 task->aelta_state = set.aiems_leds;
10776 10770
10777 10771 cv_init(&task->aelta_cv, NULL, CV_DRIVER, NULL);
10778 10772
10779 10773 /*
10780 10774 * Initialize the reference count to two. One for us and one for the
10781 10775 * taskq. This will be used in case we get canceled.
10782 10776 */
10783 10777 task->aelta_ref = 2;
10784 10778
10785 10779 /*
10786 10780 * Once dispatched, the task state is protected by our global mutex.
10787 10781 */
10788 10782 (void) ddi_taskq_dispatch(ahci_ctlp->ahcictl_em_taskq,
10789 10783 ahci_em_led_task, task, DDI_SLEEP);
10790 10784
10791 10785 signal = B_FALSE;
10792 10786 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10793 10787 while (task->aelta_ref > 1) {
10794 10788 if (cv_wait_sig(&task->aelta_cv, &ahci_ctlp->ahcictl_mutex) ==
10795 10789 0) {
10796 10790 signal = B_TRUE;
10797 10791 break;
10798 10792 }
10799 10793 }
10800 10794
10801 10795 /*
10802 10796 * Remove our reference count. If we were woken up because of a signal
10803 10797 * then the taskq may still be dispatched. In which case we shouldn't
10804 10798 * free this memory until it is done. In that case, the taskq will take
10805 10799 * care of it.
10806 10800 */
10807 10801 task->aelta_ref--;
10808 10802 cleanup = (task->aelta_ref == 0);
10809 10803 if (signal) {
10810 10804 ret = EINTR;
10811 10805 } else {
10812 10806 ret = task->aelta_ret;
10813 10807 }
10814 10808 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10815 10809
10816 10810 if (cleanup) {
10817 10811 ahci_em_led_task_free(task);
10818 10812 }
10819 10813
10820 10814 return (ret);
10821 10815 }
10822 10816
10823 10817 static int
10824 10818 ahci_em_ioctl(dev_info_t *dip, int cmd, intptr_t arg)
10825 10819 {
10826 10820 int inst;
10827 10821 ahci_ctl_t *ahci_ctlp;
10828 10822
10829 10823 inst = ddi_get_instance(dip);
10830 10824 if ((ahci_ctlp = ddi_get_soft_state(ahci_statep, inst)) == NULL) {
10831 10825 return (ENXIO);
10832 10826 }
10833 10827
10834 10828 switch (cmd) {
10835 10829 case AHCI_EM_IOC_GET:
10836 10830 return (ahci_em_ioctl_get(ahci_ctlp, arg));
10837 10831 case AHCI_EM_IOC_SET:
10838 10832 return (ahci_em_ioctl_set(ahci_ctlp, arg));
10839 10833 default:
10840 10834 return (ENOTTY);
10841 10835 }
10842 10836
10843 10837 }
10844 10838
10845 10839 static void
10846 10840 ahci_em_quiesce(ahci_ctl_t *ahci_ctlp)
10847 10841 {
10848 10842 ASSERT(ahci_ctlp->ahcictl_em_flags & AHCI_EM_PRESENT);
10849 10843
10850 10844 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10851 10845 ahci_ctlp->ahcictl_em_flags |= AHCI_EM_QUIESCE;
10852 10846 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10853 10847
10854 10848 ddi_taskq_wait(ahci_ctlp->ahcictl_em_taskq);
10855 10849 }
10856 10850
10857 10851 static void
10858 10852 ahci_em_suspend(ahci_ctl_t *ahci_ctlp)
10859 10853 {
10860 10854 ahci_em_quiesce(ahci_ctlp);
10861 10855
10862 10856 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10863 10857 ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_READY;
10864 10858 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10865 10859 }
10866 10860
10867 10861 static void
10868 10862 ahci_em_resume(ahci_ctl_t *ahci_ctlp)
10869 10863 {
10870 10864 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10871 10865 ahci_ctlp->ahcictl_em_flags |= AHCI_EM_RESETTING;
10872 10866 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10873 10867
10874 10868 (void) ddi_taskq_dispatch(ahci_ctlp->ahcictl_em_taskq, ahci_em_reset,
10875 10869 ahci_ctlp, DDI_SLEEP);
10876 10870 }
10877 10871
10878 10872 static void
10879 10873 ahci_em_fini(ahci_ctl_t *ahci_ctlp)
10880 10874 {
10881 10875 if ((ahci_ctlp->ahcictl_em_flags & AHCI_EM_PRESENT) == 0) {
10882 10876 return;
10883 10877 }
10884 10878
10885 10879 ahci_em_quiesce(ahci_ctlp);
10886 10880 ddi_taskq_destroy(ahci_ctlp->ahcictl_em_taskq);
10887 10881 ahci_ctlp->ahcictl_em_taskq = NULL;
10888 10882 }
↓ open down ↓ |
2942 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX