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