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