Print this page
XXXX introduce drv_sectohz
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/skd/skd.c
+++ new/usr/src/uts/common/io/skd/skd.c
1 1 /*
2 2 *
3 3 * skd.c: Solaris 11/10 Driver for sTec, Inc. S112x PCIe SSD card
4 4 *
5 5 * Solaris driver is based on the Linux driver authored by:
6 6 *
7 7 * Authors/Alphabetical: Dragan Stancevic <dstancevic@stec-inc.com>
8 8 * Gordon Waidhofer <gwaidhofer@stec-inc.com>
9 9 * John Hamilton <jhamilton@stec-inc.com>
10 10 */
11 11
12 12 /*
13 13 * This file and its contents are supplied under the terms of the
14 14 * Common Development and Distribution License ("CDDL"), version 1.0.
15 15 * You may only use this file in accordance with the terms of version
16 16 * 1.0 of the CDDL.
17 17 *
18 18 * A full copy of the text of the CDDL should have accompanied this
19 19 * source. A copy of the CDDL is also available via the Internet at
20 20 * http://www.illumos.org/license/CDDL.
21 21 */
22 22
23 23 /*
24 24 * Copyright 2013 STEC, Inc. All rights reserved.
25 25 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
26 26 */
27 27
28 28 #include <sys/types.h>
29 29 #include <sys/stream.h>
30 30 #include <sys/cmn_err.h>
31 31 #include <sys/kmem.h>
32 32 #include <sys/file.h>
33 33 #include <sys/buf.h>
34 34 #include <sys/uio.h>
35 35 #include <sys/cred.h>
36 36 #include <sys/modctl.h>
37 37 #include <sys/debug.h>
38 38 #include <sys/modctl.h>
39 39 #include <sys/list.h>
40 40 #include <sys/sysmacros.h>
41 41 #include <sys/errno.h>
42 42 #include <sys/pcie.h>
43 43 #include <sys/pci.h>
44 44 #include <sys/ddi.h>
45 45 #include <sys/dditypes.h>
46 46 #include <sys/sunddi.h>
47 47 #include <sys/atomic.h>
48 48 #include <sys/mutex.h>
49 49 #include <sys/param.h>
50 50 #include <sys/devops.h>
51 51 #include <sys/blkdev.h>
52 52 #include <sys/queue.h>
53 53
54 54 #include "skd_s1120.h"
55 55 #include "skd.h"
56 56
57 57 int skd_dbg_level = 0;
58 58
59 59 void *skd_state = NULL;
60 60 int skd_disable_msi = 0;
61 61 int skd_disable_msix = 0;
62 62
63 63 /* Initialized in _init() and tunable, see _init(). */
64 64 clock_t skd_timer_ticks;
65 65
66 66 /* I/O DMA attributes structures. */
67 67 static ddi_dma_attr_t skd_64bit_io_dma_attr = {
68 68 DMA_ATTR_V0, /* dma_attr_version */
69 69 SKD_DMA_LOW_ADDRESS, /* low DMA address range */
70 70 SKD_DMA_HIGH_64BIT_ADDRESS, /* high DMA address range */
71 71 SKD_DMA_XFER_COUNTER, /* DMA counter register */
72 72 SKD_DMA_ADDRESS_ALIGNMENT, /* DMA address alignment */
73 73 SKD_DMA_BURSTSIZES, /* DMA burstsizes */
74 74 SKD_DMA_MIN_XFER_SIZE, /* min effective DMA size */
75 75 SKD_DMA_MAX_XFER_SIZE, /* max DMA xfer size */
76 76 SKD_DMA_SEGMENT_BOUNDARY, /* segment boundary */
77 77 SKD_DMA_SG_LIST_LENGTH, /* s/g list length */
78 78 SKD_DMA_GRANULARITY, /* granularity of device */
79 79 SKD_DMA_XFER_FLAGS /* DMA transfer flags */
80 80 };
81 81
82 82 int skd_isr_type = -1;
83 83
84 84 #define SKD_MAX_QUEUE_DEPTH 255
85 85 #define SKD_MAX_QUEUE_DEPTH_DEFAULT 64
86 86 int skd_max_queue_depth = SKD_MAX_QUEUE_DEPTH_DEFAULT;
87 87
88 88 #define SKD_MAX_REQ_PER_MSG 14
89 89 #define SKD_MAX_REQ_PER_MSG_DEFAULT 1
90 90 int skd_max_req_per_msg = SKD_MAX_REQ_PER_MSG_DEFAULT;
91 91
92 92 #define SKD_MAX_N_SG_PER_REQ 4096
93 93 int skd_sgs_per_request = SKD_N_SG_PER_REQ_DEFAULT;
94 94
95 95 static int skd_sys_quiesce_dev(dev_info_t *);
96 96 static int skd_quiesce_dev(skd_device_t *);
97 97 static int skd_list_skmsg(skd_device_t *, int);
98 98 static int skd_list_skreq(skd_device_t *, int);
99 99 static int skd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
100 100 static int skd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
101 101 static int skd_format_internal_skspcl(struct skd_device *skdev);
102 102 static void skd_start(skd_device_t *);
103 103 static void skd_destroy_mutex(skd_device_t *skdev);
104 104 static void skd_enable_interrupts(struct skd_device *);
105 105 static void skd_request_fn_not_online(skd_device_t *skdev);
106 106 static void skd_send_internal_skspcl(struct skd_device *,
107 107 struct skd_special_context *, uint8_t);
108 108 static void skd_queue(skd_device_t *, skd_buf_private_t *);
109 109 static void *skd_alloc_dma_mem(skd_device_t *, dma_mem_t *, uint8_t);
110 110 static void skd_release_intr(skd_device_t *skdev);
111 111 static void skd_isr_fwstate(struct skd_device *skdev);
112 112 static void skd_isr_msg_from_dev(struct skd_device *skdev);
113 113 static void skd_soft_reset(struct skd_device *skdev);
114 114 static void skd_refresh_device_data(struct skd_device *skdev);
115 115 static void skd_update_props(skd_device_t *, dev_info_t *);
116 116 static void skd_end_request_abnormal(struct skd_device *, skd_buf_private_t *,
117 117 int, int);
118 118 static char *skd_pci_info(struct skd_device *skdev, char *str, size_t len);
119 119
120 120 static skd_buf_private_t *skd_get_queued_pbuf(skd_device_t *);
121 121
122 122 static void skd_bd_driveinfo(void *arg, bd_drive_t *drive);
123 123 static int skd_bd_mediainfo(void *arg, bd_media_t *media);
124 124 static int skd_bd_read(void *arg, bd_xfer_t *xfer);
125 125 static int skd_bd_write(void *arg, bd_xfer_t *xfer);
126 126 static int skd_devid_init(void *arg, dev_info_t *, ddi_devid_t *);
127 127
128 128
129 129 static bd_ops_t skd_bd_ops = {
130 130 BD_OPS_VERSION_0,
131 131 skd_bd_driveinfo,
132 132 skd_bd_mediainfo,
133 133 skd_devid_init,
134 134 NULL, /* sync_cache */
135 135 skd_bd_read,
136 136 skd_bd_write,
137 137 };
138 138
139 139 static ddi_device_acc_attr_t dev_acc_attr = {
140 140 DDI_DEVICE_ATTR_V0,
141 141 DDI_STRUCTURE_LE_ACC,
142 142 DDI_STRICTORDER_ACC
143 143 };
144 144
145 145 /*
146 146 * Solaris module loading/unloading structures
147 147 */
148 148 struct dev_ops skd_dev_ops = {
149 149 DEVO_REV, /* devo_rev */
150 150 0, /* refcnt */
151 151 ddi_no_info, /* getinfo */
152 152 nulldev, /* identify */
153 153 nulldev, /* probe */
154 154 skd_attach, /* attach */
155 155 skd_detach, /* detach */
156 156 nodev, /* reset */
157 157 NULL, /* char/block ops */
158 158 NULL, /* bus operations */
159 159 NULL, /* power management */
160 160 skd_sys_quiesce_dev /* quiesce */
161 161 };
162 162
163 163 static struct modldrv modldrv = {
164 164 &mod_driverops, /* type of module: driver */
165 165 "sTec skd v" DRV_VER_COMPL, /* name of module */
166 166 &skd_dev_ops /* driver dev_ops */
167 167 };
168 168
169 169 static struct modlinkage modlinkage = {
170 170 MODREV_1,
171 171 &modldrv,
172 172 NULL
173 173 };
174 174
175 175 /*
176 176 * sTec-required wrapper for debug printing.
177 177 */
178 178 /*PRINTFLIKE2*/
179 179 static inline void
180 180 Dcmn_err(int lvl, const char *fmt, ...)
181 181 {
182 182 va_list ap;
183 183
184 184 if (skd_dbg_level == 0)
185 185 return;
186 186
187 187 va_start(ap, fmt);
188 188 vcmn_err(lvl, fmt, ap);
189 189 va_end(ap);
190 190 }
191 191
192 192 /*
193 193 * Solaris module loading/unloading routines
194 194 */
195 195
196 196 /*
197 197 *
198 198 * Name: _init, performs initial installation
199 199 *
200 200 * Inputs: None.
201 201 *
202 202 * Returns: Returns the value returned by the ddi_softstate_init function
203 203 * on a failure to create the device state structure or the result
204 204 * of the module install routines.
205 205 *
206 206 */
207 207 int
208 208 _init(void)
209 209 {
↓ open down ↓ |
209 lines elided |
↑ open up ↑ |
210 210 int rval = 0;
211 211 int tgts = 0;
212 212
213 213 tgts |= 0x02;
214 214 tgts |= 0x08; /* In #ifdef NEXENTA block from original sTec drop. */
215 215
216 216 /*
217 217 * drv_usectohz() is a function, so can't initialize it at
218 218 * instantiation.
219 219 */
220 - skd_timer_ticks = drv_usectohz(1000000);
220 + skd_timer_ticks = drv_sectohz(1);
221 221
222 222 Dcmn_err(CE_NOTE,
223 223 "<# Installing skd Driver dbg-lvl=%d %s %x>",
224 224 skd_dbg_level, DRV_BUILD_ID, tgts);
225 225
226 226 rval = ddi_soft_state_init(&skd_state, sizeof (skd_device_t), 0);
227 227 if (rval != DDI_SUCCESS)
228 228 return (rval);
229 229
230 230 bd_mod_init(&skd_dev_ops);
231 231
232 232 rval = mod_install(&modlinkage);
233 233 if (rval != DDI_SUCCESS) {
234 234 ddi_soft_state_fini(&skd_state);
235 235 bd_mod_fini(&skd_dev_ops);
236 236 }
237 237
238 238 return (rval);
239 239 }
240 240
241 241 /*
242 242 *
243 243 * Name: _info, returns information about loadable module.
244 244 *
245 245 * Inputs: modinfo, pointer to module information structure.
246 246 *
247 247 * Returns: Value returned by mod_info().
248 248 *
249 249 */
250 250 int
251 251 _info(struct modinfo *modinfop)
252 252 {
253 253 return (mod_info(&modlinkage, modinfop));
254 254 }
255 255
256 256 /*
257 257 * _fini Prepares a module for unloading. It is called when the system
258 258 * wants to unload a module. If the module determines that it can
259 259 * be unloaded, then _fini() returns the value returned by
260 260 * mod_remove(). Upon successful return from _fini() no other
261 261 * routine in the module will be called before _init() is called.
262 262 *
263 263 * Inputs: None.
264 264 *
265 265 * Returns: DDI_SUCCESS or DDI_FAILURE.
266 266 *
267 267 */
268 268 int
269 269 _fini(void)
270 270 {
271 271 int rval;
272 272
273 273 rval = mod_remove(&modlinkage);
274 274 if (rval == DDI_SUCCESS) {
275 275 ddi_soft_state_fini(&skd_state);
276 276 bd_mod_fini(&skd_dev_ops);
277 277 }
278 278
279 279 return (rval);
280 280 }
281 281
282 282 /*
283 283 * Solaris Register read/write routines
284 284 */
285 285
286 286 /*
287 287 *
288 288 * Name: skd_reg_write64, writes a 64-bit value to specified address
289 289 *
290 290 * Inputs: skdev - device state structure.
291 291 * val - 64-bit value to be written.
292 292 * offset - offset from PCI base address.
293 293 *
294 294 * Returns: Nothing.
295 295 *
296 296 */
297 297 /*
298 298 * Local vars are to keep lint silent. Any compiler worth its weight will
299 299 * optimize it all right out...
300 300 */
301 301 static inline void
302 302 skd_reg_write64(struct skd_device *skdev, uint64_t val, uint32_t offset)
303 303 {
304 304 uint64_t *addr;
305 305
306 306 ASSERT((offset & 0x7) == 0);
307 307 /* LINTED */
308 308 addr = (uint64_t *)(skdev->dev_iobase + offset);
309 309 ddi_put64(skdev->dev_handle, addr, val);
310 310 }
311 311
312 312 /*
313 313 *
314 314 * Name: skd_reg_read32, reads a 32-bit value to specified address
315 315 *
316 316 * Inputs: skdev - device state structure.
317 317 * offset - offset from PCI base address.
318 318 *
319 319 * Returns: val, 32-bit value read from specified PCI address.
320 320 *
321 321 */
322 322 static inline uint32_t
323 323 skd_reg_read32(struct skd_device *skdev, uint32_t offset)
324 324 {
325 325 uint32_t *addr;
326 326
327 327 ASSERT((offset & 0x3) == 0);
328 328 /* LINTED */
329 329 addr = (uint32_t *)(skdev->dev_iobase + offset);
330 330 return (ddi_get32(skdev->dev_handle, addr));
331 331 }
332 332
333 333 /*
334 334 *
335 335 * Name: skd_reg_write32, writes a 32-bit value to specified address
336 336 *
337 337 * Inputs: skdev - device state structure.
338 338 * val - value to be written.
339 339 * offset - offset from PCI base address.
340 340 *
341 341 * Returns: Nothing.
342 342 *
343 343 */
344 344 static inline void
345 345 skd_reg_write32(struct skd_device *skdev, uint32_t val, uint32_t offset)
346 346 {
347 347 uint32_t *addr;
348 348
349 349 ASSERT((offset & 0x3) == 0);
350 350 /* LINTED */
351 351 addr = (uint32_t *)(skdev->dev_iobase + offset);
352 352 ddi_put32(skdev->dev_handle, addr, val);
353 353 }
354 354
355 355
356 356 /*
357 357 * Solaris skd routines
358 358 */
359 359
360 360 /*
361 361 *
362 362 * Name: skd_name, generates the name of the driver.
363 363 *
364 364 * Inputs: skdev - device state structure
365 365 *
366 366 * Returns: char pointer to generated driver name.
367 367 *
368 368 */
369 369 static const char *
370 370 skd_name(struct skd_device *skdev)
371 371 {
372 372 (void) snprintf(skdev->id_str, sizeof (skdev->id_str), "%s:", DRV_NAME);
373 373
374 374 return (skdev->id_str);
375 375 }
376 376
377 377 /*
378 378 *
379 379 * Name: skd_pci_find_capability, searches the PCI capability
380 380 * list for the specified capability.
381 381 *
382 382 * Inputs: skdev - device state structure.
383 383 * cap - capability sought.
384 384 *
385 385 * Returns: Returns position where capability was found.
386 386 * If not found, returns zero.
387 387 *
388 388 */
389 389 static int
390 390 skd_pci_find_capability(struct skd_device *skdev, int cap)
391 391 {
392 392 uint16_t status;
393 393 uint8_t pos, id, hdr;
394 394 int ttl = 48;
395 395
396 396 status = pci_config_get16(skdev->pci_handle, PCI_CONF_STAT);
397 397
398 398 if (!(status & PCI_STAT_CAP))
399 399 return (0);
400 400
401 401 hdr = pci_config_get8(skdev->pci_handle, PCI_CONF_HEADER);
402 402
403 403 if ((hdr & PCI_HEADER_TYPE_M) != 0)
404 404 return (0);
405 405
406 406 pos = pci_config_get8(skdev->pci_handle, PCI_CONF_CAP_PTR);
407 407
408 408 while (ttl-- && pos >= 0x40) {
409 409 pos &= ~3;
410 410 id = pci_config_get8(skdev->pci_handle, pos+PCI_CAP_ID);
411 411 if (id == 0xff)
412 412 break;
413 413 if (id == cap)
414 414 return (pos);
415 415 pos = pci_config_get8(skdev->pci_handle, pos+PCI_CAP_NEXT_PTR);
416 416 }
417 417
418 418 return (0);
419 419 }
420 420
421 421 /*
422 422 *
423 423 * Name: skd_io_done, called to conclude an I/O operation.
424 424 *
425 425 * Inputs: skdev - device state structure.
426 426 * pbuf - I/O request
427 427 * error - contain error value.
428 428 * mode - debug only.
429 429 *
430 430 * Returns: Nothing.
431 431 *
432 432 */
433 433 static void
434 434 skd_io_done(skd_device_t *skdev, skd_buf_private_t *pbuf,
435 435 int error, int mode)
436 436 {
437 437 bd_xfer_t *xfer;
438 438
439 439 ASSERT(pbuf != NULL);
440 440
441 441 xfer = pbuf->x_xfer;
442 442
443 443 switch (mode) {
444 444 case SKD_IODONE_WIOC:
445 445 skdev->iodone_wioc++;
446 446 break;
447 447 case SKD_IODONE_WNIOC:
448 448 skdev->iodone_wnioc++;
449 449 break;
450 450 case SKD_IODONE_WDEBUG:
451 451 skdev->iodone_wdebug++;
452 452 break;
453 453 default:
454 454 skdev->iodone_unknown++;
455 455 }
456 456
457 457 if (error) {
458 458 skdev->ios_errors++;
459 459 cmn_err(CE_WARN,
460 460 "!%s:skd_io_done:ERR=%d %lld-%ld %s", skdev->name,
461 461 error, xfer->x_blkno, xfer->x_nblks,
462 462 (pbuf->dir & B_READ) ? "Read" : "Write");
463 463 }
464 464
465 465 kmem_free(pbuf, sizeof (skd_buf_private_t));
466 466
467 467 bd_xfer_done(xfer, error);
468 468 }
469 469
470 470 /*
471 471 * QUIESCE DEVICE
472 472 */
473 473
474 474 /*
475 475 *
476 476 * Name: skd_sys_quiesce_dev, quiets the device
477 477 *
478 478 * Inputs: dip - dev info strucuture
479 479 *
480 480 * Returns: Zero.
481 481 *
482 482 */
483 483 static int
484 484 skd_sys_quiesce_dev(dev_info_t *dip)
485 485 {
486 486 skd_device_t *skdev;
487 487
488 488 skdev = ddi_get_soft_state(skd_state, ddi_get_instance(dip));
489 489
490 490 /* make sure Dcmn_err() doesn't actually print anything */
491 491 skd_dbg_level = 0;
492 492
493 493 skd_disable_interrupts(skdev);
494 494 skd_soft_reset(skdev);
495 495
496 496 return (0);
497 497 }
498 498
499 499 /*
500 500 *
501 501 * Name: skd_quiesce_dev, quiets the device, but doesn't really do much.
502 502 *
503 503 * Inputs: skdev - Device state.
504 504 *
505 505 * Returns: -EINVAL if device is not in proper state otherwise
506 506 * returns zero.
507 507 *
508 508 */
509 509 static int
510 510 skd_quiesce_dev(skd_device_t *skdev)
511 511 {
512 512 int rc = 0;
513 513
514 514 if (skd_dbg_level)
515 515 Dcmn_err(CE_NOTE, "skd_quiece_dev:");
516 516
517 517 switch (skdev->state) {
518 518 case SKD_DRVR_STATE_BUSY:
519 519 case SKD_DRVR_STATE_BUSY_IMMINENT:
520 520 Dcmn_err(CE_NOTE, "%s: stopping queue", skdev->name);
521 521 break;
522 522 case SKD_DRVR_STATE_ONLINE:
523 523 case SKD_DRVR_STATE_STOPPING:
524 524 case SKD_DRVR_STATE_SYNCING:
525 525 case SKD_DRVR_STATE_PAUSING:
526 526 case SKD_DRVR_STATE_PAUSED:
527 527 case SKD_DRVR_STATE_STARTING:
528 528 case SKD_DRVR_STATE_RESTARTING:
529 529 case SKD_DRVR_STATE_RESUMING:
530 530 default:
531 531 rc = -EINVAL;
532 532 cmn_err(CE_NOTE, "state [%d] not implemented", skdev->state);
533 533 }
534 534
535 535 return (rc);
536 536 }
537 537
538 538 /*
539 539 * UNQUIESCE DEVICE:
540 540 * Note: Assumes lock is held to protect device state.
541 541 */
542 542 /*
543 543 *
544 544 * Name: skd_unquiesce_dev, awkens the device
545 545 *
546 546 * Inputs: skdev - Device state.
547 547 *
548 548 * Returns: -EINVAL if device is not in proper state otherwise
549 549 * returns zero.
550 550 *
551 551 */
552 552 static int
553 553 skd_unquiesce_dev(struct skd_device *skdev)
554 554 {
555 555 Dcmn_err(CE_NOTE, "skd_unquiece_dev:");
556 556
557 557 skd_log_skdev(skdev, "unquiesce");
558 558 if (skdev->state == SKD_DRVR_STATE_ONLINE) {
559 559 Dcmn_err(CE_NOTE, "**** device already ONLINE");
560 560
561 561 return (0);
562 562 }
563 563 if (skdev->drive_state != FIT_SR_DRIVE_ONLINE) {
564 564 /*
565 565 * If there has been an state change to other than
566 566 * ONLINE, we will rely on controller state change
567 567 * to come back online and restart the queue.
568 568 * The BUSY state means that driver is ready to
569 569 * continue normal processing but waiting for controller
570 570 * to become available.
571 571 */
572 572 skdev->state = SKD_DRVR_STATE_BUSY;
573 573 Dcmn_err(CE_NOTE, "drive BUSY state\n");
574 574
575 575 return (0);
576 576 }
577 577 /*
578 578 * Drive just come online, driver is either in startup,
579 579 * paused performing a task, or bust waiting for hardware.
580 580 */
581 581 switch (skdev->state) {
582 582 case SKD_DRVR_STATE_PAUSED:
583 583 case SKD_DRVR_STATE_BUSY:
584 584 case SKD_DRVR_STATE_BUSY_IMMINENT:
585 585 case SKD_DRVR_STATE_BUSY_ERASE:
586 586 case SKD_DRVR_STATE_STARTING:
587 587 case SKD_DRVR_STATE_RESTARTING:
588 588 case SKD_DRVR_STATE_FAULT:
589 589 case SKD_DRVR_STATE_IDLE:
590 590 case SKD_DRVR_STATE_LOAD:
591 591 skdev->state = SKD_DRVR_STATE_ONLINE;
592 592 Dcmn_err(CE_NOTE, "%s: sTec s1120 ONLINE", skdev->name);
593 593 Dcmn_err(CE_NOTE, "%s: Starting request queue", skdev->name);
594 594 Dcmn_err(CE_NOTE,
595 595 "%s: queue depth limit=%d hard=%d soft=%d lowat=%d",
596 596 skdev->name,
597 597 skdev->queue_depth_limit,
598 598 skdev->hard_queue_depth_limit,
599 599 skdev->soft_queue_depth_limit,
600 600 skdev->queue_depth_lowat);
601 601
602 602 skdev->gendisk_on = 1;
603 603 cv_signal(&skdev->cv_waitq);
604 604 break;
605 605 case SKD_DRVR_STATE_DISAPPEARED:
606 606 default:
607 607 cmn_err(CE_NOTE, "**** driver state %d, not implemented \n",
608 608 skdev->state);
609 609 return (-EBUSY);
610 610 }
611 611
612 612 return (0);
613 613 }
614 614
615 615 /*
616 616 * READ/WRITE REQUESTS
617 617 */
618 618
619 619 /*
620 620 *
621 621 * Name: skd_blkdev_preop_sg_list, builds the S/G list from info
622 622 * passed in by the blkdev driver.
623 623 *
624 624 * Inputs: skdev - device state structure.
625 625 * skreq - request structure.
626 626 * sg_byte_count - data transfer byte count.
627 627 *
628 628 * Returns: Nothing.
629 629 *
630 630 */
631 631 /*ARGSUSED*/
632 632 static void
633 633 skd_blkdev_preop_sg_list(struct skd_device *skdev,
634 634 struct skd_request_context *skreq, uint32_t *sg_byte_count)
635 635 {
636 636 bd_xfer_t *xfer;
637 637 skd_buf_private_t *pbuf;
638 638 int i, bcount = 0;
639 639 uint_t n_sg;
640 640
641 641 *sg_byte_count = 0;
642 642
643 643 ASSERT(skreq->sg_data_dir == SKD_DATA_DIR_HOST_TO_CARD ||
644 644 skreq->sg_data_dir == SKD_DATA_DIR_CARD_TO_HOST);
645 645
646 646 pbuf = skreq->pbuf;
647 647 ASSERT(pbuf != NULL);
648 648
649 649 xfer = pbuf->x_xfer;
650 650 n_sg = xfer->x_ndmac;
651 651
652 652 ASSERT(n_sg <= skdev->sgs_per_request);
653 653
654 654 skreq->n_sg = n_sg;
655 655
656 656 skreq->io_dma_handle = xfer->x_dmah;
657 657
658 658 skreq->total_sg_bcount = 0;
659 659
660 660 for (i = 0; i < n_sg; i++) {
661 661 ddi_dma_cookie_t *cookiep = &xfer->x_dmac;
662 662 struct fit_sg_descriptor *sgd;
663 663 uint32_t cnt = (uint32_t)cookiep->dmac_size;
664 664
665 665 bcount += cnt;
666 666
667 667 sgd = &skreq->sksg_list[i];
668 668 sgd->control = FIT_SGD_CONTROL_NOT_LAST;
669 669 sgd->byte_count = cnt;
670 670 sgd->host_side_addr = cookiep->dmac_laddress;
671 671 sgd->dev_side_addr = 0; /* not used */
672 672 *sg_byte_count += cnt;
673 673
674 674 skreq->total_sg_bcount += cnt;
675 675
676 676 if ((i + 1) != n_sg)
677 677 ddi_dma_nextcookie(skreq->io_dma_handle, &xfer->x_dmac);
678 678 }
679 679
680 680 skreq->sksg_list[n_sg - 1].next_desc_ptr = 0LL;
681 681 skreq->sksg_list[n_sg - 1].control = FIT_SGD_CONTROL_LAST;
682 682
683 683 (void) ddi_dma_sync(skreq->sksg_dma_address.dma_handle, 0, 0,
684 684 DDI_DMA_SYNC_FORDEV);
685 685 }
686 686
687 687 /*
688 688 *
689 689 * Name: skd_blkdev_postop_sg_list, deallocates DMA
690 690 *
691 691 * Inputs: skdev - device state structure.
692 692 * skreq - skreq data structure.
693 693 *
694 694 * Returns: Nothing.
695 695 *
696 696 */
697 697 /* ARGSUSED */ /* Upstream common source with other platforms. */
698 698 static void
699 699 skd_blkdev_postop_sg_list(struct skd_device *skdev,
700 700 struct skd_request_context *skreq)
701 701 {
702 702 /*
703 703 * restore the next ptr for next IO request so we
704 704 * don't have to set it every time.
705 705 */
706 706 skreq->sksg_list[skreq->n_sg - 1].next_desc_ptr =
707 707 skreq->sksg_dma_address.cookies->dmac_laddress +
708 708 ((skreq->n_sg) * sizeof (struct fit_sg_descriptor));
709 709 }
710 710
711 711 /*
712 712 *
713 713 * Name: skd_start, initiates an I/O.
714 714 *
715 715 * Inputs: skdev - device state structure.
716 716 *
717 717 * Returns: EAGAIN if devicfe is not ONLINE.
718 718 * On error, if the caller is the blkdev driver, return
719 719 * the error value. Otherwise, return zero.
720 720 *
721 721 */
722 722 /* Upstream common source with other platforms. */
723 723 static void
724 724 skd_start(skd_device_t *skdev)
725 725 {
726 726 struct skd_fitmsg_context *skmsg = NULL;
727 727 struct fit_msg_hdr *fmh = NULL;
728 728 struct skd_request_context *skreq = NULL;
729 729 struct waitqueue *waitq = &skdev->waitqueue;
730 730 struct skd_scsi_request *scsi_req;
731 731 skd_buf_private_t *pbuf = NULL;
732 732 int bcount;
733 733
734 734 uint32_t lba;
735 735 uint32_t count;
736 736 uint32_t timo_slot;
737 737 void *cmd_ptr;
738 738 uint32_t sg_byte_count = 0;
739 739
740 740 /*
741 741 * Stop conditions:
742 742 * - There are no more native requests
743 743 * - There are already the maximum number of requests is progress
744 744 * - There are no more skd_request_context entries
745 745 * - There are no more FIT msg buffers
746 746 */
747 747 for (;;) {
748 748 /* Are too many requests already in progress? */
749 749 if (skdev->queue_depth_busy >= skdev->queue_depth_limit) {
750 750 Dcmn_err(CE_NOTE, "qdepth %d, limit %d\n",
751 751 skdev->queue_depth_busy,
752 752 skdev->queue_depth_limit);
753 753 break;
754 754 }
755 755
756 756 WAITQ_LOCK(skdev);
757 757 if (SIMPLEQ_EMPTY(waitq)) {
758 758 WAITQ_UNLOCK(skdev);
759 759 break;
760 760 }
761 761
762 762 /* Is a skd_request_context available? */
763 763 skreq = skdev->skreq_free_list;
764 764 if (skreq == NULL) {
765 765 WAITQ_UNLOCK(skdev);
766 766 break;
767 767 }
768 768
769 769 ASSERT(skreq->state == SKD_REQ_STATE_IDLE);
770 770 ASSERT((skreq->id & SKD_ID_INCR) == 0);
771 771
772 772 skdev->skreq_free_list = skreq->next;
773 773
774 774 skreq->state = SKD_REQ_STATE_BUSY;
775 775 skreq->id += SKD_ID_INCR;
776 776
777 777 /* Start a new FIT msg if there is none in progress. */
778 778 if (skmsg == NULL) {
779 779 /* Are there any FIT msg buffers available? */
780 780 skmsg = skdev->skmsg_free_list;
781 781 if (skmsg == NULL) {
782 782 WAITQ_UNLOCK(skdev);
783 783 break;
784 784 }
785 785
786 786 ASSERT(skmsg->state == SKD_MSG_STATE_IDLE);
787 787 ASSERT((skmsg->id & SKD_ID_INCR) == 0);
788 788
789 789 skdev->skmsg_free_list = skmsg->next;
790 790
791 791 skmsg->state = SKD_MSG_STATE_BUSY;
792 792 skmsg->id += SKD_ID_INCR;
793 793
794 794 /* Initialize the FIT msg header */
795 795 fmh = (struct fit_msg_hdr *)skmsg->msg_buf64;
796 796 bzero(fmh, sizeof (*fmh)); /* Too expensive */
797 797 fmh->protocol_id = FIT_PROTOCOL_ID_SOFIT;
798 798 skmsg->length = sizeof (struct fit_msg_hdr);
799 799 }
800 800
801 801 /*
802 802 * At this point we are committed to either start or reject
803 803 * the native request. Note that a FIT msg may have just been
804 804 * started but contains no SoFIT requests yet.
805 805 * Now - dequeue pbuf.
806 806 */
807 807 pbuf = skd_get_queued_pbuf(skdev);
808 808 WAITQ_UNLOCK(skdev);
809 809
810 810 skreq->pbuf = pbuf;
811 811 lba = pbuf->x_xfer->x_blkno;
812 812 count = pbuf->x_xfer->x_nblks;
813 813 skreq->did_complete = 0;
814 814
815 815 skreq->fitmsg_id = skmsg->id;
816 816
817 817 Dcmn_err(CE_NOTE,
818 818 "pbuf=%p lba=%u(0x%x) count=%u(0x%x) dir=%x\n",
819 819 (void *)pbuf, lba, lba, count, count, pbuf->dir);
820 820
821 821 /*
822 822 * Transcode the request.
823 823 */
824 824 cmd_ptr = &skmsg->msg_buf[skmsg->length];
825 825 bzero(cmd_ptr, 32); /* This is too expensive */
826 826
827 827 scsi_req = cmd_ptr;
828 828 scsi_req->hdr.tag = skreq->id;
829 829 scsi_req->hdr.sg_list_dma_address =
830 830 cpu_to_be64(skreq->sksg_dma_address.cookies->dmac_laddress);
831 831 scsi_req->cdb[1] = 0;
832 832 scsi_req->cdb[2] = (lba & 0xff000000) >> 24;
833 833 scsi_req->cdb[3] = (lba & 0xff0000) >> 16;
834 834 scsi_req->cdb[4] = (lba & 0xff00) >> 8;
835 835 scsi_req->cdb[5] = (lba & 0xff);
836 836 scsi_req->cdb[6] = 0;
837 837 scsi_req->cdb[7] = (count & 0xff00) >> 8;
838 838 scsi_req->cdb[8] = count & 0xff;
839 839 scsi_req->cdb[9] = 0;
840 840
841 841 if (pbuf->dir & B_READ) {
842 842 scsi_req->cdb[0] = 0x28;
843 843 skreq->sg_data_dir = SKD_DATA_DIR_CARD_TO_HOST;
844 844 } else {
845 845 scsi_req->cdb[0] = 0x2a;
846 846 skreq->sg_data_dir = SKD_DATA_DIR_HOST_TO_CARD;
847 847 }
848 848
849 849 skd_blkdev_preop_sg_list(skdev, skreq, &sg_byte_count);
850 850
851 851 scsi_req->hdr.sg_list_len_bytes = cpu_to_be32(sg_byte_count);
852 852
853 853 bcount = (sg_byte_count + 511) / 512;
854 854 scsi_req->cdb[7] = (bcount & 0xff00) >> 8;
855 855 scsi_req->cdb[8] = bcount & 0xff;
856 856
857 857 Dcmn_err(CE_NOTE,
858 858 "skd_start: pbuf=%p skreq->id=%x opc=%x ====>>>>>",
859 859 (void *)pbuf, skreq->id, *scsi_req->cdb);
860 860
861 861 skmsg->length += sizeof (struct skd_scsi_request);
862 862 fmh->num_protocol_cmds_coalesced++;
863 863
864 864 /*
865 865 * Update the active request counts.
866 866 * Capture the timeout timestamp.
867 867 */
868 868 skreq->timeout_stamp = skdev->timeout_stamp;
869 869 timo_slot = skreq->timeout_stamp & SKD_TIMEOUT_SLOT_MASK;
870 870
871 871 atomic_inc_32(&skdev->timeout_slot[timo_slot]);
872 872 atomic_inc_32(&skdev->queue_depth_busy);
873 873
874 874 Dcmn_err(CE_NOTE, "req=0x%x busy=%d timo_slot=%d",
875 875 skreq->id, skdev->queue_depth_busy, timo_slot);
876 876 /*
877 877 * If the FIT msg buffer is full send it.
878 878 */
879 879 if (skmsg->length >= SKD_N_FITMSG_BYTES ||
880 880 fmh->num_protocol_cmds_coalesced >= skd_max_req_per_msg) {
881 881
882 882 atomic_inc_64(&skdev->active_cmds);
883 883 pbuf->skreq = skreq;
884 884
885 885 skdev->fitmsg_sent1++;
886 886 skd_send_fitmsg(skdev, skmsg);
887 887
888 888 skmsg = NULL;
889 889 fmh = NULL;
890 890 }
891 891 }
892 892
893 893 /*
894 894 * Is a FIT msg in progress? If it is empty put the buffer back
895 895 * on the free list. If it is non-empty send what we got.
896 896 * This minimizes latency when there are fewer requests than
897 897 * what fits in a FIT msg.
898 898 */
899 899 if (skmsg != NULL) {
900 900 ASSERT(skmsg->length > sizeof (struct fit_msg_hdr));
901 901 Dcmn_err(CE_NOTE, "sending msg=%p, len %d",
902 902 (void *)skmsg, skmsg->length);
903 903
904 904 skdev->active_cmds++;
905 905
906 906 skdev->fitmsg_sent2++;
907 907 skd_send_fitmsg(skdev, skmsg);
908 908 }
909 909 }
910 910
911 911 /*
912 912 *
913 913 * Name: skd_end_request
914 914 *
915 915 * Inputs: skdev - device state structure.
916 916 * skreq - request structure.
917 917 * error - I/O error value.
918 918 *
919 919 * Returns: Nothing.
920 920 *
921 921 */
922 922 static void
923 923 skd_end_request(struct skd_device *skdev,
924 924 struct skd_request_context *skreq, int error)
925 925 {
926 926 skdev->ios_completed++;
927 927 skd_io_done(skdev, skreq->pbuf, error, SKD_IODONE_WIOC);
928 928 skreq->pbuf = NULL;
929 929 skreq->did_complete = 1;
930 930 }
931 931
932 932 /*
933 933 *
934 934 * Name: skd_end_request_abnormal
935 935 *
936 936 * Inputs: skdev - device state structure.
937 937 * pbuf - I/O request.
938 938 * error - I/O error value.
939 939 * mode - debug
940 940 *
941 941 * Returns: Nothing.
942 942 *
943 943 */
944 944 static void
945 945 skd_end_request_abnormal(skd_device_t *skdev, skd_buf_private_t *pbuf,
946 946 int error, int mode)
947 947 {
948 948 skd_io_done(skdev, pbuf, error, mode);
949 949 }
950 950
951 951 /*
952 952 *
953 953 * Name: skd_request_fn_not_online, handles the condition
954 954 * of the device not being online.
955 955 *
956 956 * Inputs: skdev - device state structure.
957 957 *
958 958 * Returns: nothing (void).
959 959 *
960 960 */
961 961 static void
962 962 skd_request_fn_not_online(skd_device_t *skdev)
963 963 {
964 964 int error;
965 965 skd_buf_private_t *pbuf;
966 966
967 967 ASSERT(skdev->state != SKD_DRVR_STATE_ONLINE);
968 968
969 969 skd_log_skdev(skdev, "req_not_online");
970 970
971 971 switch (skdev->state) {
972 972 case SKD_DRVR_STATE_PAUSING:
973 973 case SKD_DRVR_STATE_PAUSED:
974 974 case SKD_DRVR_STATE_STARTING:
975 975 case SKD_DRVR_STATE_RESTARTING:
976 976 case SKD_DRVR_STATE_WAIT_BOOT:
977 977 /*
978 978 * In case of starting, we haven't started the queue,
979 979 * so we can't get here... but requests are
980 980 * possibly hanging out waiting for us because we
981 981 * reported the dev/skd/0 already. They'll wait
982 982 * forever if connect doesn't complete.
983 983 * What to do??? delay dev/skd/0 ??
984 984 */
985 985 case SKD_DRVR_STATE_BUSY:
986 986 case SKD_DRVR_STATE_BUSY_IMMINENT:
987 987 case SKD_DRVR_STATE_BUSY_ERASE:
988 988 case SKD_DRVR_STATE_DRAINING_TIMEOUT:
989 989 return;
990 990
991 991 case SKD_DRVR_STATE_BUSY_SANITIZE:
992 992 case SKD_DRVR_STATE_STOPPING:
993 993 case SKD_DRVR_STATE_SYNCING:
994 994 case SKD_DRVR_STATE_FAULT:
995 995 case SKD_DRVR_STATE_DISAPPEARED:
996 996 default:
997 997 error = -EIO;
998 998 break;
999 999 }
1000 1000
1001 1001 /*
1002 1002 * If we get here, terminate all pending block requeusts
1003 1003 * with EIO and any scsi pass thru with appropriate sense
1004 1004 */
1005 1005 ASSERT(WAITQ_LOCK_HELD(skdev));
1006 1006 if (SIMPLEQ_EMPTY(&skdev->waitqueue))
1007 1007 return;
1008 1008
1009 1009 while ((pbuf = skd_get_queued_pbuf(skdev)))
1010 1010 skd_end_request_abnormal(skdev, pbuf, error, SKD_IODONE_WNIOC);
1011 1011
1012 1012 cv_signal(&skdev->cv_waitq);
1013 1013 }
1014 1014
1015 1015 /*
1016 1016 * TIMER
1017 1017 */
1018 1018
1019 1019 static void skd_timer_tick_not_online(struct skd_device *skdev);
1020 1020
1021 1021 /*
1022 1022 *
1023 1023 * Name: skd_timer_tick, monitors requests for timeouts.
1024 1024 *
1025 1025 * Inputs: skdev - device state structure.
1026 1026 *
1027 1027 * Returns: Nothing.
1028 1028 *
1029 1029 */
1030 1030 static void
1031 1031 skd_timer_tick(skd_device_t *skdev)
1032 1032 {
1033 1033 uint32_t timo_slot;
1034 1034
1035 1035 skdev->timer_active = 1;
1036 1036
1037 1037 if (skdev->state != SKD_DRVR_STATE_ONLINE) {
1038 1038 skd_timer_tick_not_online(skdev);
1039 1039 goto timer_func_out;
1040 1040 }
1041 1041
1042 1042 skdev->timeout_stamp++;
1043 1043 timo_slot = skdev->timeout_stamp & SKD_TIMEOUT_SLOT_MASK;
1044 1044
1045 1045 /*
1046 1046 * All requests that happened during the previous use of
1047 1047 * this slot should be done by now. The previous use was
1048 1048 * over 7 seconds ago.
1049 1049 */
1050 1050 if (skdev->timeout_slot[timo_slot] == 0) {
1051 1051 goto timer_func_out;
1052 1052 }
1053 1053
1054 1054 /* Something is overdue */
1055 1055 Dcmn_err(CE_NOTE, "found %d timeouts, draining busy=%d",
1056 1056 skdev->timeout_slot[timo_slot],
1057 1057 skdev->queue_depth_busy);
1058 1058 skdev->timer_countdown = SKD_TIMER_SECONDS(3);
1059 1059 skdev->state = SKD_DRVR_STATE_DRAINING_TIMEOUT;
1060 1060 skdev->timo_slot = timo_slot;
1061 1061
1062 1062 timer_func_out:
1063 1063 skdev->timer_active = 0;
1064 1064 }
1065 1065
1066 1066 /*
1067 1067 *
1068 1068 * Name: skd_timer_tick_not_online, handles various device
1069 1069 * state transitions.
1070 1070 *
1071 1071 * Inputs: skdev - device state structure.
1072 1072 *
1073 1073 * Returns: Nothing.
1074 1074 *
1075 1075 */
1076 1076 static void
1077 1077 skd_timer_tick_not_online(struct skd_device *skdev)
1078 1078 {
1079 1079 Dcmn_err(CE_NOTE, "skd_skd_timer_tick_not_online: state=%d tmo=%d",
1080 1080 skdev->state, skdev->timer_countdown);
1081 1081
1082 1082 ASSERT(skdev->state != SKD_DRVR_STATE_ONLINE);
1083 1083
1084 1084 switch (skdev->state) {
1085 1085 case SKD_DRVR_STATE_IDLE:
1086 1086 case SKD_DRVR_STATE_LOAD:
1087 1087 break;
1088 1088 case SKD_DRVR_STATE_BUSY_SANITIZE:
1089 1089 cmn_err(CE_WARN, "!drive busy sanitize[%x], driver[%x]\n",
1090 1090 skdev->drive_state, skdev->state);
1091 1091 break;
1092 1092
1093 1093 case SKD_DRVR_STATE_BUSY:
1094 1094 case SKD_DRVR_STATE_BUSY_IMMINENT:
1095 1095 case SKD_DRVR_STATE_BUSY_ERASE:
1096 1096 Dcmn_err(CE_NOTE, "busy[%x], countdown=%d\n",
1097 1097 skdev->state, skdev->timer_countdown);
1098 1098 if (skdev->timer_countdown > 0) {
1099 1099 skdev->timer_countdown--;
1100 1100 return;
1101 1101 }
1102 1102 cmn_err(CE_WARN, "!busy[%x], timedout=%d, restarting device.",
1103 1103 skdev->state, skdev->timer_countdown);
1104 1104 skd_restart_device(skdev);
1105 1105 break;
1106 1106
1107 1107 case SKD_DRVR_STATE_WAIT_BOOT:
1108 1108 case SKD_DRVR_STATE_STARTING:
1109 1109 if (skdev->timer_countdown > 0) {
1110 1110 skdev->timer_countdown--;
1111 1111 return;
1112 1112 }
1113 1113 /*
1114 1114 * For now, we fault the drive. Could attempt resets to
1115 1115 * revcover at some point.
1116 1116 */
1117 1117 skdev->state = SKD_DRVR_STATE_FAULT;
1118 1118
1119 1119 cmn_err(CE_WARN, "!(%s): DriveFault Connect Timeout (%x)",
1120 1120 skd_name(skdev), skdev->drive_state);
1121 1121
1122 1122 /* start the queue so we can respond with error to requests */
1123 1123 skd_start(skdev);
1124 1124
1125 1125 /* wakeup anyone waiting for startup complete */
1126 1126 skdev->gendisk_on = -1;
1127 1127
1128 1128 cv_signal(&skdev->cv_waitq);
1129 1129 break;
1130 1130
1131 1131
1132 1132 case SKD_DRVR_STATE_PAUSING:
1133 1133 case SKD_DRVR_STATE_PAUSED:
1134 1134 break;
1135 1135
1136 1136 case SKD_DRVR_STATE_DRAINING_TIMEOUT:
1137 1137 cmn_err(CE_WARN,
1138 1138 "!%s: draining busy [%d] tick[%d] qdb[%d] tmls[%d]\n",
1139 1139 skdev->name,
1140 1140 skdev->timo_slot,
1141 1141 skdev->timer_countdown,
1142 1142 skdev->queue_depth_busy,
1143 1143 skdev->timeout_slot[skdev->timo_slot]);
1144 1144 /* if the slot has cleared we can let the I/O continue */
1145 1145 if (skdev->timeout_slot[skdev->timo_slot] == 0) {
1146 1146 Dcmn_err(CE_NOTE, "Slot drained, starting queue.");
1147 1147 skdev->state = SKD_DRVR_STATE_ONLINE;
1148 1148 skd_start(skdev);
1149 1149 return;
1150 1150 }
1151 1151 if (skdev->timer_countdown > 0) {
1152 1152 skdev->timer_countdown--;
1153 1153 return;
1154 1154 }
1155 1155 skd_restart_device(skdev);
1156 1156 break;
1157 1157
1158 1158 case SKD_DRVR_STATE_RESTARTING:
1159 1159 if (skdev->timer_countdown > 0) {
1160 1160 skdev->timer_countdown--;
1161 1161
1162 1162 return;
1163 1163 }
1164 1164 /*
1165 1165 * For now, we fault the drive. Could attempt resets to
1166 1166 * revcover at some point.
1167 1167 */
1168 1168 skdev->state = SKD_DRVR_STATE_FAULT;
1169 1169 cmn_err(CE_WARN, "!(%s): DriveFault Reconnect Timeout (%x)\n",
1170 1170 skd_name(skdev), skdev->drive_state);
1171 1171
1172 1172 /*
1173 1173 * Recovering does two things:
1174 1174 * 1. completes IO with error
1175 1175 * 2. reclaims dma resources
1176 1176 * When is it safe to recover requests?
1177 1177 * - if the drive state is faulted
1178 1178 * - if the state is still soft reset after out timeout
1179 1179 * - if the drive registers are dead (state = FF)
1180 1180 */
1181 1181
1182 1182 if ((skdev->drive_state == FIT_SR_DRIVE_SOFT_RESET) ||
1183 1183 (skdev->drive_state == FIT_SR_DRIVE_FAULT) ||
1184 1184 (skdev->drive_state == FIT_SR_DRIVE_STATE_MASK)) {
1185 1185 /*
1186 1186 * It never came out of soft reset. Try to
1187 1187 * recover the requests and then let them
1188 1188 * fail. This is to mitigate hung processes.
1189 1189 *
1190 1190 * Acquire the interrupt lock since these lists are
1191 1191 * manipulated by interrupt handlers.
1192 1192 */
1193 1193 ASSERT(!WAITQ_LOCK_HELD(skdev));
1194 1194 INTR_LOCK(skdev);
1195 1195 skd_recover_requests(skdev);
1196 1196 INTR_UNLOCK(skdev);
1197 1197 }
1198 1198 /* start the queue so we can respond with error to requests */
1199 1199 skd_start(skdev);
1200 1200 /* wakeup anyone waiting for startup complete */
1201 1201 skdev->gendisk_on = -1;
1202 1202 cv_signal(&skdev->cv_waitq);
1203 1203 break;
1204 1204
1205 1205 case SKD_DRVR_STATE_RESUMING:
1206 1206 case SKD_DRVR_STATE_STOPPING:
1207 1207 case SKD_DRVR_STATE_SYNCING:
1208 1208 case SKD_DRVR_STATE_FAULT:
1209 1209 case SKD_DRVR_STATE_DISAPPEARED:
1210 1210 default:
1211 1211 break;
1212 1212 }
1213 1213 }
1214 1214
1215 1215 /*
1216 1216 *
1217 1217 * Name: skd_timer, kicks off the timer processing.
1218 1218 *
1219 1219 * Inputs: skdev - device state structure.
1220 1220 *
1221 1221 * Returns: Nothing.
1222 1222 *
1223 1223 */
1224 1224 static void
1225 1225 skd_timer(void *arg)
1226 1226 {
1227 1227 skd_device_t *skdev = (skd_device_t *)arg;
1228 1228
1229 1229 /* Someone set us to 0, don't bother rescheduling. */
1230 1230 ADAPTER_STATE_LOCK(skdev);
1231 1231 if (skdev->skd_timer_timeout_id != 0) {
1232 1232 ADAPTER_STATE_UNLOCK(skdev);
1233 1233 /* Pardon the drop-and-then-acquire logic here. */
1234 1234 skd_timer_tick(skdev);
1235 1235 ADAPTER_STATE_LOCK(skdev);
1236 1236 /* Restart timer, if not being stopped. */
1237 1237 if (skdev->skd_timer_timeout_id != 0) {
1238 1238 skdev->skd_timer_timeout_id =
1239 1239 timeout(skd_timer, arg, skd_timer_ticks);
1240 1240 }
1241 1241 }
1242 1242 ADAPTER_STATE_UNLOCK(skdev);
1243 1243 }
1244 1244
1245 1245 /*
1246 1246 *
1247 1247 * Name: skd_start_timer, kicks off the 1-second timer.
1248 1248 *
1249 1249 * Inputs: skdev - device state structure.
1250 1250 *
1251 1251 * Returns: Zero.
1252 1252 *
1253 1253 */
1254 1254 static void
1255 1255 skd_start_timer(struct skd_device *skdev)
1256 1256 {
1257 1257 /* Start one second driver timer. */
1258 1258 ADAPTER_STATE_LOCK(skdev);
1259 1259 ASSERT(skdev->skd_timer_timeout_id == 0);
1260 1260
1261 1261 /*
1262 1262 * Do first "timeout tick" right away, but not in this
1263 1263 * thread.
1264 1264 */
1265 1265 skdev->skd_timer_timeout_id = timeout(skd_timer, skdev, 1);
1266 1266 ADAPTER_STATE_UNLOCK(skdev);
1267 1267 }
1268 1268
1269 1269 /*
1270 1270 * INTERNAL REQUESTS -- generated by driver itself
1271 1271 */
1272 1272
1273 1273 /*
1274 1274 *
1275 1275 * Name: skd_format_internal_skspcl, setups the internal
1276 1276 * FIT request message.
1277 1277 *
1278 1278 * Inputs: skdev - device state structure.
1279 1279 *
1280 1280 * Returns: One.
1281 1281 *
1282 1282 */
1283 1283 static int
1284 1284 skd_format_internal_skspcl(struct skd_device *skdev)
1285 1285 {
1286 1286 struct skd_special_context *skspcl = &skdev->internal_skspcl;
1287 1287 struct fit_sg_descriptor *sgd = &skspcl->req.sksg_list[0];
1288 1288 struct fit_msg_hdr *fmh;
1289 1289 uint64_t dma_address;
1290 1290 struct skd_scsi_request *scsi;
1291 1291
1292 1292 fmh = (struct fit_msg_hdr *)&skspcl->msg_buf64[0];
1293 1293 fmh->protocol_id = FIT_PROTOCOL_ID_SOFIT;
1294 1294 fmh->num_protocol_cmds_coalesced = 1;
1295 1295
1296 1296 /* Instead of 64-bytes in, use 8-(64-bit-words) for linted alignment. */
1297 1297 scsi = (struct skd_scsi_request *)&skspcl->msg_buf64[8];
1298 1298 bzero(scsi, sizeof (*scsi));
1299 1299 dma_address = skspcl->req.sksg_dma_address.cookies->_dmu._dmac_ll;
1300 1300 scsi->hdr.sg_list_dma_address = cpu_to_be64(dma_address);
1301 1301 sgd->control = FIT_SGD_CONTROL_LAST;
1302 1302 sgd->byte_count = 0;
1303 1303 sgd->host_side_addr = skspcl->db_dma_address.cookies->_dmu._dmac_ll;
1304 1304 sgd->dev_side_addr = 0; /* not used */
1305 1305 sgd->next_desc_ptr = 0LL;
1306 1306
1307 1307 return (1);
1308 1308 }
1309 1309
1310 1310 /*
1311 1311 *
1312 1312 * Name: skd_send_internal_skspcl, send internal requests to
1313 1313 * the hardware.
1314 1314 *
1315 1315 * Inputs: skdev - device state structure.
1316 1316 * skspcl - request structure
1317 1317 * opcode - just what it says
1318 1318 *
1319 1319 * Returns: Nothing.
1320 1320 *
1321 1321 */
1322 1322 void
1323 1323 skd_send_internal_skspcl(struct skd_device *skdev,
1324 1324 struct skd_special_context *skspcl, uint8_t opcode)
1325 1325 {
1326 1326 struct fit_sg_descriptor *sgd = &skspcl->req.sksg_list[0];
1327 1327 struct skd_scsi_request *scsi;
1328 1328
1329 1329 if (SKD_REQ_STATE_IDLE != skspcl->req.state) {
1330 1330 /*
1331 1331 * A refresh is already in progress.
1332 1332 * Just wait for it to finish.
1333 1333 */
1334 1334 return;
1335 1335 }
1336 1336
1337 1337 ASSERT(0 == (skspcl->req.id & SKD_ID_INCR));
1338 1338 skspcl->req.state = SKD_REQ_STATE_BUSY;
1339 1339 skspcl->req.id += SKD_ID_INCR;
1340 1340
1341 1341 /* Instead of 64-bytes in, use 8-(64-bit-words) for linted alignment. */
1342 1342 scsi = (struct skd_scsi_request *)&skspcl->msg_buf64[8];
1343 1343 scsi->hdr.tag = skspcl->req.id;
1344 1344
1345 1345 Dcmn_err(CE_NOTE, "internal skspcl: opcode=%x req.id=%x ==========>",
1346 1346 opcode, skspcl->req.id);
1347 1347
1348 1348 switch (opcode) {
1349 1349 case TEST_UNIT_READY:
1350 1350 scsi->cdb[0] = TEST_UNIT_READY;
1351 1351 scsi->cdb[1] = 0x00;
1352 1352 scsi->cdb[2] = 0x00;
1353 1353 scsi->cdb[3] = 0x00;
1354 1354 scsi->cdb[4] = 0x00;
1355 1355 scsi->cdb[5] = 0x00;
1356 1356 sgd->byte_count = 0;
1357 1357 scsi->hdr.sg_list_len_bytes = 0;
1358 1358 break;
1359 1359 case READ_CAPACITY_EXT:
1360 1360 scsi->cdb[0] = READ_CAPACITY_EXT;
1361 1361 scsi->cdb[1] = 0x10;
1362 1362 scsi->cdb[2] = 0x00;
1363 1363 scsi->cdb[3] = 0x00;
1364 1364 scsi->cdb[4] = 0x00;
1365 1365 scsi->cdb[5] = 0x00;
1366 1366 scsi->cdb[6] = 0x00;
1367 1367 scsi->cdb[7] = 0x00;
1368 1368 scsi->cdb[8] = 0x00;
1369 1369 scsi->cdb[9] = 0x00;
1370 1370 scsi->cdb[10] = 0x00;
1371 1371 scsi->cdb[11] = 0x00;
1372 1372 scsi->cdb[12] = 0x00;
1373 1373 scsi->cdb[13] = 0x20;
1374 1374 scsi->cdb[14] = 0x00;
1375 1375 scsi->cdb[15] = 0x00;
1376 1376 sgd->byte_count = SKD_N_READ_CAP_EXT_BYTES;
1377 1377 scsi->hdr.sg_list_len_bytes = cpu_to_be32(sgd->byte_count);
1378 1378 break;
1379 1379 case 0x28:
1380 1380 (void) memset(skspcl->data_buf, 0x65, SKD_N_INTERNAL_BYTES);
1381 1381
1382 1382 scsi->cdb[0] = 0x28;
1383 1383 scsi->cdb[1] = 0x00;
1384 1384 scsi->cdb[2] = 0x00;
1385 1385 scsi->cdb[3] = 0x00;
1386 1386 scsi->cdb[4] = 0x00;
1387 1387 scsi->cdb[5] = 0x00;
1388 1388 scsi->cdb[6] = 0x00;
1389 1389 scsi->cdb[7] = 0x00;
1390 1390 scsi->cdb[8] = 0x01;
1391 1391 scsi->cdb[9] = 0x00;
1392 1392 sgd->byte_count = SKD_N_INTERNAL_BYTES;
1393 1393 scsi->hdr.sg_list_len_bytes = cpu_to_be32(SKD_N_INTERNAL_BYTES);
1394 1394 break;
1395 1395 case INQUIRY:
1396 1396 scsi->cdb[0] = INQUIRY;
1397 1397 scsi->cdb[1] = 0x01; /* evpd */
1398 1398 scsi->cdb[2] = 0x80; /* serial number page */
1399 1399 scsi->cdb[3] = 0x00;
1400 1400 scsi->cdb[4] = 0x10;
1401 1401 scsi->cdb[5] = 0x00;
1402 1402 sgd->byte_count = 16; /* SKD_N_INQ_BYTES */;
1403 1403 scsi->hdr.sg_list_len_bytes = cpu_to_be32(sgd->byte_count);
1404 1404 break;
1405 1405 case INQUIRY2:
1406 1406 scsi->cdb[0] = INQUIRY;
1407 1407 scsi->cdb[1] = 0x00;
1408 1408 scsi->cdb[2] = 0x00; /* serial number page */
1409 1409 scsi->cdb[3] = 0x00;
1410 1410 scsi->cdb[4] = 0x24;
1411 1411 scsi->cdb[5] = 0x00;
1412 1412 sgd->byte_count = 36; /* SKD_N_INQ_BYTES */;
1413 1413 scsi->hdr.sg_list_len_bytes = cpu_to_be32(sgd->byte_count);
1414 1414 break;
1415 1415 case SYNCHRONIZE_CACHE:
1416 1416 scsi->cdb[0] = SYNCHRONIZE_CACHE;
1417 1417 scsi->cdb[1] = 0x00;
1418 1418 scsi->cdb[2] = 0x00;
1419 1419 scsi->cdb[3] = 0x00;
1420 1420 scsi->cdb[4] = 0x00;
1421 1421 scsi->cdb[5] = 0x00;
1422 1422 scsi->cdb[6] = 0x00;
1423 1423 scsi->cdb[7] = 0x00;
1424 1424 scsi->cdb[8] = 0x00;
1425 1425 scsi->cdb[9] = 0x00;
1426 1426 sgd->byte_count = 0;
1427 1427 scsi->hdr.sg_list_len_bytes = 0;
1428 1428 break;
1429 1429 default:
1430 1430 ASSERT("Don't know what to send");
1431 1431 return;
1432 1432
1433 1433 }
1434 1434
1435 1435 skd_send_special_fitmsg(skdev, skspcl);
1436 1436 }
1437 1437
1438 1438 /*
1439 1439 *
1440 1440 * Name: skd_refresh_device_data, sends a TUR command.
1441 1441 *
1442 1442 * Inputs: skdev - device state structure.
1443 1443 *
1444 1444 * Returns: Nothing.
1445 1445 *
1446 1446 */
1447 1447 static void
1448 1448 skd_refresh_device_data(struct skd_device *skdev)
1449 1449 {
1450 1450 struct skd_special_context *skspcl = &skdev->internal_skspcl;
1451 1451
1452 1452 Dcmn_err(CE_NOTE, "refresh_device_data: state=%d", skdev->state);
1453 1453
1454 1454 skd_send_internal_skspcl(skdev, skspcl, TEST_UNIT_READY);
1455 1455 }
1456 1456
1457 1457 /*
1458 1458 *
1459 1459 * Name: skd_complete_internal, handles the completion of
1460 1460 * driver-initiated I/O requests.
1461 1461 *
1462 1462 * Inputs: skdev - device state structure.
1463 1463 * skcomp - completion structure.
1464 1464 * skerr - error structure.
1465 1465 * skspcl - request structure.
1466 1466 *
1467 1467 * Returns: Nothing.
1468 1468 *
1469 1469 */
1470 1470 /* ARGSUSED */ /* Upstream common source with other platforms. */
1471 1471 static void
1472 1472 skd_complete_internal(struct skd_device *skdev,
1473 1473 volatile struct fit_completion_entry_v1 *skcomp,
1474 1474 volatile struct fit_comp_error_info *skerr,
1475 1475 struct skd_special_context *skspcl)
1476 1476 {
1477 1477 uint8_t *buf = skspcl->data_buf;
1478 1478 uint8_t status = 2;
1479 1479 int i;
1480 1480 /* Instead of 64-bytes in, use 8-(64-bit-words) for linted alignment. */
1481 1481 struct skd_scsi_request *scsi =
1482 1482 (struct skd_scsi_request *)&skspcl->msg_buf64[8];
1483 1483
1484 1484 ASSERT(skspcl == &skdev->internal_skspcl);
1485 1485
1486 1486 (void) ddi_dma_sync(skspcl->db_dma_address.dma_handle, 0, 0,
1487 1487 DDI_DMA_SYNC_FORKERNEL);
1488 1488 (void) ddi_dma_sync(skspcl->mb_dma_address.dma_handle, 0, 0,
1489 1489 DDI_DMA_SYNC_FORKERNEL);
1490 1490
1491 1491 Dcmn_err(CE_NOTE, "complete internal %x", scsi->cdb[0]);
1492 1492
1493 1493 skspcl->req.completion = *skcomp;
1494 1494 skspcl->req.state = SKD_REQ_STATE_IDLE;
1495 1495 skspcl->req.id += SKD_ID_INCR;
1496 1496
1497 1497 status = skspcl->req.completion.status;
1498 1498
1499 1499 Dcmn_err(CE_NOTE, "<<<<====== complete_internal: opc=%x", *scsi->cdb);
1500 1500
1501 1501 switch (scsi->cdb[0]) {
1502 1502 case TEST_UNIT_READY:
1503 1503 if (SAM_STAT_GOOD == status) {
1504 1504 skd_send_internal_skspcl(skdev, skspcl,
1505 1505 READ_CAPACITY_EXT);
1506 1506 } else {
1507 1507 if (skdev->state == SKD_DRVR_STATE_STOPPING) {
1508 1508 cmn_err(CE_WARN,
1509 1509 "!%s: TUR failed, don't send anymore"
1510 1510 "state 0x%x", skdev->name, skdev->state);
1511 1511
1512 1512 return;
1513 1513 }
1514 1514
1515 1515 Dcmn_err(CE_NOTE, "%s: TUR failed, retry skerr",
1516 1516 skdev->name);
1517 1517 skd_send_internal_skspcl(skdev, skspcl, 0x00);
1518 1518 }
1519 1519 break;
1520 1520 case READ_CAPACITY_EXT: {
1521 1521 uint64_t cap, Nblocks;
1522 1522 uint64_t xbuf[1];
1523 1523
1524 1524 skdev->read_cap_is_valid = 0;
1525 1525 if (SAM_STAT_GOOD == status) {
1526 1526 bcopy(buf, xbuf, 8);
1527 1527 cap = be64_to_cpu(*xbuf);
1528 1528 skdev->read_cap_last_lba = cap;
1529 1529 skdev->read_cap_blocksize =
1530 1530 (buf[8] << 24) | (buf[9] << 16) |
1531 1531 (buf[10] << 8) | buf[11];
1532 1532
1533 1533 cap *= skdev->read_cap_blocksize;
1534 1534 Dcmn_err(CE_NOTE, " Last LBA: %" PRIu64 " (0x%" PRIx64
1535 1535 "), blk sz: %d, Capacity: %" PRIu64 "GB\n",
1536 1536 skdev->read_cap_last_lba,
1537 1537 skdev->read_cap_last_lba,
1538 1538 skdev->read_cap_blocksize,
1539 1539 cap >> 30ULL);
1540 1540
1541 1541 Nblocks = skdev->read_cap_last_lba + 1;
1542 1542
1543 1543 skdev->Nblocks = Nblocks;
1544 1544 skdev->read_cap_is_valid = 1;
1545 1545
1546 1546 skd_send_internal_skspcl(skdev, skspcl, INQUIRY2);
1547 1547
1548 1548 } else {
1549 1549 Dcmn_err(CE_NOTE, "**** READCAP failed, retry TUR");
1550 1550 skd_send_internal_skspcl(skdev, skspcl,
1551 1551 TEST_UNIT_READY);
1552 1552 }
1553 1553 break;
1554 1554 }
1555 1555 case INQUIRY:
1556 1556 skdev->inquiry_is_valid = 0;
1557 1557 if (SAM_STAT_GOOD == status) {
1558 1558 skdev->inquiry_is_valid = 1;
1559 1559
1560 1560 if (scsi->cdb[1] == 0x1) {
1561 1561 bcopy(&buf[4], skdev->inq_serial_num, 12);
1562 1562 skdev->inq_serial_num[12] = '\0';
1563 1563 } else {
1564 1564 char *tmp = skdev->inq_vendor_id;
1565 1565
1566 1566 bcopy(&buf[8], tmp, 8);
1567 1567 tmp[8] = '\0';
1568 1568 for (i = 7; i >= 0 && tmp[i] != '\0'; i--)
1569 1569 if (tmp[i] == ' ')
1570 1570 tmp[i] = '\0';
1571 1571
1572 1572 tmp = skdev->inq_product_id;
1573 1573 bcopy(&buf[16], tmp, 16);
1574 1574 tmp[16] = '\0';
1575 1575
1576 1576 for (i = 15; i >= 0 && tmp[i] != '\0'; i--)
1577 1577 if (tmp[i] == ' ')
1578 1578 tmp[i] = '\0';
1579 1579
1580 1580 tmp = skdev->inq_product_rev;
1581 1581 bcopy(&buf[32], tmp, 4);
1582 1582 tmp[4] = '\0';
1583 1583 }
1584 1584 }
1585 1585
1586 1586 if (skdev->state != SKD_DRVR_STATE_ONLINE)
1587 1587 if (skd_unquiesce_dev(skdev) < 0)
1588 1588 cmn_err(CE_NOTE, "** failed, to ONLINE device");
1589 1589 break;
1590 1590 case SYNCHRONIZE_CACHE:
1591 1591 skdev->sync_done = (SAM_STAT_GOOD == status) ? 1 : -1;
1592 1592
1593 1593 cv_signal(&skdev->cv_waitq);
1594 1594 break;
1595 1595
1596 1596 default:
1597 1597 ASSERT("we didn't send this");
1598 1598 }
1599 1599 }
1600 1600
1601 1601 /*
1602 1602 * FIT MESSAGES
1603 1603 */
1604 1604
1605 1605 /*
1606 1606 *
1607 1607 * Name: skd_send_fitmsg, send a FIT message to the hardware.
1608 1608 *
1609 1609 * Inputs: skdev - device state structure.
1610 1610 * skmsg - FIT message structure.
1611 1611 *
1612 1612 * Returns: Nothing.
1613 1613 *
1614 1614 */
1615 1615 /* ARGSUSED */ /* Upstream common source with other platforms. */
1616 1616 static void
1617 1617 skd_send_fitmsg(struct skd_device *skdev,
1618 1618 struct skd_fitmsg_context *skmsg)
1619 1619 {
1620 1620 uint64_t qcmd;
1621 1621 struct fit_msg_hdr *fmh;
1622 1622
1623 1623 Dcmn_err(CE_NOTE, "msgbuf's DMA addr: 0x%" PRIx64 ", qdepth_busy=%d",
1624 1624 skmsg->mb_dma_address.cookies->dmac_laddress,
1625 1625 skdev->queue_depth_busy);
1626 1626
1627 1627 Dcmn_err(CE_NOTE, "msg_buf 0x%p, offset %x", (void *)skmsg->msg_buf,
1628 1628 skmsg->offset);
1629 1629
1630 1630 qcmd = skmsg->mb_dma_address.cookies->dmac_laddress;
1631 1631 qcmd |= FIT_QCMD_QID_NORMAL;
1632 1632
1633 1633 fmh = (struct fit_msg_hdr *)skmsg->msg_buf64;
1634 1634 skmsg->outstanding = fmh->num_protocol_cmds_coalesced;
1635 1635
1636 1636 if (skdev->dbg_level > 1) {
1637 1637 uint8_t *bp = skmsg->msg_buf;
1638 1638 int i;
1639 1639
1640 1640 for (i = 0; i < skmsg->length; i += 8) {
1641 1641 Dcmn_err(CE_NOTE, " msg[%2d] %02x %02x %02x %02x "
1642 1642 "%02x %02x %02x %02x",
1643 1643 i, bp[i + 0], bp[i + 1], bp[i + 2],
1644 1644 bp[i + 3], bp[i + 4], bp[i + 5],
1645 1645 bp[i + 6], bp[i + 7]);
1646 1646 if (i == 0) i = 64 - 8;
1647 1647 }
1648 1648 }
1649 1649
1650 1650 (void) ddi_dma_sync(skmsg->mb_dma_address.dma_handle, 0, 0,
1651 1651 DDI_DMA_SYNC_FORDEV);
1652 1652
1653 1653 ASSERT(skmsg->length > sizeof (struct fit_msg_hdr));
1654 1654 if (skmsg->length > 256) {
1655 1655 qcmd |= FIT_QCMD_MSGSIZE_512;
1656 1656 } else if (skmsg->length > 128) {
1657 1657 qcmd |= FIT_QCMD_MSGSIZE_256;
1658 1658 } else if (skmsg->length > 64) {
1659 1659 qcmd |= FIT_QCMD_MSGSIZE_128;
1660 1660 }
1661 1661
1662 1662 skdev->ios_started++;
1663 1663
1664 1664 SKD_WRITEQ(skdev, qcmd, FIT_Q_COMMAND);
1665 1665 }
1666 1666
1667 1667 /*
1668 1668 *
1669 1669 * Name: skd_send_special_fitmsg, send a special FIT message
1670 1670 * to the hardware used driver-originated I/O requests.
1671 1671 *
1672 1672 * Inputs: skdev - device state structure.
1673 1673 * skspcl - skspcl structure.
1674 1674 *
1675 1675 * Returns: Nothing.
1676 1676 *
1677 1677 */
1678 1678 static void
1679 1679 skd_send_special_fitmsg(struct skd_device *skdev,
1680 1680 struct skd_special_context *skspcl)
1681 1681 {
1682 1682 uint64_t qcmd;
1683 1683
1684 1684 Dcmn_err(CE_NOTE, "send_special_fitmsg: pt 1");
1685 1685
1686 1686 if (skdev->dbg_level > 1) {
1687 1687 uint8_t *bp = skspcl->msg_buf;
1688 1688 int i;
1689 1689
1690 1690 for (i = 0; i < SKD_N_SPECIAL_FITMSG_BYTES; i += 8) {
1691 1691 cmn_err(CE_NOTE,
1692 1692 " spcl[%2d] %02x %02x %02x %02x "
1693 1693 "%02x %02x %02x %02x\n", i,
1694 1694 bp[i + 0], bp[i + 1], bp[i + 2], bp[i + 3],
1695 1695 bp[i + 4], bp[i + 5], bp[i + 6], bp[i + 7]);
1696 1696 if (i == 0) i = 64 - 8;
1697 1697 }
1698 1698
1699 1699 for (i = 0; i < skspcl->req.n_sg; i++) {
1700 1700 struct fit_sg_descriptor *sgd =
1701 1701 &skspcl->req.sksg_list[i];
1702 1702
1703 1703 cmn_err(CE_NOTE, " sg[%d] count=%u ctrl=0x%x "
1704 1704 "addr=0x%" PRIx64 " next=0x%" PRIx64,
1705 1705 i, sgd->byte_count, sgd->control,
1706 1706 sgd->host_side_addr, sgd->next_desc_ptr);
1707 1707 }
1708 1708 }
1709 1709
1710 1710 (void) ddi_dma_sync(skspcl->mb_dma_address.dma_handle, 0, 0,
1711 1711 DDI_DMA_SYNC_FORDEV);
1712 1712 (void) ddi_dma_sync(skspcl->db_dma_address.dma_handle, 0, 0,
1713 1713 DDI_DMA_SYNC_FORDEV);
1714 1714
1715 1715 /*
1716 1716 * Special FIT msgs are always 128 bytes: a 64-byte FIT hdr
1717 1717 * and one 64-byte SSDI command.
1718 1718 */
1719 1719 qcmd = skspcl->mb_dma_address.cookies->dmac_laddress;
1720 1720
1721 1721 qcmd |= FIT_QCMD_QID_NORMAL + FIT_QCMD_MSGSIZE_128;
1722 1722
1723 1723 SKD_WRITEQ(skdev, qcmd, FIT_Q_COMMAND);
1724 1724 }
1725 1725
1726 1726 /*
1727 1727 * COMPLETION QUEUE
1728 1728 */
1729 1729
1730 1730 static void skd_complete_other(struct skd_device *skdev,
1731 1731 volatile struct fit_completion_entry_v1 *skcomp,
1732 1732 volatile struct fit_comp_error_info *skerr);
1733 1733
1734 1734 struct sns_info {
1735 1735 uint8_t type;
1736 1736 uint8_t stat;
1737 1737 uint8_t key;
1738 1738 uint8_t asc;
1739 1739 uint8_t ascq;
1740 1740 uint8_t mask;
1741 1741 enum skd_check_status_action action;
1742 1742 };
1743 1743
1744 1744 static struct sns_info skd_chkstat_table[] = {
1745 1745 /* Good */
1746 1746 {0x70, 0x02, RECOVERED_ERROR, 0, 0, 0x1c, SKD_CHECK_STATUS_REPORT_GOOD},
1747 1747
1748 1748 /* Smart alerts */
1749 1749 {0x70, 0x02, NO_SENSE, 0x0B, 0x00, 0x1E, /* warnings */
1750 1750 SKD_CHECK_STATUS_REPORT_SMART_ALERT},
1751 1751 {0x70, 0x02, NO_SENSE, 0x5D, 0x00, 0x1E, /* thresholds */
1752 1752 SKD_CHECK_STATUS_REPORT_SMART_ALERT},
1753 1753 {0x70, 0x02, RECOVERED_ERROR, 0x0B, 0x01, 0x1F, /* temp over trigger */
1754 1754 SKD_CHECK_STATUS_REPORT_SMART_ALERT},
1755 1755
1756 1756 /* Retry (with limits) */
1757 1757 {0x70, 0x02, ABORTED_COMMAND, 0, 0, 0x1C, /* DMA errors */
1758 1758 SKD_CHECK_STATUS_REQUEUE_REQUEST},
1759 1759 {0x70, 0x02, UNIT_ATTENTION, 0x0B, 0x00, 0x1E, /* warnings */
1760 1760 SKD_CHECK_STATUS_REQUEUE_REQUEST},
1761 1761 {0x70, 0x02, UNIT_ATTENTION, 0x5D, 0x00, 0x1E, /* thresholds */
1762 1762 SKD_CHECK_STATUS_REQUEUE_REQUEST},
1763 1763 {0x70, 0x02, UNIT_ATTENTION, 0x80, 0x30, 0x1F, /* backup power */
1764 1764 SKD_CHECK_STATUS_REQUEUE_REQUEST},
1765 1765
1766 1766 /* Busy (or about to be) */
1767 1767 {0x70, 0x02, UNIT_ATTENTION, 0x3f, 0x01, 0x1F, /* fw changed */
1768 1768 SKD_CHECK_STATUS_BUSY_IMMINENT},
1769 1769 };
1770 1770
1771 1771 /*
1772 1772 *
1773 1773 * Name: skd_check_status, checks the return status from a
1774 1774 * completed I/O request.
1775 1775 *
1776 1776 * Inputs: skdev - device state structure.
1777 1777 * cmp_status - SCSI status byte.
1778 1778 * skerr - the error data structure.
1779 1779 *
1780 1780 * Returns: Depending on the error condition, return the action
1781 1781 * to be taken as specified in the skd_chkstat_table.
1782 1782 * If no corresponding value is found in the table
1783 1783 * return SKD_CHECK_STATUS_REPORT_GOOD is no error otherwise
1784 1784 * return SKD_CHECK_STATUS_REPORT_ERROR.
1785 1785 *
1786 1786 */
1787 1787 static enum skd_check_status_action
1788 1788 skd_check_status(struct skd_device *skdev, uint8_t cmp_status,
1789 1789 volatile struct fit_comp_error_info *skerr)
1790 1790 {
1791 1791 /*
1792 1792 * Look up status and sense data to decide how to handle the error
1793 1793 * from the device.
1794 1794 * mask says which fields must match e.g., mask=0x18 means check
1795 1795 * type and stat, ignore key, asc, ascq.
1796 1796 */
1797 1797 int i, n;
1798 1798
1799 1799 Dcmn_err(CE_NOTE, "(%s): key/asc/ascq %02x/%02x/%02x",
1800 1800 skd_name(skdev), skerr->key, skerr->code, skerr->qual);
1801 1801
1802 1802 Dcmn_err(CE_NOTE, "stat: t=%02x stat=%02x k=%02x c=%02x q=%02x",
1803 1803 skerr->type, cmp_status, skerr->key, skerr->code, skerr->qual);
1804 1804
1805 1805 /* Does the info match an entry in the good category? */
1806 1806 n = sizeof (skd_chkstat_table) / sizeof (skd_chkstat_table[0]);
1807 1807 for (i = 0; i < n; i++) {
1808 1808 struct sns_info *sns = &skd_chkstat_table[i];
1809 1809
1810 1810 if (sns->mask & 0x10)
1811 1811 if (skerr->type != sns->type) continue;
1812 1812
1813 1813 if (sns->mask & 0x08)
1814 1814 if (cmp_status != sns->stat) continue;
1815 1815
1816 1816 if (sns->mask & 0x04)
1817 1817 if (skerr->key != sns->key) continue;
1818 1818
1819 1819 if (sns->mask & 0x02)
1820 1820 if (skerr->code != sns->asc) continue;
1821 1821
1822 1822 if (sns->mask & 0x01)
1823 1823 if (skerr->qual != sns->ascq) continue;
1824 1824
1825 1825 if (sns->action == SKD_CHECK_STATUS_REPORT_SMART_ALERT) {
1826 1826 cmn_err(CE_WARN, "!(%s):SMART Alert: sense key/asc/ascq"
1827 1827 " %02x/%02x/%02x",
1828 1828 skd_name(skdev), skerr->key,
1829 1829 skerr->code, skerr->qual);
1830 1830 }
1831 1831
1832 1832 Dcmn_err(CE_NOTE, "skd_check_status: returning %x",
1833 1833 sns->action);
1834 1834
1835 1835 return (sns->action);
1836 1836 }
1837 1837
1838 1838 /*
1839 1839 * No other match, so nonzero status means error,
1840 1840 * zero status means good
1841 1841 */
1842 1842 if (cmp_status) {
1843 1843 cmn_err(CE_WARN,
1844 1844 "!%s: status check: qdepth=%d skmfl=%p (%d) skrfl=%p (%d)",
1845 1845 skdev->name,
1846 1846 skdev->queue_depth_busy,
1847 1847 (void *)skdev->skmsg_free_list, skd_list_skmsg(skdev, 0),
1848 1848 (void *)skdev->skreq_free_list, skd_list_skreq(skdev, 0));
1849 1849
1850 1850 cmn_err(CE_WARN, "!%s: t=%02x stat=%02x k=%02x c=%02x q=%02x",
1851 1851 skdev->name, skerr->type, cmp_status, skerr->key,
1852 1852 skerr->code, skerr->qual);
1853 1853
1854 1854 return (SKD_CHECK_STATUS_REPORT_ERROR);
1855 1855 }
1856 1856
1857 1857 Dcmn_err(CE_NOTE, "status check good default");
1858 1858
1859 1859 return (SKD_CHECK_STATUS_REPORT_GOOD);
1860 1860 }
1861 1861
1862 1862 /*
1863 1863 *
1864 1864 * Name: skd_isr_completion_posted, handles I/O completions.
1865 1865 *
1866 1866 * Inputs: skdev - device state structure.
1867 1867 *
1868 1868 * Returns: Nothing.
1869 1869 *
1870 1870 */
1871 1871 static void
1872 1872 skd_isr_completion_posted(struct skd_device *skdev)
1873 1873 {
1874 1874 volatile struct fit_completion_entry_v1 *skcmp = NULL;
1875 1875 volatile struct fit_comp_error_info *skerr;
1876 1876 struct skd_fitmsg_context *skmsg;
1877 1877 struct skd_request_context *skreq;
1878 1878 skd_buf_private_t *pbuf;
1879 1879 uint16_t req_id;
1880 1880 uint32_t req_slot;
1881 1881 uint32_t timo_slot;
1882 1882 uint32_t msg_slot;
1883 1883 uint16_t cmp_cntxt = 0;
1884 1884 uint8_t cmp_status = 0;
1885 1885 uint8_t cmp_cycle = 0;
1886 1886 uint32_t cmp_bytes = 0;
1887 1887
1888 1888 (void) ddi_dma_sync(skdev->cq_dma_address.dma_handle, 0, 0,
1889 1889 DDI_DMA_SYNC_FORKERNEL);
1890 1890
1891 1891 for (;;) {
1892 1892 ASSERT(skdev->skcomp_ix < SKD_N_COMPLETION_ENTRY);
1893 1893
1894 1894 WAITQ_LOCK(skdev);
1895 1895
1896 1896 skcmp = &skdev->skcomp_table[skdev->skcomp_ix];
1897 1897 cmp_cycle = skcmp->cycle;
1898 1898 cmp_cntxt = skcmp->tag;
1899 1899 cmp_status = skcmp->status;
1900 1900 cmp_bytes = be32_to_cpu(skcmp->num_returned_bytes);
1901 1901
1902 1902 skerr = &skdev->skerr_table[skdev->skcomp_ix];
1903 1903
1904 1904 Dcmn_err(CE_NOTE,
1905 1905 "cycle=%d ix=%d got cycle=%d cmdctxt=0x%x stat=%d "
1906 1906 "qdepth_busy=%d rbytes=0x%x proto=%d",
1907 1907 skdev->skcomp_cycle, skdev->skcomp_ix,
1908 1908 cmp_cycle, cmp_cntxt, cmp_status,
1909 1909 skdev->queue_depth_busy, cmp_bytes, skdev->proto_ver);
1910 1910
1911 1911 if (cmp_cycle != skdev->skcomp_cycle) {
1912 1912 Dcmn_err(CE_NOTE, "%s:end of completions", skdev->name);
1913 1913
1914 1914 WAITQ_UNLOCK(skdev);
1915 1915 break;
1916 1916 }
1917 1917
1918 1918
1919 1919 skdev->n_req++;
1920 1920
1921 1921 /*
1922 1922 * Update the completion queue head index and possibly
1923 1923 * the completion cycle count.
1924 1924 */
1925 1925 skdev->skcomp_ix++;
1926 1926 if (skdev->skcomp_ix >= SKD_N_COMPLETION_ENTRY) {
1927 1927 skdev->skcomp_ix = 0;
1928 1928 skdev->skcomp_cycle++; /* 8-bit wrap-around */
1929 1929 }
1930 1930
1931 1931
1932 1932 /*
1933 1933 * The command context is a unique 32-bit ID. The low order
1934 1934 * bits help locate the request. The request is usually a
1935 1935 * r/w request (see skd_start() above) or a special request.
1936 1936 */
1937 1937 req_id = cmp_cntxt;
1938 1938 req_slot = req_id & SKD_ID_SLOT_AND_TABLE_MASK;
1939 1939
1940 1940 Dcmn_err(CE_NOTE,
1941 1941 "<<<< completion_posted 1: req_id=%x req_slot=%x",
1942 1942 req_id, req_slot);
1943 1943
1944 1944 /* Is this other than a r/w request? */
1945 1945 if (req_slot >= skdev->num_req_context) {
1946 1946 /*
1947 1947 * This is not a completion for a r/w request.
1948 1948 */
1949 1949 skd_complete_other(skdev, skcmp, skerr);
1950 1950 WAITQ_UNLOCK(skdev);
1951 1951 continue;
1952 1952 }
1953 1953
1954 1954 skreq = &skdev->skreq_table[req_slot];
1955 1955
1956 1956 /*
1957 1957 * Make sure the request ID for the slot matches.
1958 1958 */
1959 1959 ASSERT(skreq->id == req_id);
1960 1960
1961 1961 if (SKD_REQ_STATE_ABORTED == skreq->state) {
1962 1962 Dcmn_err(CE_NOTE, "reclaim req %p id=%04x\n",
1963 1963 (void *)skreq, skreq->id);
1964 1964 /*
1965 1965 * a previously timed out command can
1966 1966 * now be cleaned up
1967 1967 */
1968 1968 msg_slot = skreq->fitmsg_id & SKD_ID_SLOT_MASK;
1969 1969 ASSERT(msg_slot < skdev->num_fitmsg_context);
1970 1970 skmsg = &skdev->skmsg_table[msg_slot];
1971 1971 if (skmsg->id == skreq->fitmsg_id) {
1972 1972 ASSERT(skmsg->outstanding > 0);
1973 1973 skmsg->outstanding--;
1974 1974 if (skmsg->outstanding == 0) {
1975 1975 ASSERT(SKD_MSG_STATE_BUSY ==
1976 1976 skmsg->state);
1977 1977 skmsg->state = SKD_MSG_STATE_IDLE;
1978 1978 skmsg->id += SKD_ID_INCR;
1979 1979 skmsg->next = skdev->skmsg_free_list;
1980 1980 skdev->skmsg_free_list = skmsg;
1981 1981 }
1982 1982 }
1983 1983 /*
1984 1984 * Reclaim the skd_request_context
1985 1985 */
1986 1986 skreq->state = SKD_REQ_STATE_IDLE;
1987 1987 skreq->id += SKD_ID_INCR;
1988 1988 skreq->next = skdev->skreq_free_list;
1989 1989 skdev->skreq_free_list = skreq;
1990 1990 WAITQ_UNLOCK(skdev);
1991 1991 continue;
1992 1992 }
1993 1993
1994 1994 skreq->completion.status = cmp_status;
1995 1995
1996 1996 pbuf = skreq->pbuf;
1997 1997 ASSERT(pbuf != NULL);
1998 1998
1999 1999 Dcmn_err(CE_NOTE, "<<<< completion_posted 2: pbuf=%p "
2000 2000 "req_id=%x req_slot=%x", (void *)pbuf, req_id, req_slot);
2001 2001 if (cmp_status && skdev->disks_initialized) {
2002 2002 cmn_err(CE_WARN, "!%s: "
2003 2003 "I/O err: pbuf=%p blkno=%lld (%llx) nbklks=%ld ",
2004 2004 skdev->name, (void *)pbuf, pbuf->x_xfer->x_blkno,
2005 2005 pbuf->x_xfer->x_blkno, pbuf->x_xfer->x_nblks);
2006 2006 }
2007 2007
2008 2008 ASSERT(skdev->active_cmds);
2009 2009 atomic_dec_64(&skdev->active_cmds);
2010 2010
2011 2011 if (SAM_STAT_GOOD == cmp_status) {
2012 2012 /* Release DMA resources for the request. */
2013 2013 if (pbuf->x_xfer->x_nblks != 0)
2014 2014 skd_blkdev_postop_sg_list(skdev, skreq);
2015 2015 WAITQ_UNLOCK(skdev);
2016 2016 skd_end_request(skdev, skreq, 0);
2017 2017 WAITQ_LOCK(skdev);
2018 2018 } else {
2019 2019 switch (skd_check_status(skdev, cmp_status, skerr)) {
2020 2020 case SKD_CHECK_STATUS_REPORT_GOOD:
2021 2021 case SKD_CHECK_STATUS_REPORT_SMART_ALERT:
2022 2022 WAITQ_UNLOCK(skdev);
2023 2023 skd_end_request(skdev, skreq, 0);
2024 2024 WAITQ_LOCK(skdev);
2025 2025 break;
2026 2026
2027 2027 case SKD_CHECK_STATUS_BUSY_IMMINENT:
2028 2028 skd_log_skreq(skdev, skreq, "retry(busy)");
2029 2029 skd_queue(skdev, pbuf);
2030 2030 skdev->state = SKD_DRVR_STATE_BUSY_IMMINENT;
2031 2031 skdev->timer_countdown = SKD_TIMER_MINUTES(20);
2032 2032
2033 2033 (void) skd_quiesce_dev(skdev);
2034 2034 break;
2035 2035
2036 2036 /* FALLTHRU */
2037 2037 case SKD_CHECK_STATUS_REPORT_ERROR:
2038 2038 /* fall thru to report error */
2039 2039 default:
2040 2040 /*
2041 2041 * Save the entire completion
2042 2042 * and error entries for
2043 2043 * later error interpretation.
2044 2044 */
2045 2045 skreq->completion = *skcmp;
2046 2046 skreq->err_info = *skerr;
2047 2047 WAITQ_UNLOCK(skdev);
2048 2048 skd_end_request(skdev, skreq, -EIO);
2049 2049 WAITQ_LOCK(skdev);
2050 2050 break;
2051 2051 }
2052 2052 }
2053 2053
2054 2054 /*
2055 2055 * Reclaim the FIT msg buffer if this is
2056 2056 * the first of the requests it carried to
2057 2057 * be completed. The FIT msg buffer used to
2058 2058 * send this request cannot be reused until
2059 2059 * we are sure the s1120 card has copied
2060 2060 * it to its memory. The FIT msg might have
2061 2061 * contained several requests. As soon as
2062 2062 * any of them are completed we know that
2063 2063 * the entire FIT msg was transferred.
2064 2064 * Only the first completed request will
2065 2065 * match the FIT msg buffer id. The FIT
2066 2066 * msg buffer id is immediately updated.
2067 2067 * When subsequent requests complete the FIT
2068 2068 * msg buffer id won't match, so we know
2069 2069 * quite cheaply that it is already done.
2070 2070 */
2071 2071 msg_slot = skreq->fitmsg_id & SKD_ID_SLOT_MASK;
2072 2072
2073 2073 ASSERT(msg_slot < skdev->num_fitmsg_context);
2074 2074 skmsg = &skdev->skmsg_table[msg_slot];
2075 2075 if (skmsg->id == skreq->fitmsg_id) {
2076 2076 ASSERT(SKD_MSG_STATE_BUSY == skmsg->state);
2077 2077 skmsg->state = SKD_MSG_STATE_IDLE;
2078 2078 skmsg->id += SKD_ID_INCR;
2079 2079 skmsg->next = skdev->skmsg_free_list;
2080 2080 skdev->skmsg_free_list = skmsg;
2081 2081 }
2082 2082
2083 2083 /*
2084 2084 * Decrease the number of active requests.
2085 2085 * This also decrements the count in the
2086 2086 * timeout slot.
2087 2087 */
2088 2088 timo_slot = skreq->timeout_stamp & SKD_TIMEOUT_SLOT_MASK;
2089 2089 ASSERT(skdev->timeout_slot[timo_slot] > 0);
2090 2090 ASSERT(skdev->queue_depth_busy > 0);
2091 2091
2092 2092 atomic_dec_32(&skdev->timeout_slot[timo_slot]);
2093 2093 atomic_dec_32(&skdev->queue_depth_busy);
2094 2094
2095 2095 /*
2096 2096 * Reclaim the skd_request_context
2097 2097 */
2098 2098 skreq->state = SKD_REQ_STATE_IDLE;
2099 2099 skreq->id += SKD_ID_INCR;
2100 2100 skreq->next = skdev->skreq_free_list;
2101 2101 skdev->skreq_free_list = skreq;
2102 2102
2103 2103 WAITQ_UNLOCK(skdev);
2104 2104
2105 2105 /*
2106 2106 * make sure the lock is held by caller.
2107 2107 */
2108 2108 if ((skdev->state == SKD_DRVR_STATE_PAUSING) &&
2109 2109 (0 == skdev->queue_depth_busy)) {
2110 2110 skdev->state = SKD_DRVR_STATE_PAUSED;
2111 2111 cv_signal(&skdev->cv_waitq);
2112 2112 }
2113 2113 } /* for(;;) */
2114 2114 }
2115 2115
2116 2116 /*
2117 2117 *
2118 2118 * Name: skd_complete_other, handle the completion of a
2119 2119 * non-r/w request.
2120 2120 *
2121 2121 * Inputs: skdev - device state structure.
2122 2122 * skcomp - FIT completion structure.
2123 2123 * skerr - error structure.
2124 2124 *
2125 2125 * Returns: Nothing.
2126 2126 *
2127 2127 */
2128 2128 static void
2129 2129 skd_complete_other(struct skd_device *skdev,
2130 2130 volatile struct fit_completion_entry_v1 *skcomp,
2131 2131 volatile struct fit_comp_error_info *skerr)
2132 2132 {
2133 2133 uint32_t req_id = 0;
2134 2134 uint32_t req_table;
2135 2135 uint32_t req_slot;
2136 2136 struct skd_special_context *skspcl;
2137 2137
2138 2138 req_id = skcomp->tag;
2139 2139 req_table = req_id & SKD_ID_TABLE_MASK;
2140 2140 req_slot = req_id & SKD_ID_SLOT_MASK;
2141 2141
2142 2142 Dcmn_err(CE_NOTE, "complete_other: table=0x%x id=0x%x slot=%d",
2143 2143 req_table, req_id, req_slot);
2144 2144
2145 2145 /*
2146 2146 * Based on the request id, determine how to dispatch this completion.
2147 2147 * This swich/case is finding the good cases and forwarding the
2148 2148 * completion entry. Errors are reported below the switch.
2149 2149 */
2150 2150 ASSERT(req_table == SKD_ID_INTERNAL);
2151 2151 ASSERT(req_slot == 0);
2152 2152
2153 2153 skspcl = &skdev->internal_skspcl;
2154 2154 ASSERT(skspcl->req.id == req_id);
2155 2155 ASSERT(skspcl->req.state == SKD_REQ_STATE_BUSY);
2156 2156
2157 2157 Dcmn_err(CE_NOTE, "<<<<== complete_other: ID_INTERNAL");
2158 2158 skd_complete_internal(skdev, skcomp, skerr, skspcl);
2159 2159 }
2160 2160
2161 2161 /*
2162 2162 *
2163 2163 * Name: skd_reset_skcomp, does what it says, resetting completion
2164 2164 * tables.
2165 2165 *
2166 2166 * Inputs: skdev - device state structure.
2167 2167 *
2168 2168 * Returns: Nothing.
2169 2169 *
2170 2170 */
2171 2171 static void
2172 2172 skd_reset_skcomp(struct skd_device *skdev)
2173 2173 {
2174 2174 uint32_t nbytes;
2175 2175
2176 2176 nbytes = sizeof (struct fit_completion_entry_v1) *
2177 2177 SKD_N_COMPLETION_ENTRY;
2178 2178 nbytes += sizeof (struct fit_comp_error_info) * SKD_N_COMPLETION_ENTRY;
2179 2179
2180 2180 if (skdev->skcomp_table)
2181 2181 bzero(skdev->skcomp_table, nbytes);
2182 2182
2183 2183 skdev->skcomp_ix = 0;
2184 2184 skdev->skcomp_cycle = 1;
2185 2185 }
2186 2186
2187 2187
2188 2188
2189 2189 /*
2190 2190 * INTERRUPTS
2191 2191 */
2192 2192
2193 2193 /*
2194 2194 *
2195 2195 * Name: skd_isr_aif, handles the device interrupts.
2196 2196 *
2197 2197 * Inputs: arg - skdev device state structure.
2198 2198 * intvec - not referenced
2199 2199 *
2200 2200 * Returns: DDI_INTR_CLAIMED if interrupt is handled otherwise
2201 2201 * return DDI_INTR_UNCLAIMED.
2202 2202 *
2203 2203 */
2204 2204 /* ARGSUSED */ /* Upstream common source with other platforms. */
2205 2205 static uint_t
2206 2206 skd_isr_aif(caddr_t arg, caddr_t intvec)
2207 2207 {
2208 2208 uint32_t intstat;
2209 2209 uint32_t ack;
2210 2210 int rc = DDI_INTR_UNCLAIMED;
2211 2211 struct skd_device *skdev;
2212 2212
2213 2213 skdev = (skd_device_t *)(uintptr_t)arg;
2214 2214
2215 2215 ASSERT(skdev != NULL);
2216 2216
2217 2217 skdev->intr_cntr++;
2218 2218
2219 2219 Dcmn_err(CE_NOTE, "skd_isr_aif: intr=%" PRId64 "\n", skdev->intr_cntr);
2220 2220
2221 2221 for (;;) {
2222 2222
2223 2223 ASSERT(!WAITQ_LOCK_HELD(skdev));
2224 2224 INTR_LOCK(skdev);
2225 2225
2226 2226 intstat = SKD_READL(skdev, FIT_INT_STATUS_HOST);
2227 2227
2228 2228 ack = FIT_INT_DEF_MASK;
2229 2229 ack &= intstat;
2230 2230
2231 2231 Dcmn_err(CE_NOTE, "intstat=0x%x ack=0x%x", intstat, ack);
2232 2232
2233 2233 /*
2234 2234 * As long as there is an int pending on device, keep
2235 2235 * running loop. When none, get out, but if we've never
2236 2236 * done any processing, call completion handler?
2237 2237 */
2238 2238 if (ack == 0) {
2239 2239 /*
2240 2240 * No interrupts on device, but run the completion
2241 2241 * processor anyway?
2242 2242 */
2243 2243 if (rc == DDI_INTR_UNCLAIMED &&
2244 2244 skdev->state == SKD_DRVR_STATE_ONLINE) {
2245 2245 Dcmn_err(CE_NOTE,
2246 2246 "1: Want isr_comp_posted call");
2247 2247 skd_isr_completion_posted(skdev);
2248 2248 }
2249 2249 INTR_UNLOCK(skdev);
2250 2250
2251 2251 break;
2252 2252 }
2253 2253 rc = DDI_INTR_CLAIMED;
2254 2254
2255 2255 SKD_WRITEL(skdev, ack, FIT_INT_STATUS_HOST);
2256 2256
2257 2257 if ((skdev->state != SKD_DRVR_STATE_LOAD) &&
2258 2258 (skdev->state != SKD_DRVR_STATE_STOPPING)) {
2259 2259 if (intstat & FIT_ISH_COMPLETION_POSTED) {
2260 2260 Dcmn_err(CE_NOTE,
2261 2261 "2: Want isr_comp_posted call");
2262 2262 skd_isr_completion_posted(skdev);
2263 2263 }
2264 2264
2265 2265 if (intstat & FIT_ISH_FW_STATE_CHANGE) {
2266 2266 Dcmn_err(CE_NOTE, "isr: fwstate change");
2267 2267
2268 2268 skd_isr_fwstate(skdev);
2269 2269 if (skdev->state == SKD_DRVR_STATE_FAULT ||
2270 2270 skdev->state ==
2271 2271 SKD_DRVR_STATE_DISAPPEARED) {
2272 2272 INTR_UNLOCK(skdev);
2273 2273
2274 2274 return (rc);
2275 2275 }
2276 2276 }
2277 2277
2278 2278 if (intstat & FIT_ISH_MSG_FROM_DEV) {
2279 2279 Dcmn_err(CE_NOTE, "isr: msg_from_dev change");
2280 2280 skd_isr_msg_from_dev(skdev);
2281 2281 }
2282 2282 }
2283 2283
2284 2284 INTR_UNLOCK(skdev);
2285 2285 }
2286 2286
2287 2287 if (!SIMPLEQ_EMPTY(&skdev->waitqueue))
2288 2288 skd_start(skdev);
2289 2289
2290 2290 return (rc);
2291 2291 }
2292 2292
2293 2293 /*
2294 2294 *
2295 2295 * Name: skd_drive_fault, set the drive state to DRV_STATE_FAULT.
2296 2296 *
2297 2297 * Inputs: skdev - device state structure.
2298 2298 *
2299 2299 * Returns: Nothing.
2300 2300 *
2301 2301 */
2302 2302 static void
2303 2303 skd_drive_fault(struct skd_device *skdev)
2304 2304 {
2305 2305 skdev->state = SKD_DRVR_STATE_FAULT;
2306 2306 cmn_err(CE_WARN, "!(%s): Drive FAULT\n",
2307 2307 skd_name(skdev));
2308 2308 }
2309 2309
2310 2310 /*
2311 2311 *
2312 2312 * Name: skd_drive_disappeared, set the drive state to DISAPPEARED..
2313 2313 *
2314 2314 * Inputs: skdev - device state structure.
2315 2315 *
2316 2316 * Returns: Nothing.
2317 2317 *
2318 2318 */
2319 2319 static void
2320 2320 skd_drive_disappeared(struct skd_device *skdev)
2321 2321 {
2322 2322 skdev->state = SKD_DRVR_STATE_DISAPPEARED;
2323 2323 cmn_err(CE_WARN, "!(%s): Drive DISAPPEARED\n",
2324 2324 skd_name(skdev));
2325 2325 }
2326 2326
2327 2327 /*
2328 2328 *
2329 2329 * Name: skd_isr_fwstate, handles the various device states.
2330 2330 *
2331 2331 * Inputs: skdev - device state structure.
2332 2332 *
2333 2333 * Returns: Nothing.
2334 2334 *
2335 2335 */
2336 2336 static void
2337 2337 skd_isr_fwstate(struct skd_device *skdev)
2338 2338 {
2339 2339 uint32_t sense;
2340 2340 uint32_t state;
2341 2341 int prev_driver_state;
2342 2342 uint32_t mtd;
2343 2343
2344 2344 prev_driver_state = skdev->state;
2345 2345
2346 2346 sense = SKD_READL(skdev, FIT_STATUS);
2347 2347 state = sense & FIT_SR_DRIVE_STATE_MASK;
2348 2348
2349 2349 Dcmn_err(CE_NOTE, "s1120 state %s(%d)=>%s(%d)",
2350 2350 skd_drive_state_to_str(skdev->drive_state), skdev->drive_state,
2351 2351 skd_drive_state_to_str(state), state);
2352 2352
2353 2353 skdev->drive_state = state;
2354 2354
2355 2355 switch (skdev->drive_state) {
2356 2356 case FIT_SR_DRIVE_INIT:
2357 2357 if (skdev->state == SKD_DRVR_STATE_PROTOCOL_MISMATCH) {
2358 2358 skd_disable_interrupts(skdev);
2359 2359 break;
2360 2360 }
2361 2361 if (skdev->state == SKD_DRVR_STATE_RESTARTING) {
2362 2362 skd_recover_requests(skdev);
2363 2363 }
2364 2364 if (skdev->state == SKD_DRVR_STATE_WAIT_BOOT) {
2365 2365 skdev->timer_countdown =
2366 2366 SKD_TIMER_SECONDS(SKD_STARTING_TO);
2367 2367 skdev->state = SKD_DRVR_STATE_STARTING;
2368 2368 skd_soft_reset(skdev);
2369 2369 break;
2370 2370 }
2371 2371 mtd = FIT_MXD_CONS(FIT_MTD_FITFW_INIT, 0, 0);
2372 2372 SKD_WRITEL(skdev, mtd, FIT_MSG_TO_DEVICE);
2373 2373 skdev->last_mtd = mtd;
2374 2374 break;
2375 2375
2376 2376 case FIT_SR_DRIVE_ONLINE:
2377 2377 skdev->queue_depth_limit = skdev->soft_queue_depth_limit;
2378 2378 if (skdev->queue_depth_limit > skdev->hard_queue_depth_limit) {
2379 2379 skdev->queue_depth_limit =
2380 2380 skdev->hard_queue_depth_limit;
2381 2381 }
2382 2382
2383 2383 skdev->queue_depth_lowat = skdev->queue_depth_limit * 2 / 3 + 1;
2384 2384 if (skdev->queue_depth_lowat < 1)
2385 2385 skdev->queue_depth_lowat = 1;
2386 2386 Dcmn_err(CE_NOTE,
2387 2387 "%s queue depth limit=%d hard=%d soft=%d lowat=%d",
2388 2388 DRV_NAME,
2389 2389 skdev->queue_depth_limit,
2390 2390 skdev->hard_queue_depth_limit,
2391 2391 skdev->soft_queue_depth_limit,
2392 2392 skdev->queue_depth_lowat);
2393 2393
2394 2394 skd_refresh_device_data(skdev);
2395 2395 break;
2396 2396 case FIT_SR_DRIVE_BUSY:
2397 2397 skdev->state = SKD_DRVR_STATE_BUSY;
2398 2398 skdev->timer_countdown = SKD_TIMER_MINUTES(20);
2399 2399 (void) skd_quiesce_dev(skdev);
2400 2400 break;
2401 2401 case FIT_SR_DRIVE_BUSY_SANITIZE:
2402 2402 skdev->state = SKD_DRVR_STATE_BUSY_SANITIZE;
2403 2403 skd_start(skdev);
2404 2404 break;
2405 2405 case FIT_SR_DRIVE_BUSY_ERASE:
2406 2406 skdev->state = SKD_DRVR_STATE_BUSY_ERASE;
2407 2407 skdev->timer_countdown = SKD_TIMER_MINUTES(20);
2408 2408 break;
2409 2409 case FIT_SR_DRIVE_OFFLINE:
2410 2410 skdev->state = SKD_DRVR_STATE_IDLE;
2411 2411 break;
2412 2412 case FIT_SR_DRIVE_SOFT_RESET:
2413 2413 skdev->state = SKD_DRVR_STATE_RESTARTING;
2414 2414
2415 2415 switch (skdev->state) {
2416 2416 case SKD_DRVR_STATE_STARTING:
2417 2417 case SKD_DRVR_STATE_RESTARTING:
2418 2418 break;
2419 2419 default:
2420 2420 skdev->state = SKD_DRVR_STATE_RESTARTING;
2421 2421 break;
2422 2422 }
2423 2423 break;
2424 2424 case FIT_SR_DRIVE_FW_BOOTING:
2425 2425 Dcmn_err(CE_NOTE,
2426 2426 "ISR FIT_SR_DRIVE_FW_BOOTING %s", skdev->name);
2427 2427 skdev->state = SKD_DRVR_STATE_WAIT_BOOT;
2428 2428 skdev->timer_countdown = SKD_TIMER_SECONDS(SKD_WAIT_BOOT_TO);
2429 2429 break;
2430 2430
2431 2431 case FIT_SR_DRIVE_DEGRADED:
2432 2432 case FIT_SR_PCIE_LINK_DOWN:
2433 2433 case FIT_SR_DRIVE_NEED_FW_DOWNLOAD:
2434 2434 break;
2435 2435
2436 2436 case FIT_SR_DRIVE_FAULT:
2437 2437 skd_drive_fault(skdev);
2438 2438 skd_recover_requests(skdev);
2439 2439 skd_start(skdev);
2440 2440 break;
2441 2441
2442 2442 case 0xFF:
2443 2443 skd_drive_disappeared(skdev);
2444 2444 skd_recover_requests(skdev);
2445 2445 skd_start(skdev);
2446 2446 break;
2447 2447 default:
2448 2448 /*
2449 2449 * Uknown FW State. Wait for a state we recognize.
2450 2450 */
2451 2451 break;
2452 2452 }
2453 2453
2454 2454 Dcmn_err(CE_NOTE, "Driver state %s(%d)=>%s(%d)",
2455 2455 skd_skdev_state_to_str(prev_driver_state), prev_driver_state,
2456 2456 skd_skdev_state_to_str(skdev->state), skdev->state);
2457 2457 }
2458 2458
2459 2459 /*
2460 2460 *
2461 2461 * Name: skd_recover_requests, attempts to recover requests.
2462 2462 *
2463 2463 * Inputs: skdev - device state structure.
2464 2464 *
2465 2465 * Returns: Nothing.
2466 2466 *
2467 2467 */
2468 2468 static void
2469 2469 skd_recover_requests(struct skd_device *skdev)
2470 2470 {
2471 2471 int i;
2472 2472
2473 2473 ASSERT(INTR_LOCK_HELD(skdev));
2474 2474
2475 2475 for (i = 0; i < skdev->num_req_context; i++) {
2476 2476 struct skd_request_context *skreq = &skdev->skreq_table[i];
2477 2477
2478 2478 if (skreq->state == SKD_REQ_STATE_BUSY) {
2479 2479 skd_log_skreq(skdev, skreq, "requeue");
2480 2480
2481 2481 ASSERT(0 != (skreq->id & SKD_ID_INCR));
2482 2482 ASSERT(skreq->pbuf != NULL);
2483 2483 /* Release DMA resources for the request. */
2484 2484 skd_blkdev_postop_sg_list(skdev, skreq);
2485 2485
2486 2486 skd_end_request(skdev, skreq, EAGAIN);
2487 2487 skreq->pbuf = NULL;
2488 2488 skreq->state = SKD_REQ_STATE_IDLE;
2489 2489 skreq->id += SKD_ID_INCR;
2490 2490 }
2491 2491 if (i > 0) {
2492 2492 skreq[-1].next = skreq;
2493 2493 }
2494 2494 skreq->next = NULL;
2495 2495 }
2496 2496
2497 2497 WAITQ_LOCK(skdev);
2498 2498 skdev->skreq_free_list = skdev->skreq_table;
2499 2499 WAITQ_UNLOCK(skdev);
2500 2500
2501 2501 for (i = 0; i < skdev->num_fitmsg_context; i++) {
2502 2502 struct skd_fitmsg_context *skmsg = &skdev->skmsg_table[i];
2503 2503
2504 2504 if (skmsg->state == SKD_MSG_STATE_BUSY) {
2505 2505 skd_log_skmsg(skdev, skmsg, "salvaged");
2506 2506 ASSERT((skmsg->id & SKD_ID_INCR) != 0);
2507 2507 skmsg->state = SKD_MSG_STATE_IDLE;
2508 2508 skmsg->id &= ~SKD_ID_INCR;
2509 2509 }
2510 2510 if (i > 0) {
2511 2511 skmsg[-1].next = skmsg;
2512 2512 }
2513 2513 skmsg->next = NULL;
2514 2514 }
2515 2515 WAITQ_LOCK(skdev);
2516 2516 skdev->skmsg_free_list = skdev->skmsg_table;
2517 2517 WAITQ_UNLOCK(skdev);
2518 2518
2519 2519 for (i = 0; i < SKD_N_TIMEOUT_SLOT; i++) {
2520 2520 skdev->timeout_slot[i] = 0;
2521 2521 }
2522 2522 skdev->queue_depth_busy = 0;
2523 2523 }
2524 2524
2525 2525 /*
2526 2526 *
2527 2527 * Name: skd_isr_msg_from_dev, handles a message from the device.
2528 2528 *
2529 2529 * Inputs: skdev - device state structure.
2530 2530 *
2531 2531 * Returns: Nothing.
2532 2532 *
2533 2533 */
2534 2534 static void
2535 2535 skd_isr_msg_from_dev(struct skd_device *skdev)
2536 2536 {
2537 2537 uint32_t mfd;
2538 2538 uint32_t mtd;
2539 2539
2540 2540 Dcmn_err(CE_NOTE, "skd_isr_msg_from_dev:");
2541 2541
2542 2542 mfd = SKD_READL(skdev, FIT_MSG_FROM_DEVICE);
2543 2543
2544 2544 Dcmn_err(CE_NOTE, "mfd=0x%x last_mtd=0x%x\n", mfd, skdev->last_mtd);
2545 2545
2546 2546 /*
2547 2547 * ignore any mtd that is an ack for something we didn't send
2548 2548 */
2549 2549 if (FIT_MXD_TYPE(mfd) != FIT_MXD_TYPE(skdev->last_mtd)) {
2550 2550 return;
2551 2551 }
2552 2552
2553 2553 switch (FIT_MXD_TYPE(mfd)) {
2554 2554 case FIT_MTD_FITFW_INIT:
2555 2555 skdev->proto_ver = FIT_PROTOCOL_MAJOR_VER(mfd);
2556 2556
2557 2557 if (skdev->proto_ver != FIT_PROTOCOL_VERSION_1) {
2558 2558 cmn_err(CE_WARN, "!(%s): protocol mismatch\n",
2559 2559 skdev->name);
2560 2560 cmn_err(CE_WARN, "!(%s): got=%d support=%d\n",
2561 2561 skdev->name, skdev->proto_ver,
2562 2562 FIT_PROTOCOL_VERSION_1);
2563 2563 cmn_err(CE_WARN, "!(%s): please upgrade driver\n",
2564 2564 skdev->name);
2565 2565 skdev->state = SKD_DRVR_STATE_PROTOCOL_MISMATCH;
2566 2566 skd_soft_reset(skdev);
2567 2567 break;
2568 2568 }
2569 2569 mtd = FIT_MXD_CONS(FIT_MTD_GET_CMDQ_DEPTH, 0, 0);
2570 2570 SKD_WRITEL(skdev, mtd, FIT_MSG_TO_DEVICE);
2571 2571 skdev->last_mtd = mtd;
2572 2572 break;
2573 2573
2574 2574 case FIT_MTD_GET_CMDQ_DEPTH:
2575 2575 skdev->hard_queue_depth_limit = FIT_MXD_DATA(mfd);
2576 2576 mtd = FIT_MXD_CONS(FIT_MTD_SET_COMPQ_DEPTH, 0,
2577 2577 SKD_N_COMPLETION_ENTRY);
2578 2578 SKD_WRITEL(skdev, mtd, FIT_MSG_TO_DEVICE);
2579 2579 skdev->last_mtd = mtd;
2580 2580 break;
2581 2581
2582 2582 case FIT_MTD_SET_COMPQ_DEPTH:
2583 2583 SKD_WRITEQ(skdev, skdev->cq_dma_address.cookies->dmac_laddress,
2584 2584 FIT_MSG_TO_DEVICE_ARG);
2585 2585 mtd = FIT_MXD_CONS(FIT_MTD_SET_COMPQ_ADDR, 0, 0);
2586 2586 SKD_WRITEL(skdev, mtd, FIT_MSG_TO_DEVICE);
2587 2587 skdev->last_mtd = mtd;
2588 2588 break;
2589 2589
2590 2590 case FIT_MTD_SET_COMPQ_ADDR:
2591 2591 skd_reset_skcomp(skdev);
2592 2592 mtd = FIT_MXD_CONS(FIT_MTD_ARM_QUEUE, 0, 0);
2593 2593 SKD_WRITEL(skdev, mtd, FIT_MSG_TO_DEVICE);
2594 2594 skdev->last_mtd = mtd;
2595 2595 break;
2596 2596
2597 2597 case FIT_MTD_ARM_QUEUE:
2598 2598 skdev->last_mtd = 0;
2599 2599 /*
2600 2600 * State should be, or soon will be, FIT_SR_DRIVE_ONLINE.
2601 2601 */
2602 2602 break;
2603 2603
2604 2604 default:
2605 2605 break;
2606 2606 }
2607 2607 }
2608 2608
2609 2609
2610 2610 /*
2611 2611 *
2612 2612 * Name: skd_disable_interrupts, issues command to disable
2613 2613 * device interrupts.
2614 2614 *
2615 2615 * Inputs: skdev - device state structure.
2616 2616 *
2617 2617 * Returns: Nothing.
2618 2618 *
2619 2619 */
2620 2620 static void
2621 2621 skd_disable_interrupts(struct skd_device *skdev)
2622 2622 {
2623 2623 uint32_t sense;
2624 2624
2625 2625 Dcmn_err(CE_NOTE, "skd_disable_interrupts:");
2626 2626
2627 2627 sense = SKD_READL(skdev, FIT_CONTROL);
2628 2628 sense &= ~FIT_CR_ENABLE_INTERRUPTS;
2629 2629 SKD_WRITEL(skdev, sense, FIT_CONTROL);
2630 2630
2631 2631 Dcmn_err(CE_NOTE, "sense 0x%x", sense);
2632 2632
2633 2633 /*
2634 2634 * Note that the 1s is written. A 1-bit means
2635 2635 * disable, a 0 means enable.
2636 2636 */
2637 2637 SKD_WRITEL(skdev, ~0, FIT_INT_MASK_HOST);
2638 2638 }
2639 2639
2640 2640 /*
2641 2641 *
2642 2642 * Name: skd_enable_interrupts, issues command to enable
2643 2643 * device interrupts.
2644 2644 *
2645 2645 * Inputs: skdev - device state structure.
2646 2646 *
2647 2647 * Returns: Nothing.
2648 2648 *
2649 2649 */
2650 2650 static void
2651 2651 skd_enable_interrupts(struct skd_device *skdev)
2652 2652 {
2653 2653 uint32_t val;
2654 2654
2655 2655 Dcmn_err(CE_NOTE, "skd_enable_interrupts:");
2656 2656
2657 2657 /* unmask interrupts first */
2658 2658 val = FIT_ISH_FW_STATE_CHANGE +
2659 2659 FIT_ISH_COMPLETION_POSTED +
2660 2660 FIT_ISH_MSG_FROM_DEV;
2661 2661
2662 2662 /*
2663 2663 * Note that the compliment of mask is written. A 1-bit means
2664 2664 * disable, a 0 means enable.
2665 2665 */
2666 2666 SKD_WRITEL(skdev, ~val, FIT_INT_MASK_HOST);
2667 2667
2668 2668 Dcmn_err(CE_NOTE, "interrupt mask=0x%x", ~val);
2669 2669
2670 2670 val = SKD_READL(skdev, FIT_CONTROL);
2671 2671 val |= FIT_CR_ENABLE_INTERRUPTS;
2672 2672
2673 2673 Dcmn_err(CE_NOTE, "control=0x%x", val);
2674 2674
2675 2675 SKD_WRITEL(skdev, val, FIT_CONTROL);
2676 2676 }
2677 2677
2678 2678 /*
2679 2679 *
2680 2680 * Name: skd_soft_reset, issues a soft reset to the hardware.
2681 2681 *
2682 2682 * Inputs: skdev - device state structure.
2683 2683 *
2684 2684 * Returns: Nothing.
2685 2685 *
2686 2686 */
2687 2687 static void
2688 2688 skd_soft_reset(struct skd_device *skdev)
2689 2689 {
2690 2690 uint32_t val;
2691 2691
2692 2692 Dcmn_err(CE_NOTE, "skd_soft_reset:");
2693 2693
2694 2694 val = SKD_READL(skdev, FIT_CONTROL);
2695 2695 val |= (FIT_CR_SOFT_RESET);
2696 2696
2697 2697 Dcmn_err(CE_NOTE, "soft_reset: control=0x%x", val);
2698 2698
2699 2699 SKD_WRITEL(skdev, val, FIT_CONTROL);
2700 2700 }
2701 2701
2702 2702 /*
2703 2703 *
2704 2704 * Name: skd_start_device, gets the device going.
2705 2705 *
2706 2706 * Inputs: skdev - device state structure.
2707 2707 *
2708 2708 * Returns: Nothing.
2709 2709 *
2710 2710 */
2711 2711 static void
2712 2712 skd_start_device(struct skd_device *skdev)
2713 2713 {
2714 2714 uint32_t state;
2715 2715 int delay_action = 0;
2716 2716
2717 2717 Dcmn_err(CE_NOTE, "skd_start_device:");
2718 2718
2719 2719 /* ack all ghost interrupts */
2720 2720 SKD_WRITEL(skdev, FIT_INT_DEF_MASK, FIT_INT_STATUS_HOST);
2721 2721
2722 2722 state = SKD_READL(skdev, FIT_STATUS);
2723 2723
2724 2724 Dcmn_err(CE_NOTE, "initial status=0x%x", state);
2725 2725
2726 2726 state &= FIT_SR_DRIVE_STATE_MASK;
2727 2727 skdev->drive_state = state;
2728 2728 skdev->last_mtd = 0;
2729 2729
2730 2730 skdev->state = SKD_DRVR_STATE_STARTING;
2731 2731 skdev->timer_countdown = SKD_TIMER_SECONDS(SKD_STARTING_TO);
2732 2732
2733 2733 skd_enable_interrupts(skdev);
2734 2734
2735 2735 switch (skdev->drive_state) {
2736 2736 case FIT_SR_DRIVE_OFFLINE:
2737 2737 Dcmn_err(CE_NOTE, "(%s): Drive offline...",
2738 2738 skd_name(skdev));
2739 2739 break;
2740 2740
2741 2741 case FIT_SR_DRIVE_FW_BOOTING:
2742 2742 Dcmn_err(CE_NOTE, "FIT_SR_DRIVE_FW_BOOTING %s\n", skdev->name);
2743 2743 skdev->state = SKD_DRVR_STATE_WAIT_BOOT;
2744 2744 skdev->timer_countdown = SKD_TIMER_SECONDS(SKD_WAIT_BOOT_TO);
2745 2745 break;
2746 2746
2747 2747 case FIT_SR_DRIVE_BUSY_SANITIZE:
2748 2748 Dcmn_err(CE_NOTE, "(%s): Start: BUSY_SANITIZE\n",
2749 2749 skd_name(skdev));
2750 2750 skdev->state = SKD_DRVR_STATE_BUSY_SANITIZE;
2751 2751 skdev->timer_countdown = SKD_TIMER_SECONDS(60);
2752 2752 break;
2753 2753
2754 2754 case FIT_SR_DRIVE_BUSY_ERASE:
2755 2755 Dcmn_err(CE_NOTE, "(%s): Start: BUSY_ERASE\n",
2756 2756 skd_name(skdev));
2757 2757 skdev->state = SKD_DRVR_STATE_BUSY_ERASE;
2758 2758 skdev->timer_countdown = SKD_TIMER_SECONDS(60);
2759 2759 break;
2760 2760
2761 2761 case FIT_SR_DRIVE_INIT:
2762 2762 case FIT_SR_DRIVE_ONLINE:
2763 2763 skd_soft_reset(skdev);
2764 2764
2765 2765 break;
2766 2766
2767 2767 case FIT_SR_DRIVE_BUSY:
2768 2768 Dcmn_err(CE_NOTE, "(%s): Drive Busy...\n",
2769 2769 skd_name(skdev));
2770 2770 skdev->state = SKD_DRVR_STATE_BUSY;
2771 2771 skdev->timer_countdown = SKD_TIMER_SECONDS(60);
2772 2772 break;
2773 2773
2774 2774 case FIT_SR_DRIVE_SOFT_RESET:
2775 2775 Dcmn_err(CE_NOTE, "(%s) drive soft reset in prog\n",
2776 2776 skd_name(skdev));
2777 2777 break;
2778 2778
2779 2779 case FIT_SR_DRIVE_FAULT:
2780 2780 /*
2781 2781 * Fault state is bad...soft reset won't do it...
2782 2782 * Hard reset, maybe, but does it work on device?
2783 2783 * For now, just fault so the system doesn't hang.
2784 2784 */
2785 2785 skd_drive_fault(skdev);
2786 2786
2787 2787 delay_action = 1;
2788 2788 break;
2789 2789
2790 2790 case 0xFF:
2791 2791 skd_drive_disappeared(skdev);
2792 2792
2793 2793 delay_action = 1;
2794 2794 break;
2795 2795
2796 2796 default:
2797 2797 Dcmn_err(CE_NOTE, "(%s) Start: unknown state %x\n",
2798 2798 skd_name(skdev), skdev->drive_state);
2799 2799 break;
2800 2800 }
2801 2801
2802 2802 state = SKD_READL(skdev, FIT_CONTROL);
2803 2803 Dcmn_err(CE_NOTE, "FIT Control Status=0x%x\n", state);
2804 2804
2805 2805 state = SKD_READL(skdev, FIT_INT_STATUS_HOST);
2806 2806 Dcmn_err(CE_NOTE, "Intr Status=0x%x\n", state);
2807 2807
2808 2808 state = SKD_READL(skdev, FIT_INT_MASK_HOST);
2809 2809 Dcmn_err(CE_NOTE, "Intr Mask=0x%x\n", state);
2810 2810
2811 2811 state = SKD_READL(skdev, FIT_MSG_FROM_DEVICE);
2812 2812 Dcmn_err(CE_NOTE, "Msg from Dev=0x%x\n", state);
2813 2813
2814 2814 state = SKD_READL(skdev, FIT_HW_VERSION);
2815 2815 Dcmn_err(CE_NOTE, "HW version=0x%x\n", state);
2816 2816
2817 2817 if (delay_action) {
2818 2818 /* start the queue so we can respond with error to requests */
2819 2819 Dcmn_err(CE_NOTE, "Starting %s queue\n", skdev->name);
2820 2820 skd_start(skdev);
2821 2821 skdev->gendisk_on = -1;
2822 2822 cv_signal(&skdev->cv_waitq);
2823 2823 }
2824 2824 }
2825 2825
2826 2826 /*
2827 2827 *
2828 2828 * Name: skd_restart_device, restart the hardware.
2829 2829 *
2830 2830 * Inputs: skdev - device state structure.
2831 2831 *
2832 2832 * Returns: Nothing.
2833 2833 *
2834 2834 */
2835 2835 static void
2836 2836 skd_restart_device(struct skd_device *skdev)
2837 2837 {
2838 2838 uint32_t state;
2839 2839
2840 2840 Dcmn_err(CE_NOTE, "skd_restart_device:");
2841 2841
2842 2842 /* ack all ghost interrupts */
2843 2843 SKD_WRITEL(skdev, FIT_INT_DEF_MASK, FIT_INT_STATUS_HOST);
2844 2844
2845 2845 state = SKD_READL(skdev, FIT_STATUS);
2846 2846
2847 2847 Dcmn_err(CE_NOTE, "skd_restart_device: drive status=0x%x\n", state);
2848 2848
2849 2849 state &= FIT_SR_DRIVE_STATE_MASK;
2850 2850 skdev->drive_state = state;
2851 2851 skdev->last_mtd = 0;
2852 2852
2853 2853 skdev->state = SKD_DRVR_STATE_RESTARTING;
2854 2854 skdev->timer_countdown = SKD_TIMER_MINUTES(4);
2855 2855
2856 2856 skd_soft_reset(skdev);
2857 2857 }
2858 2858
2859 2859 /*
2860 2860 *
2861 2861 * Name: skd_stop_device, stops the device.
2862 2862 *
2863 2863 * Inputs: skdev - device state structure.
2864 2864 *
2865 2865 * Returns: Nothing.
2866 2866 *
2867 2867 */
2868 2868 static void
2869 2869 skd_stop_device(struct skd_device *skdev)
2870 2870 {
2871 2871 clock_t cur_ticks, tmo;
2872 2872 int secs;
2873 2873 struct skd_special_context *skspcl = &skdev->internal_skspcl;
2874 2874
2875 2875 if (SKD_DRVR_STATE_ONLINE != skdev->state) {
2876 2876 Dcmn_err(CE_NOTE, "(%s): skd_stop_device not online no sync\n",
2877 2877 skdev->name);
2878 2878 goto stop_out;
2879 2879 }
2880 2880
2881 2881 if (SKD_REQ_STATE_IDLE != skspcl->req.state) {
2882 2882 Dcmn_err(CE_NOTE, "(%s): skd_stop_device no special\n",
2883 2883 skdev->name);
2884 2884 goto stop_out;
2885 2885 }
↓ open down ↓ |
2655 lines elided |
↑ open up ↑ |
2886 2886
2887 2887 skdev->state = SKD_DRVR_STATE_SYNCING;
2888 2888 skdev->sync_done = 0;
2889 2889
2890 2890 skd_send_internal_skspcl(skdev, skspcl, SYNCHRONIZE_CACHE);
2891 2891
2892 2892 secs = 10;
2893 2893 mutex_enter(&skdev->skd_internalio_mutex);
2894 2894 while (skdev->sync_done == 0) {
2895 2895 cur_ticks = ddi_get_lbolt();
2896 - tmo = cur_ticks + drv_usectohz(1000000 * secs);
2896 + tmo = cur_ticks + drv_sectohz(secs);
2897 2897 if (cv_timedwait(&skdev->cv_waitq,
2898 2898 &skdev->skd_internalio_mutex, tmo) == -1) {
2899 2899 /* Oops - timed out */
2900 2900
2901 2901 Dcmn_err(CE_NOTE, "stop_device - %d secs TMO", secs);
2902 2902 }
2903 2903 }
2904 2904
2905 2905 mutex_exit(&skdev->skd_internalio_mutex);
2906 2906
2907 2907 switch (skdev->sync_done) {
2908 2908 case 0:
2909 2909 Dcmn_err(CE_NOTE, "(%s): skd_stop_device no sync\n",
2910 2910 skdev->name);
2911 2911 break;
2912 2912 case 1:
2913 2913 Dcmn_err(CE_NOTE, "(%s): skd_stop_device sync done\n",
2914 2914 skdev->name);
2915 2915 break;
2916 2916 default:
2917 2917 Dcmn_err(CE_NOTE, "(%s): skd_stop_device sync error\n",
2918 2918 skdev->name);
2919 2919 }
2920 2920
2921 2921
2922 2922 stop_out:
2923 2923 skdev->state = SKD_DRVR_STATE_STOPPING;
2924 2924
2925 2925 skd_disable_interrupts(skdev);
2926 2926
2927 2927 /* ensure all ints on device are cleared */
2928 2928 SKD_WRITEL(skdev, FIT_INT_DEF_MASK, FIT_INT_STATUS_HOST);
2929 2929 /* soft reset the device to unload with a clean slate */
2930 2930 SKD_WRITEL(skdev, FIT_CR_SOFT_RESET, FIT_CONTROL);
2931 2931 }
2932 2932
2933 2933 /*
2934 2934 * CONSTRUCT
2935 2935 */
2936 2936
2937 2937 static int skd_cons_skcomp(struct skd_device *);
2938 2938 static int skd_cons_skmsg(struct skd_device *);
2939 2939 static int skd_cons_skreq(struct skd_device *);
2940 2940 static int skd_cons_sksb(struct skd_device *);
2941 2941 static struct fit_sg_descriptor *skd_cons_sg_list(struct skd_device *, uint32_t,
2942 2942 dma_mem_t *);
2943 2943
2944 2944 /*
2945 2945 *
2946 2946 * Name: skd_construct, calls other routines to build device
2947 2947 * interface structures.
2948 2948 *
2949 2949 * Inputs: skdev - device state structure.
2950 2950 * instance - DDI instance number.
2951 2951 *
2952 2952 * Returns: Returns DDI_FAILURE on any failure otherwise returns
2953 2953 * DDI_SUCCESS.
2954 2954 *
2955 2955 */
2956 2956 /* ARGSUSED */ /* Upstream common source with other platforms. */
2957 2957 static int
2958 2958 skd_construct(skd_device_t *skdev, int instance)
2959 2959 {
2960 2960 int rc = 0;
2961 2961
2962 2962 skdev->state = SKD_DRVR_STATE_LOAD;
2963 2963 skdev->irq_type = skd_isr_type;
2964 2964 skdev->soft_queue_depth_limit = skd_max_queue_depth;
2965 2965 skdev->hard_queue_depth_limit = 10; /* until GET_CMDQ_DEPTH */
2966 2966
2967 2967 skdev->num_req_context = skd_max_queue_depth;
2968 2968 skdev->num_fitmsg_context = skd_max_queue_depth;
2969 2969
2970 2970 skdev->queue_depth_limit = skdev->hard_queue_depth_limit;
2971 2971 skdev->queue_depth_lowat = 1;
2972 2972 skdev->proto_ver = 99; /* initialize to invalid value */
2973 2973 skdev->sgs_per_request = skd_sgs_per_request;
2974 2974 skdev->dbg_level = skd_dbg_level;
2975 2975
2976 2976 rc = skd_cons_skcomp(skdev);
2977 2977 if (rc < 0) {
2978 2978 goto err_out;
2979 2979 }
2980 2980
2981 2981 rc = skd_cons_skmsg(skdev);
2982 2982 if (rc < 0) {
2983 2983 goto err_out;
2984 2984 }
2985 2985
2986 2986 rc = skd_cons_skreq(skdev);
2987 2987 if (rc < 0) {
2988 2988 goto err_out;
2989 2989 }
2990 2990
2991 2991 rc = skd_cons_sksb(skdev);
2992 2992 if (rc < 0) {
2993 2993 goto err_out;
2994 2994 }
2995 2995
2996 2996 Dcmn_err(CE_NOTE, "CONSTRUCT VICTORY");
2997 2997
2998 2998 return (DDI_SUCCESS);
2999 2999
3000 3000 err_out:
3001 3001 Dcmn_err(CE_NOTE, "construct failed\n");
3002 3002 skd_destruct(skdev);
3003 3003
3004 3004 return (DDI_FAILURE);
3005 3005 }
3006 3006
3007 3007 /*
3008 3008 *
3009 3009 * Name: skd_free_phys, frees DMA memory.
3010 3010 *
3011 3011 * Inputs: skdev - device state structure.
3012 3012 * mem - DMA info.
3013 3013 *
3014 3014 * Returns: Nothing.
3015 3015 *
3016 3016 */
3017 3017 static void
3018 3018 skd_free_phys(skd_device_t *skdev, dma_mem_t *mem)
3019 3019 {
3020 3020 _NOTE(ARGUNUSED(skdev));
3021 3021
3022 3022 if (mem == NULL || mem->dma_handle == NULL)
3023 3023 return;
3024 3024
3025 3025 (void) ddi_dma_unbind_handle(mem->dma_handle);
3026 3026
3027 3027 if (mem->acc_handle != NULL) {
3028 3028 ddi_dma_mem_free(&mem->acc_handle);
3029 3029 mem->acc_handle = NULL;
3030 3030 }
3031 3031
3032 3032 mem->bp = NULL;
3033 3033 ddi_dma_free_handle(&mem->dma_handle);
3034 3034 mem->dma_handle = NULL;
3035 3035 }
3036 3036
3037 3037 /*
3038 3038 *
3039 3039 * Name: skd_alloc_dma_mem, allocates DMA memory.
3040 3040 *
3041 3041 * Inputs: skdev - device state structure.
3042 3042 * mem - DMA data structure.
3043 3043 * sleep - indicates whether called routine can sleep.
3044 3044 * atype - specified 32 or 64 bit allocation.
3045 3045 *
3046 3046 * Returns: Void pointer to mem->bp on success else NULL.
3047 3047 * NOTE: There are some failure modes even if sleep is set
3048 3048 * to KM_SLEEP, so callers MUST check the return code even
3049 3049 * if KM_SLEEP is passed in.
3050 3050 *
3051 3051 */
3052 3052 static void *
3053 3053 skd_alloc_dma_mem(skd_device_t *skdev, dma_mem_t *mem, uint8_t atype)
3054 3054 {
3055 3055 size_t rlen;
3056 3056 uint_t cnt;
3057 3057 ddi_dma_attr_t dma_attr = skd_64bit_io_dma_attr;
3058 3058 ddi_device_acc_attr_t acc_attr = {
3059 3059 DDI_DEVICE_ATTR_V0,
3060 3060 DDI_STRUCTURE_LE_ACC,
3061 3061 DDI_STRICTORDER_ACC
3062 3062 };
3063 3063
3064 3064 if (atype == ATYPE_32BIT)
3065 3065 dma_attr.dma_attr_addr_hi = SKD_DMA_HIGH_32BIT_ADDRESS;
3066 3066
3067 3067 dma_attr.dma_attr_sgllen = 1;
3068 3068
3069 3069 /*
3070 3070 * Allocate DMA memory.
3071 3071 */
3072 3072 if (ddi_dma_alloc_handle(skdev->dip, &dma_attr, DDI_DMA_SLEEP, NULL,
3073 3073 &mem->dma_handle) != DDI_SUCCESS) {
3074 3074 cmn_err(CE_WARN, "!alloc_dma_mem-1, failed");
3075 3075
3076 3076 mem->dma_handle = NULL;
3077 3077
3078 3078 return (NULL);
3079 3079 }
3080 3080
3081 3081 if (ddi_dma_mem_alloc(mem->dma_handle, mem->size, &acc_attr,
3082 3082 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, (caddr_t *)&mem->bp, &rlen,
3083 3083 &mem->acc_handle) != DDI_SUCCESS) {
3084 3084 cmn_err(CE_WARN, "!skd_alloc_dma_mem-2, failed");
3085 3085 ddi_dma_free_handle(&mem->dma_handle);
3086 3086 mem->dma_handle = NULL;
3087 3087 mem->acc_handle = NULL;
3088 3088 mem->bp = NULL;
3089 3089
3090 3090 return (NULL);
3091 3091 }
3092 3092 bzero(mem->bp, mem->size);
3093 3093
3094 3094 if (ddi_dma_addr_bind_handle(mem->dma_handle, NULL, mem->bp,
3095 3095 mem->size, (DDI_DMA_CONSISTENT | DDI_DMA_RDWR), DDI_DMA_SLEEP, NULL,
3096 3096 &mem->cookie, &cnt) != DDI_DMA_MAPPED) {
3097 3097 cmn_err(CE_WARN, "!skd_alloc_dma_mem-3, failed");
3098 3098 ddi_dma_mem_free(&mem->acc_handle);
3099 3099 ddi_dma_free_handle(&mem->dma_handle);
3100 3100
3101 3101 return (NULL);
3102 3102 }
3103 3103
3104 3104 if (cnt > 1) {
3105 3105 (void) ddi_dma_unbind_handle(mem->dma_handle);
3106 3106 cmn_err(CE_WARN, "!skd_alloc_dma_mem-4, failed, "
3107 3107 "cookie_count %d > 1", cnt);
3108 3108 skd_free_phys(skdev, mem);
3109 3109
3110 3110 return (NULL);
3111 3111 }
3112 3112 mem->cookies = &mem->cookie;
3113 3113 mem->cookies->dmac_size = mem->size;
3114 3114
3115 3115 return (mem->bp);
3116 3116 }
3117 3117
3118 3118 /*
3119 3119 *
3120 3120 * Name: skd_cons_skcomp, allocates space for the skcomp table.
3121 3121 *
3122 3122 * Inputs: skdev - device state structure.
3123 3123 *
3124 3124 * Returns: -ENOMEM if no memory otherwise NULL.
3125 3125 *
3126 3126 */
3127 3127 static int
3128 3128 skd_cons_skcomp(struct skd_device *skdev)
3129 3129 {
3130 3130 uint64_t *dma_alloc;
3131 3131 struct fit_completion_entry_v1 *skcomp;
3132 3132 int rc = 0;
3133 3133 uint32_t nbytes;
3134 3134 dma_mem_t *mem;
3135 3135
3136 3136 nbytes = sizeof (*skcomp) * SKD_N_COMPLETION_ENTRY;
3137 3137 nbytes += sizeof (struct fit_comp_error_info) * SKD_N_COMPLETION_ENTRY;
3138 3138
3139 3139 Dcmn_err(CE_NOTE, "cons_skcomp: nbytes=%d,entries=%d", nbytes,
3140 3140 SKD_N_COMPLETION_ENTRY);
3141 3141
3142 3142 mem = &skdev->cq_dma_address;
3143 3143 mem->size = nbytes;
3144 3144
3145 3145 dma_alloc = skd_alloc_dma_mem(skdev, mem, ATYPE_64BIT);
3146 3146 skcomp = (struct fit_completion_entry_v1 *)dma_alloc;
3147 3147 if (skcomp == NULL) {
3148 3148 rc = -ENOMEM;
3149 3149 goto err_out;
3150 3150 }
3151 3151
3152 3152 bzero(skcomp, nbytes);
3153 3153
3154 3154 Dcmn_err(CE_NOTE, "cons_skcomp: skcomp=%p nbytes=%d",
3155 3155 (void *)skcomp, nbytes);
3156 3156
3157 3157 skdev->skcomp_table = skcomp;
3158 3158 skdev->skerr_table = (struct fit_comp_error_info *)(dma_alloc +
3159 3159 (SKD_N_COMPLETION_ENTRY * sizeof (*skcomp) / sizeof (uint64_t)));
3160 3160
3161 3161 err_out:
3162 3162 return (rc);
3163 3163 }
3164 3164
3165 3165 /*
3166 3166 *
3167 3167 * Name: skd_cons_skmsg, allocates space for the skmsg table.
3168 3168 *
3169 3169 * Inputs: skdev - device state structure.
3170 3170 *
3171 3171 * Returns: -ENOMEM if no memory otherwise NULL.
3172 3172 *
3173 3173 */
3174 3174 static int
3175 3175 skd_cons_skmsg(struct skd_device *skdev)
3176 3176 {
3177 3177 dma_mem_t *mem;
3178 3178 int rc = 0;
3179 3179 uint32_t i;
3180 3180
3181 3181 Dcmn_err(CE_NOTE, "skmsg_table kzalloc, struct %lu, count %u total %lu",
3182 3182 (ulong_t)sizeof (struct skd_fitmsg_context),
3183 3183 skdev->num_fitmsg_context,
3184 3184 (ulong_t)(sizeof (struct skd_fitmsg_context) *
3185 3185 skdev->num_fitmsg_context));
3186 3186
3187 3187 skdev->skmsg_table = (struct skd_fitmsg_context *)kmem_zalloc(
3188 3188 sizeof (struct skd_fitmsg_context) * skdev->num_fitmsg_context,
3189 3189 KM_SLEEP);
3190 3190
3191 3191 for (i = 0; i < skdev->num_fitmsg_context; i++) {
3192 3192 struct skd_fitmsg_context *skmsg;
3193 3193
3194 3194 skmsg = &skdev->skmsg_table[i];
3195 3195
3196 3196 skmsg->id = i + SKD_ID_FIT_MSG;
3197 3197
3198 3198 skmsg->state = SKD_MSG_STATE_IDLE;
3199 3199
3200 3200 mem = &skmsg->mb_dma_address;
3201 3201 mem->size = SKD_N_FITMSG_BYTES + 64;
3202 3202
3203 3203 skmsg->msg_buf = skd_alloc_dma_mem(skdev, mem, ATYPE_64BIT);
3204 3204
3205 3205 if (NULL == skmsg->msg_buf) {
3206 3206 rc = -ENOMEM;
3207 3207 i++;
3208 3208 break;
3209 3209 }
3210 3210
3211 3211 skmsg->offset = 0;
3212 3212
3213 3213 bzero(skmsg->msg_buf, SKD_N_FITMSG_BYTES);
3214 3214
3215 3215 skmsg->next = &skmsg[1];
3216 3216 }
3217 3217
3218 3218 /* Free list is in order starting with the 0th entry. */
3219 3219 skdev->skmsg_table[i - 1].next = NULL;
3220 3220 skdev->skmsg_free_list = skdev->skmsg_table;
3221 3221
3222 3222 return (rc);
3223 3223 }
3224 3224
3225 3225 /*
3226 3226 *
3227 3227 * Name: skd_cons_skreq, allocates space for the skreq table.
3228 3228 *
3229 3229 * Inputs: skdev - device state structure.
3230 3230 *
3231 3231 * Returns: -ENOMEM if no memory otherwise NULL.
3232 3232 *
3233 3233 */
3234 3234 static int
3235 3235 skd_cons_skreq(struct skd_device *skdev)
3236 3236 {
3237 3237 int rc = 0;
3238 3238 uint32_t i;
3239 3239
3240 3240 Dcmn_err(CE_NOTE,
3241 3241 "skreq_table kmem_zalloc, struct %lu, count %u total %lu",
3242 3242 (ulong_t)sizeof (struct skd_request_context),
3243 3243 skdev->num_req_context,
3244 3244 (ulong_t) (sizeof (struct skd_request_context) *
3245 3245 skdev->num_req_context));
3246 3246
3247 3247 skdev->skreq_table = (struct skd_request_context *)kmem_zalloc(
3248 3248 sizeof (struct skd_request_context) * skdev->num_req_context,
3249 3249 KM_SLEEP);
3250 3250
3251 3251 for (i = 0; i < skdev->num_req_context; i++) {
3252 3252 struct skd_request_context *skreq;
3253 3253
3254 3254 skreq = &skdev->skreq_table[i];
3255 3255
3256 3256 skreq->id = (uint16_t)(i + SKD_ID_RW_REQUEST);
3257 3257 skreq->state = SKD_REQ_STATE_IDLE;
3258 3258
3259 3259 skreq->sksg_list = skd_cons_sg_list(skdev,
3260 3260 skdev->sgs_per_request,
3261 3261 &skreq->sksg_dma_address);
3262 3262
3263 3263 if (NULL == skreq->sksg_list) {
3264 3264 rc = -ENOMEM;
3265 3265 goto err_out;
3266 3266 }
3267 3267
3268 3268 skreq->next = &skreq[1];
3269 3269 }
3270 3270
3271 3271 /* Free list is in order starting with the 0th entry. */
3272 3272 skdev->skreq_table[i - 1].next = NULL;
3273 3273 skdev->skreq_free_list = skdev->skreq_table;
3274 3274
3275 3275 err_out:
3276 3276 return (rc);
3277 3277 }
3278 3278
3279 3279 /*
3280 3280 *
3281 3281 * Name: skd_cons_sksb, allocates space for the skspcl msg buf
3282 3282 * and data buf.
3283 3283 *
3284 3284 * Inputs: skdev - device state structure.
3285 3285 *
3286 3286 * Returns: -ENOMEM if no memory otherwise NULL.
3287 3287 *
3288 3288 */
3289 3289 static int
3290 3290 skd_cons_sksb(struct skd_device *skdev)
3291 3291 {
3292 3292 int rc = 0;
3293 3293 struct skd_special_context *skspcl;
3294 3294 dma_mem_t *mem;
3295 3295 uint32_t nbytes;
3296 3296
3297 3297 skspcl = &skdev->internal_skspcl;
3298 3298
3299 3299 skspcl->req.id = 0 + SKD_ID_INTERNAL;
3300 3300 skspcl->req.state = SKD_REQ_STATE_IDLE;
3301 3301
3302 3302 nbytes = SKD_N_INTERNAL_BYTES;
3303 3303
3304 3304 mem = &skspcl->db_dma_address;
3305 3305 mem->size = nbytes;
3306 3306
3307 3307 /* data_buf's DMA pointer is skspcl->db_dma_address */
3308 3308 skspcl->data_buf = skd_alloc_dma_mem(skdev, mem, ATYPE_64BIT);
3309 3309 if (skspcl->data_buf == NULL) {
3310 3310 rc = -ENOMEM;
3311 3311 goto err_out;
3312 3312 }
3313 3313
3314 3314 bzero(skspcl->data_buf, nbytes);
3315 3315
3316 3316 nbytes = SKD_N_SPECIAL_FITMSG_BYTES;
3317 3317
3318 3318 mem = &skspcl->mb_dma_address;
3319 3319 mem->size = nbytes;
3320 3320
3321 3321 /* msg_buf DMA pointer is skspcl->mb_dma_address */
3322 3322 skspcl->msg_buf = skd_alloc_dma_mem(skdev, mem, ATYPE_64BIT);
3323 3323 if (skspcl->msg_buf == NULL) {
3324 3324 rc = -ENOMEM;
3325 3325 goto err_out;
3326 3326 }
3327 3327
3328 3328
3329 3329 bzero(skspcl->msg_buf, nbytes);
3330 3330
3331 3331 skspcl->req.sksg_list = skd_cons_sg_list(skdev, 1,
3332 3332 &skspcl->req.sksg_dma_address);
3333 3333
3334 3334
3335 3335 if (skspcl->req.sksg_list == NULL) {
3336 3336 rc = -ENOMEM;
3337 3337 goto err_out;
3338 3338 }
3339 3339
3340 3340 if (skd_format_internal_skspcl(skdev) == 0) {
3341 3341 rc = -EINVAL;
3342 3342 goto err_out;
3343 3343 }
3344 3344
3345 3345 err_out:
3346 3346 return (rc);
3347 3347 }
3348 3348
3349 3349 /*
3350 3350 *
3351 3351 * Name: skd_cons_sg_list, allocates the S/G list.
3352 3352 *
3353 3353 * Inputs: skdev - device state structure.
3354 3354 * n_sg - Number of scatter-gather entries.
3355 3355 * ret_dma_addr - S/G list DMA pointer.
3356 3356 *
3357 3357 * Returns: A list of FIT message descriptors.
3358 3358 *
3359 3359 */
3360 3360 static struct fit_sg_descriptor
3361 3361 *skd_cons_sg_list(struct skd_device *skdev,
3362 3362 uint32_t n_sg, dma_mem_t *ret_dma_addr)
3363 3363 {
3364 3364 struct fit_sg_descriptor *sg_list;
3365 3365 uint32_t nbytes;
3366 3366 dma_mem_t *mem;
3367 3367
3368 3368 nbytes = sizeof (*sg_list) * n_sg;
3369 3369
3370 3370 mem = ret_dma_addr;
3371 3371 mem->size = nbytes;
3372 3372
3373 3373 /* sg_list's DMA pointer is *ret_dma_addr */
3374 3374 sg_list = skd_alloc_dma_mem(skdev, mem, ATYPE_32BIT);
3375 3375
3376 3376 if (sg_list != NULL) {
3377 3377 uint64_t dma_address = ret_dma_addr->cookie.dmac_laddress;
3378 3378 uint32_t i;
3379 3379
3380 3380 bzero(sg_list, nbytes);
3381 3381
3382 3382 for (i = 0; i < n_sg - 1; i++) {
3383 3383 uint64_t ndp_off;
3384 3384 ndp_off = (i + 1) * sizeof (struct fit_sg_descriptor);
3385 3385
3386 3386 sg_list[i].next_desc_ptr = dma_address + ndp_off;
3387 3387 }
3388 3388 sg_list[i].next_desc_ptr = 0LL;
3389 3389 }
3390 3390
3391 3391 return (sg_list);
3392 3392 }
3393 3393
3394 3394 /*
3395 3395 * DESTRUCT (FREE)
3396 3396 */
3397 3397
3398 3398 static void skd_free_skcomp(struct skd_device *skdev);
3399 3399 static void skd_free_skmsg(struct skd_device *skdev);
3400 3400 static void skd_free_skreq(struct skd_device *skdev);
3401 3401 static void skd_free_sksb(struct skd_device *skdev);
3402 3402
3403 3403 static void skd_free_sg_list(struct skd_device *skdev,
3404 3404 struct fit_sg_descriptor *sg_list,
3405 3405 uint32_t n_sg, dma_mem_t dma_addr);
3406 3406
3407 3407 /*
3408 3408 *
3409 3409 * Name: skd_destruct, call various rouines to deallocate
3410 3410 * space acquired during initialization.
3411 3411 *
3412 3412 * Inputs: skdev - device state structure.
3413 3413 *
3414 3414 * Returns: Nothing.
3415 3415 *
3416 3416 */
3417 3417 static void
3418 3418 skd_destruct(struct skd_device *skdev)
3419 3419 {
3420 3420 if (skdev == NULL) {
3421 3421 return;
3422 3422 }
3423 3423
3424 3424 Dcmn_err(CE_NOTE, "destruct sksb");
3425 3425 skd_free_sksb(skdev);
3426 3426
3427 3427 Dcmn_err(CE_NOTE, "destruct skreq");
3428 3428 skd_free_skreq(skdev);
3429 3429
3430 3430 Dcmn_err(CE_NOTE, "destruct skmsg");
3431 3431 skd_free_skmsg(skdev);
3432 3432
3433 3433 Dcmn_err(CE_NOTE, "destruct skcomp");
3434 3434 skd_free_skcomp(skdev);
3435 3435
3436 3436 Dcmn_err(CE_NOTE, "DESTRUCT VICTORY");
3437 3437 }
3438 3438
3439 3439 /*
3440 3440 *
3441 3441 * Name: skd_free_skcomp, deallocates skcomp table DMA resources.
3442 3442 *
3443 3443 * Inputs: skdev - device state structure.
3444 3444 *
3445 3445 * Returns: Nothing.
3446 3446 *
3447 3447 */
3448 3448 static void
3449 3449 skd_free_skcomp(struct skd_device *skdev)
3450 3450 {
3451 3451 if (skdev->skcomp_table != NULL) {
3452 3452 skd_free_phys(skdev, &skdev->cq_dma_address);
3453 3453 }
3454 3454
3455 3455 skdev->skcomp_table = NULL;
3456 3456 }
3457 3457
3458 3458 /*
3459 3459 *
3460 3460 * Name: skd_free_skmsg, deallocates skmsg table DMA resources.
3461 3461 *
3462 3462 * Inputs: skdev - device state structure.
3463 3463 *
3464 3464 * Returns: Nothing.
3465 3465 *
3466 3466 */
3467 3467 static void
3468 3468 skd_free_skmsg(struct skd_device *skdev)
3469 3469 {
3470 3470 uint32_t i;
3471 3471
3472 3472 if (NULL == skdev->skmsg_table)
3473 3473 return;
3474 3474
3475 3475 for (i = 0; i < skdev->num_fitmsg_context; i++) {
3476 3476 struct skd_fitmsg_context *skmsg;
3477 3477
3478 3478 skmsg = &skdev->skmsg_table[i];
3479 3479
3480 3480 if (skmsg->msg_buf != NULL) {
3481 3481 skd_free_phys(skdev, &skmsg->mb_dma_address);
3482 3482 }
3483 3483
3484 3484
3485 3485 skmsg->msg_buf = NULL;
3486 3486 }
3487 3487
3488 3488 kmem_free(skdev->skmsg_table, sizeof (struct skd_fitmsg_context) *
3489 3489 skdev->num_fitmsg_context);
3490 3490
3491 3491 skdev->skmsg_table = NULL;
3492 3492
3493 3493 }
3494 3494
3495 3495 /*
3496 3496 *
3497 3497 * Name: skd_free_skreq, deallocates skspcl table DMA resources.
3498 3498 *
3499 3499 * Inputs: skdev - device state structure.
3500 3500 *
3501 3501 * Returns: Nothing.
3502 3502 *
3503 3503 */
3504 3504 static void
3505 3505 skd_free_skreq(struct skd_device *skdev)
3506 3506 {
3507 3507 uint32_t i;
3508 3508
3509 3509 if (NULL == skdev->skreq_table)
3510 3510 return;
3511 3511
3512 3512 for (i = 0; i < skdev->num_req_context; i++) {
3513 3513 struct skd_request_context *skreq;
3514 3514
3515 3515 skreq = &skdev->skreq_table[i];
3516 3516
3517 3517 skd_free_sg_list(skdev, skreq->sksg_list,
3518 3518 skdev->sgs_per_request, skreq->sksg_dma_address);
3519 3519
3520 3520 skreq->sksg_list = NULL;
3521 3521 }
3522 3522
3523 3523 kmem_free(skdev->skreq_table, sizeof (struct skd_request_context) *
3524 3524 skdev->num_req_context);
3525 3525
3526 3526 skdev->skreq_table = NULL;
3527 3527
3528 3528 }
3529 3529
3530 3530 /*
3531 3531 *
3532 3532 * Name: skd_free_sksb, deallocates skspcl data buf and
3533 3533 * msg buf DMA resources.
3534 3534 *
3535 3535 * Inputs: skdev - device state structure.
3536 3536 *
3537 3537 * Returns: Nothing.
3538 3538 *
3539 3539 */
3540 3540 static void
3541 3541 skd_free_sksb(struct skd_device *skdev)
3542 3542 {
3543 3543 struct skd_special_context *skspcl;
3544 3544
3545 3545 skspcl = &skdev->internal_skspcl;
3546 3546
3547 3547 if (skspcl->data_buf != NULL) {
3548 3548 skd_free_phys(skdev, &skspcl->db_dma_address);
3549 3549 }
3550 3550
3551 3551 skspcl->data_buf = NULL;
3552 3552
3553 3553 if (skspcl->msg_buf != NULL) {
3554 3554 skd_free_phys(skdev, &skspcl->mb_dma_address);
3555 3555 }
3556 3556
3557 3557 skspcl->msg_buf = NULL;
3558 3558
3559 3559 skd_free_sg_list(skdev, skspcl->req.sksg_list, 1,
3560 3560 skspcl->req.sksg_dma_address);
3561 3561
3562 3562 skspcl->req.sksg_list = NULL;
3563 3563 }
3564 3564
3565 3565 /*
3566 3566 *
3567 3567 * Name: skd_free_sg_list, deallocates S/G DMA resources.
3568 3568 *
3569 3569 * Inputs: skdev - device state structure.
3570 3570 * sg_list - S/G list itself.
3571 3571 * n_sg - nukmber of segments
3572 3572 * dma_addr - S/G list DMA address.
3573 3573 *
3574 3574 * Returns: Nothing.
3575 3575 *
3576 3576 */
3577 3577 /* ARGSUSED */ /* Upstream common source with other platforms. */
3578 3578 static void
3579 3579 skd_free_sg_list(struct skd_device *skdev,
3580 3580 struct fit_sg_descriptor *sg_list,
3581 3581 uint32_t n_sg, dma_mem_t dma_addr)
3582 3582 {
3583 3583 if (sg_list != NULL) {
3584 3584 skd_free_phys(skdev, &dma_addr);
3585 3585 }
3586 3586 }
3587 3587
3588 3588 /*
3589 3589 *
3590 3590 * Name: skd_queue, queues the I/O request.
3591 3591 *
3592 3592 * Inputs: skdev - device state structure.
3593 3593 * pbuf - I/O request
3594 3594 *
3595 3595 * Returns: Nothing.
3596 3596 *
3597 3597 */
3598 3598 static void
3599 3599 skd_queue(skd_device_t *skdev, skd_buf_private_t *pbuf)
3600 3600 {
3601 3601 struct waitqueue *waitq;
3602 3602
3603 3603 ASSERT(skdev != NULL);
3604 3604 ASSERT(pbuf != NULL);
3605 3605
3606 3606 ASSERT(WAITQ_LOCK_HELD(skdev));
3607 3607
3608 3608 waitq = &skdev->waitqueue;
3609 3609
3610 3610 if (SIMPLEQ_EMPTY(waitq))
3611 3611 SIMPLEQ_INSERT_HEAD(waitq, pbuf, sq);
3612 3612 else
3613 3613 SIMPLEQ_INSERT_TAIL(waitq, pbuf, sq);
3614 3614 }
3615 3615
3616 3616 /*
3617 3617 *
3618 3618 * Name: skd_list_skreq, displays the skreq table entries.
3619 3619 *
3620 3620 * Inputs: skdev - device state structure.
3621 3621 * list - flag, if true displays the entry address.
3622 3622 *
3623 3623 * Returns: Returns number of skmsg entries found.
3624 3624 *
3625 3625 */
3626 3626 /* ARGSUSED */ /* Upstream common source with other platforms. */
3627 3627 static int
3628 3628 skd_list_skreq(skd_device_t *skdev, int list)
3629 3629 {
3630 3630 int inx = 0;
3631 3631 struct skd_request_context *skreq;
3632 3632
3633 3633 if (list) {
3634 3634 Dcmn_err(CE_NOTE, "skreq_table[0]\n");
3635 3635
3636 3636 skreq = &skdev->skreq_table[0];
3637 3637 while (skreq) {
3638 3638 if (list)
3639 3639 Dcmn_err(CE_NOTE,
3640 3640 "%d: skreq=%p state=%d id=%x fid=%x "
3641 3641 "pbuf=%p dir=%d comp=%d\n",
3642 3642 inx, (void *)skreq, skreq->state,
3643 3643 skreq->id, skreq->fitmsg_id,
3644 3644 (void *)skreq->pbuf,
3645 3645 skreq->sg_data_dir, skreq->did_complete);
3646 3646 inx++;
3647 3647 skreq = skreq->next;
3648 3648 }
3649 3649 }
3650 3650
3651 3651 inx = 0;
3652 3652 skreq = skdev->skreq_free_list;
3653 3653
3654 3654 if (list)
3655 3655 Dcmn_err(CE_NOTE, "skreq_free_list\n");
3656 3656 while (skreq) {
3657 3657 if (list)
3658 3658 Dcmn_err(CE_NOTE, "%d: skreq=%p state=%d id=%x fid=%x "
3659 3659 "pbuf=%p dir=%d\n", inx, (void *)skreq,
3660 3660 skreq->state, skreq->id, skreq->fitmsg_id,
3661 3661 (void *)skreq->pbuf, skreq->sg_data_dir);
3662 3662 inx++;
3663 3663 skreq = skreq->next;
3664 3664 }
3665 3665
3666 3666 return (inx);
3667 3667 }
3668 3668
3669 3669 /*
3670 3670 *
3671 3671 * Name: skd_list_skmsg, displays the skmsg table entries.
3672 3672 *
3673 3673 * Inputs: skdev - device state structure.
3674 3674 * list - flag, if true displays the entry address.
3675 3675 *
3676 3676 * Returns: Returns number of skmsg entries found.
3677 3677 *
3678 3678 */
3679 3679 static int
3680 3680 skd_list_skmsg(skd_device_t *skdev, int list)
3681 3681 {
3682 3682 int inx = 0;
3683 3683 struct skd_fitmsg_context *skmsgp;
3684 3684
3685 3685 skmsgp = &skdev->skmsg_table[0];
3686 3686
3687 3687 if (list) {
3688 3688 Dcmn_err(CE_NOTE, "skmsg_table[0]\n");
3689 3689
3690 3690 while (skmsgp) {
3691 3691 if (list)
3692 3692 Dcmn_err(CE_NOTE, "%d: skmsgp=%p id=%x outs=%d "
3693 3693 "l=%d o=%d nxt=%p\n", inx, (void *)skmsgp,
3694 3694 skmsgp->id, skmsgp->outstanding,
3695 3695 skmsgp->length, skmsgp->offset,
3696 3696 (void *)skmsgp->next);
3697 3697 inx++;
3698 3698 skmsgp = skmsgp->next;
3699 3699 }
3700 3700 }
3701 3701
3702 3702 inx = 0;
3703 3703 if (list)
3704 3704 Dcmn_err(CE_NOTE, "skmsg_free_list\n");
3705 3705 skmsgp = skdev->skmsg_free_list;
3706 3706 while (skmsgp) {
3707 3707 if (list)
3708 3708 Dcmn_err(CE_NOTE, "%d: skmsgp=%p id=%x outs=%d l=%d "
3709 3709 "o=%d nxt=%p\n",
3710 3710 inx, (void *)skmsgp, skmsgp->id,
3711 3711 skmsgp->outstanding, skmsgp->length,
3712 3712 skmsgp->offset, (void *)skmsgp->next);
3713 3713 inx++;
3714 3714 skmsgp = skmsgp->next;
3715 3715 }
3716 3716
3717 3717 return (inx);
3718 3718 }
3719 3719
3720 3720 /*
3721 3721 *
3722 3722 * Name: skd_get_queue_pbuf, retrieves top of queue entry and
3723 3723 * delinks entry from the queue.
3724 3724 *
3725 3725 * Inputs: skdev - device state structure.
3726 3726 * drive - device number
3727 3727 *
3728 3728 * Returns: Returns the top of the job queue entry.
3729 3729 *
3730 3730 */
3731 3731 static skd_buf_private_t
3732 3732 *skd_get_queued_pbuf(skd_device_t *skdev)
3733 3733 {
3734 3734 skd_buf_private_t *pbuf;
3735 3735
3736 3736 ASSERT(WAITQ_LOCK_HELD(skdev));
3737 3737 pbuf = SIMPLEQ_FIRST(&skdev->waitqueue);
3738 3738 if (pbuf != NULL)
3739 3739 SIMPLEQ_REMOVE_HEAD(&skdev->waitqueue, sq);
3740 3740 return (pbuf);
3741 3741 }
3742 3742
3743 3743 /*
3744 3744 * PCI DRIVER GLUE
3745 3745 */
3746 3746
3747 3747 /*
3748 3748 *
3749 3749 * Name: skd_pci_info, logs certain device PCI info.
3750 3750 *
3751 3751 * Inputs: skdev - device state structure.
3752 3752 *
3753 3753 * Returns: str which contains the device speed info..
3754 3754 *
3755 3755 */
3756 3756 static char *
3757 3757 skd_pci_info(struct skd_device *skdev, char *str, size_t len)
3758 3758 {
3759 3759 int pcie_reg;
3760 3760
3761 3761 str[0] = '\0';
3762 3762
3763 3763 pcie_reg = skd_pci_find_capability(skdev, PCI_CAP_ID_EXP);
3764 3764
3765 3765 if (pcie_reg) {
3766 3766 uint16_t lstat, lspeed, lwidth;
3767 3767
3768 3768 pcie_reg += 0x12;
3769 3769 lstat = pci_config_get16(skdev->pci_handle, pcie_reg);
3770 3770 lspeed = lstat & (0xF);
3771 3771 lwidth = (lstat & 0x3F0) >> 4;
3772 3772
3773 3773 (void) snprintf(str, len, "PCIe (%s rev %d)",
3774 3774 lspeed == 1 ? "2.5GT/s" :
3775 3775 lspeed == 2 ? "5.0GT/s" : "<unknown>",
3776 3776 lwidth);
3777 3777 }
3778 3778
3779 3779 return (str);
3780 3780 }
3781 3781
3782 3782 /*
3783 3783 * MODULE GLUE
3784 3784 */
3785 3785
3786 3786 /*
3787 3787 *
3788 3788 * Name: skd_init, initializes certain values.
3789 3789 *
3790 3790 * Inputs: skdev - device state structure.
3791 3791 *
3792 3792 * Returns: Zero.
3793 3793 *
3794 3794 */
3795 3795 /* ARGSUSED */ /* Upstream common source with other platforms. */
3796 3796 static int
3797 3797 skd_init(skd_device_t *skdev)
3798 3798 {
3799 3799 Dcmn_err(CE_NOTE, "skd_init: v%s-b%s\n", DRV_VERSION, DRV_BUILD_ID);
3800 3800
3801 3801 if (skd_max_queue_depth < 1 ||
3802 3802 skd_max_queue_depth > SKD_MAX_QUEUE_DEPTH) {
3803 3803 cmn_err(CE_NOTE, "skd_max_q_depth %d invalid, re-set to %d\n",
3804 3804 skd_max_queue_depth, SKD_MAX_QUEUE_DEPTH_DEFAULT);
3805 3805 skd_max_queue_depth = SKD_MAX_QUEUE_DEPTH_DEFAULT;
3806 3806 }
3807 3807
3808 3808 if (skd_max_req_per_msg < 1 || skd_max_req_per_msg > 14) {
3809 3809 cmn_err(CE_NOTE, "skd_max_req_per_msg %d invalid, set to %d\n",
3810 3810 skd_max_req_per_msg, SKD_MAX_REQ_PER_MSG_DEFAULT);
3811 3811 skd_max_req_per_msg = SKD_MAX_REQ_PER_MSG_DEFAULT;
3812 3812 }
3813 3813
3814 3814
3815 3815 if (skd_sgs_per_request < 1 || skd_sgs_per_request > 4096) {
3816 3816 cmn_err(CE_NOTE, "skd_sg_per_request %d invalid, set to %d\n",
3817 3817 skd_sgs_per_request, SKD_N_SG_PER_REQ_DEFAULT);
3818 3818 skd_sgs_per_request = SKD_N_SG_PER_REQ_DEFAULT;
3819 3819 }
3820 3820
3821 3821 if (skd_dbg_level < 0 || skd_dbg_level > 2) {
3822 3822 cmn_err(CE_NOTE, "skd_dbg_level %d invalid, re-set to %d\n",
3823 3823 skd_dbg_level, 0);
3824 3824 skd_dbg_level = 0;
3825 3825 }
3826 3826
3827 3827 return (0);
3828 3828 }
3829 3829
3830 3830 /*
3831 3831 *
3832 3832 * Name: skd_exit, exits the driver & logs the fact.
3833 3833 *
3834 3834 * Inputs: none.
3835 3835 *
3836 3836 * Returns: Nothing.
3837 3837 *
3838 3838 */
3839 3839 static void
3840 3840 skd_exit(void)
3841 3841 {
3842 3842 cmn_err(CE_NOTE, "skd v%s unloading", DRV_VERSION);
3843 3843 }
3844 3844
3845 3845 /*
3846 3846 *
3847 3847 * Name: skd_drive_state_to_str, converts binary drive state
3848 3848 * to its corresponding string value.
3849 3849 *
3850 3850 * Inputs: Drive state.
3851 3851 *
3852 3852 * Returns: String representing drive state.
3853 3853 *
3854 3854 */
3855 3855 const char *
3856 3856 skd_drive_state_to_str(int state)
3857 3857 {
3858 3858 switch (state) {
3859 3859 case FIT_SR_DRIVE_OFFLINE: return ("OFFLINE");
3860 3860 case FIT_SR_DRIVE_INIT: return ("INIT");
3861 3861 case FIT_SR_DRIVE_ONLINE: return ("ONLINE");
3862 3862 case FIT_SR_DRIVE_BUSY: return ("BUSY");
3863 3863 case FIT_SR_DRIVE_FAULT: return ("FAULT");
3864 3864 case FIT_SR_DRIVE_DEGRADED: return ("DEGRADED");
3865 3865 case FIT_SR_PCIE_LINK_DOWN: return ("LINK_DOWN");
3866 3866 case FIT_SR_DRIVE_SOFT_RESET: return ("SOFT_RESET");
3867 3867 case FIT_SR_DRIVE_NEED_FW_DOWNLOAD: return ("NEED_FW");
3868 3868 case FIT_SR_DRIVE_INIT_FAULT: return ("INIT_FAULT");
3869 3869 case FIT_SR_DRIVE_BUSY_SANITIZE:return ("BUSY_SANITIZE");
3870 3870 case FIT_SR_DRIVE_BUSY_ERASE: return ("BUSY_ERASE");
3871 3871 case FIT_SR_DRIVE_FW_BOOTING: return ("FW_BOOTING");
3872 3872 default: return ("???");
3873 3873 }
3874 3874 }
3875 3875
3876 3876 /*
3877 3877 *
3878 3878 * Name: skd_skdev_state_to_str, converts binary driver state
3879 3879 * to its corresponding string value.
3880 3880 *
3881 3881 * Inputs: Driver state.
3882 3882 *
3883 3883 * Returns: String representing driver state.
3884 3884 *
3885 3885 */
3886 3886 static const char *
3887 3887 skd_skdev_state_to_str(enum skd_drvr_state state)
3888 3888 {
3889 3889 switch (state) {
3890 3890 case SKD_DRVR_STATE_LOAD: return ("LOAD");
3891 3891 case SKD_DRVR_STATE_IDLE: return ("IDLE");
3892 3892 case SKD_DRVR_STATE_BUSY: return ("BUSY");
3893 3893 case SKD_DRVR_STATE_STARTING: return ("STARTING");
3894 3894 case SKD_DRVR_STATE_ONLINE: return ("ONLINE");
3895 3895 case SKD_DRVR_STATE_PAUSING: return ("PAUSING");
3896 3896 case SKD_DRVR_STATE_PAUSED: return ("PAUSED");
3897 3897 case SKD_DRVR_STATE_DRAINING_TIMEOUT: return ("DRAINING_TIMEOUT");
3898 3898 case SKD_DRVR_STATE_RESTARTING: return ("RESTARTING");
3899 3899 case SKD_DRVR_STATE_RESUMING: return ("RESUMING");
3900 3900 case SKD_DRVR_STATE_STOPPING: return ("STOPPING");
3901 3901 case SKD_DRVR_STATE_SYNCING: return ("SYNCING");
3902 3902 case SKD_DRVR_STATE_FAULT: return ("FAULT");
3903 3903 case SKD_DRVR_STATE_DISAPPEARED: return ("DISAPPEARED");
3904 3904 case SKD_DRVR_STATE_BUSY_ERASE: return ("BUSY_ERASE");
3905 3905 case SKD_DRVR_STATE_BUSY_SANITIZE:return ("BUSY_SANITIZE");
3906 3906 case SKD_DRVR_STATE_BUSY_IMMINENT: return ("BUSY_IMMINENT");
3907 3907 case SKD_DRVR_STATE_WAIT_BOOT: return ("WAIT_BOOT");
3908 3908
3909 3909 default: return ("???");
3910 3910 }
3911 3911 }
3912 3912
3913 3913 /*
3914 3914 *
3915 3915 * Name: skd_skmsg_state_to_str, converts binary driver state
3916 3916 * to its corresponding string value.
3917 3917 *
3918 3918 * Inputs: Msg state.
3919 3919 *
3920 3920 * Returns: String representing msg state.
3921 3921 *
3922 3922 */
3923 3923 static const char *
3924 3924 skd_skmsg_state_to_str(enum skd_fit_msg_state state)
3925 3925 {
3926 3926 switch (state) {
3927 3927 case SKD_MSG_STATE_IDLE: return ("IDLE");
3928 3928 case SKD_MSG_STATE_BUSY: return ("BUSY");
3929 3929 default: return ("???");
3930 3930 }
3931 3931 }
3932 3932
3933 3933 /*
3934 3934 *
3935 3935 * Name: skd_skreq_state_to_str, converts binary req state
3936 3936 * to its corresponding string value.
3937 3937 *
3938 3938 * Inputs: Req state.
3939 3939 *
3940 3940 * Returns: String representing req state.
3941 3941 *
3942 3942 */
3943 3943 static const char *
3944 3944 skd_skreq_state_to_str(enum skd_req_state state)
3945 3945 {
3946 3946 switch (state) {
3947 3947 case SKD_REQ_STATE_IDLE: return ("IDLE");
3948 3948 case SKD_REQ_STATE_SETUP: return ("SETUP");
3949 3949 case SKD_REQ_STATE_BUSY: return ("BUSY");
3950 3950 case SKD_REQ_STATE_COMPLETED: return ("COMPLETED");
3951 3951 case SKD_REQ_STATE_TIMEOUT: return ("TIMEOUT");
3952 3952 case SKD_REQ_STATE_ABORTED: return ("ABORTED");
3953 3953 default: return ("???");
3954 3954 }
3955 3955 }
3956 3956
3957 3957 /*
3958 3958 *
3959 3959 * Name: skd_log_skdev, logs device state & parameters.
3960 3960 *
3961 3961 * Inputs: skdev - device state structure.
3962 3962 * event - event (string) to log.
3963 3963 *
3964 3964 * Returns: Nothing.
3965 3965 *
3966 3966 */
3967 3967 static void
3968 3968 skd_log_skdev(struct skd_device *skdev, const char *event)
3969 3969 {
3970 3970 Dcmn_err(CE_NOTE, "log_skdev(%s) skdev=%p event='%s'",
3971 3971 skdev->name, (void *)skdev, event);
3972 3972 Dcmn_err(CE_NOTE, " drive_state=%s(%d) driver_state=%s(%d)",
3973 3973 skd_drive_state_to_str(skdev->drive_state), skdev->drive_state,
3974 3974 skd_skdev_state_to_str(skdev->state), skdev->state);
3975 3975 Dcmn_err(CE_NOTE, " busy=%d limit=%d soft=%d hard=%d lowat=%d",
3976 3976 skdev->queue_depth_busy, skdev->queue_depth_limit,
3977 3977 skdev->soft_queue_depth_limit, skdev->hard_queue_depth_limit,
3978 3978 skdev->queue_depth_lowat);
3979 3979 Dcmn_err(CE_NOTE, " timestamp=0x%x cycle=%d cycle_ix=%d",
3980 3980 skdev->timeout_stamp, skdev->skcomp_cycle, skdev->skcomp_ix);
3981 3981 }
3982 3982
3983 3983 /*
3984 3984 *
3985 3985 * Name: skd_log_skmsg, logs the skmsg event.
3986 3986 *
3987 3987 * Inputs: skdev - device state structure.
3988 3988 * skmsg - FIT message structure.
3989 3989 * event - event string to log.
3990 3990 *
3991 3991 * Returns: Nothing.
3992 3992 *
3993 3993 */
3994 3994 static void
3995 3995 skd_log_skmsg(struct skd_device *skdev,
3996 3996 struct skd_fitmsg_context *skmsg, const char *event)
3997 3997 {
3998 3998 Dcmn_err(CE_NOTE, "log_skmsg:(%s) skmsg=%p event='%s'",
3999 3999 skdev->name, (void *)skmsg, event);
4000 4000 Dcmn_err(CE_NOTE, " state=%s(%d) id=0x%04x length=%d",
4001 4001 skd_skmsg_state_to_str(skmsg->state), skmsg->state,
4002 4002 skmsg->id, skmsg->length);
4003 4003 }
4004 4004
4005 4005 /*
4006 4006 *
4007 4007 * Name: skd_log_skreq, logs the skreq event.
4008 4008 *
4009 4009 * Inputs: skdev - device state structure.
4010 4010 * skreq -skreq structure.
4011 4011 * event - event string to log.
4012 4012 *
4013 4013 * Returns: Nothing.
4014 4014 *
4015 4015 */
4016 4016 static void
4017 4017 skd_log_skreq(struct skd_device *skdev,
4018 4018 struct skd_request_context *skreq, const char *event)
4019 4019 {
4020 4020 skd_buf_private_t *pbuf;
4021 4021
4022 4022 Dcmn_err(CE_NOTE, "log_skreq: (%s) skreq=%p pbuf=%p event='%s'",
4023 4023 skdev->name, (void *)skreq, (void *)skreq->pbuf, event);
4024 4024
4025 4025 Dcmn_err(CE_NOTE, " state=%s(%d) id=0x%04x fitmsg=0x%04x",
4026 4026 skd_skreq_state_to_str(skreq->state), skreq->state,
4027 4027 skreq->id, skreq->fitmsg_id);
4028 4028 Dcmn_err(CE_NOTE, " timo=0x%x sg_dir=%d n_sg=%d",
4029 4029 skreq->timeout_stamp, skreq->sg_data_dir, skreq->n_sg);
4030 4030
4031 4031 if ((pbuf = skreq->pbuf) != NULL) {
4032 4032 uint32_t lba, count;
4033 4033 lba = pbuf->x_xfer->x_blkno;
4034 4034 count = pbuf->x_xfer->x_nblks;
4035 4035 Dcmn_err(CE_NOTE, " pbuf=%p lba=%u(0x%x) count=%u(0x%x) ",
4036 4036 (void *)pbuf, lba, lba, count, count);
4037 4037 Dcmn_err(CE_NOTE, " dir=%s "
4038 4038 " intrs=%" PRId64 " qdepth=%d",
4039 4039 (pbuf->dir & B_READ) ? "Read" : "Write",
4040 4040 skdev->intr_cntr, skdev->queue_depth_busy);
4041 4041 } else {
4042 4042 Dcmn_err(CE_NOTE, " req=NULL\n");
4043 4043 }
4044 4044 }
4045 4045
4046 4046 /*
4047 4047 *
4048 4048 * Name: skd_init_mutex, initializes all mutexes.
4049 4049 *
4050 4050 * Inputs: skdev - device state structure.
4051 4051 *
4052 4052 * Returns: DDI_FAILURE on failure otherwise DDI_SUCCESS.
4053 4053 *
4054 4054 */
4055 4055 static int
4056 4056 skd_init_mutex(skd_device_t *skdev)
4057 4057 {
4058 4058 void *intr;
4059 4059
4060 4060 Dcmn_err(CE_CONT, "(%s%d): init_mutex flags=%x", DRV_NAME,
4061 4061 skdev->instance, skdev->flags);
4062 4062
4063 4063 intr = (void *)(uintptr_t)skdev->intr_pri;
4064 4064
4065 4065 if (skdev->flags & SKD_MUTEX_INITED)
4066 4066 cmn_err(CE_NOTE, "init_mutex: Oh-Oh - already INITED");
4067 4067
4068 4068 /* mutexes to protect the adapter state structure. */
4069 4069 mutex_init(&skdev->skd_lock_mutex, NULL, MUTEX_DRIVER,
4070 4070 DDI_INTR_PRI(intr));
4071 4071 mutex_init(&skdev->skd_intr_mutex, NULL, MUTEX_DRIVER,
4072 4072 DDI_INTR_PRI(intr));
4073 4073 mutex_init(&skdev->waitqueue_mutex, NULL, MUTEX_DRIVER,
4074 4074 DDI_INTR_PRI(intr));
4075 4075 mutex_init(&skdev->skd_internalio_mutex, NULL, MUTEX_DRIVER,
4076 4076 DDI_INTR_PRI(intr));
4077 4077
4078 4078 cv_init(&skdev->cv_waitq, NULL, CV_DRIVER, NULL);
4079 4079
4080 4080 skdev->flags |= SKD_MUTEX_INITED;
4081 4081 if (skdev->flags & SKD_MUTEX_DESTROYED)
4082 4082 skdev->flags &= ~SKD_MUTEX_DESTROYED;
4083 4083
4084 4084 Dcmn_err(CE_CONT, "init_mutex (%s%d): done, flags=%x", DRV_NAME,
4085 4085 skdev->instance, skdev->flags);
4086 4086
4087 4087 return (DDI_SUCCESS);
4088 4088 }
4089 4089
4090 4090 /*
4091 4091 *
4092 4092 * Name: skd_destroy_mutex, destroys all mutexes.
4093 4093 *
4094 4094 * Inputs: skdev - device state structure.
4095 4095 *
4096 4096 * Returns: Nothing.
4097 4097 *
4098 4098 */
4099 4099 static void
4100 4100 skd_destroy_mutex(skd_device_t *skdev)
4101 4101 {
4102 4102 if ((skdev->flags & SKD_MUTEX_DESTROYED) == 0) {
4103 4103 if (skdev->flags & SKD_MUTEX_INITED) {
4104 4104 mutex_destroy(&skdev->waitqueue_mutex);
4105 4105 mutex_destroy(&skdev->skd_intr_mutex);
4106 4106 mutex_destroy(&skdev->skd_lock_mutex);
4107 4107 mutex_destroy(&skdev->skd_internalio_mutex);
4108 4108
4109 4109 cv_destroy(&skdev->cv_waitq);
4110 4110
4111 4111 skdev->flags |= SKD_MUTEX_DESTROYED;
4112 4112
4113 4113 if (skdev->flags & SKD_MUTEX_INITED)
4114 4114 skdev->flags &= ~SKD_MUTEX_INITED;
4115 4115 }
4116 4116 }
4117 4117 }
4118 4118
4119 4119 /*
4120 4120 *
4121 4121 * Name: skd_setup_intr, setup the interrupt handling
4122 4122 *
4123 4123 * Inputs: skdev - device state structure.
4124 4124 * intr_type - requested DDI interrupt type.
4125 4125 *
4126 4126 * Returns: DDI_FAILURE on failure otherwise DDI_SUCCESS.
4127 4127 *
4128 4128 */
4129 4129 static int
4130 4130 skd_setup_intr(skd_device_t *skdev, int intr_type)
4131 4131 {
4132 4132 int32_t count = 0;
4133 4133 int32_t avail = 0;
4134 4134 int32_t actual = 0;
4135 4135 int32_t ret;
4136 4136 uint32_t i;
4137 4137
4138 4138 Dcmn_err(CE_CONT, "(%s%d): setup_intr", DRV_NAME, skdev->instance);
4139 4139
4140 4140 /* Get number of interrupts the platform h/w supports */
4141 4141 if (((ret = ddi_intr_get_nintrs(skdev->dip, intr_type, &count)) !=
4142 4142 DDI_SUCCESS) || count == 0) {
4143 4143 cmn_err(CE_WARN, "!intr_setup failed, nintrs ret=%xh, cnt=%xh",
4144 4144 ret, count);
4145 4145
4146 4146 return (DDI_FAILURE);
4147 4147 }
4148 4148
4149 4149 /* Get number of available system interrupts */
4150 4150 if (((ret = ddi_intr_get_navail(skdev->dip, intr_type, &avail)) !=
4151 4151 DDI_SUCCESS) || avail == 0) {
4152 4152 cmn_err(CE_WARN, "!intr_setup failed, navail ret=%xh, "
4153 4153 "avail=%xh", ret, avail);
4154 4154
4155 4155 return (DDI_FAILURE);
4156 4156 }
4157 4157
4158 4158 if (intr_type == DDI_INTR_TYPE_MSIX && avail < SKD_MSIX_MAXAIF) {
4159 4159 cmn_err(CE_WARN, "!intr_setup failed, min MSI-X h/w vectors "
4160 4160 "req'd: %d, avail: %d",
4161 4161 SKD_MSIX_MAXAIF, count);
4162 4162
4163 4163 return (DDI_FAILURE);
4164 4164 }
4165 4165
4166 4166 /* Allocate space for interrupt handles */
4167 4167 skdev->hsize = sizeof (ddi_intr_handle_t) * avail;
4168 4168 skdev->htable = kmem_zalloc(skdev->hsize, KM_SLEEP);
4169 4169
4170 4170 /* Allocate the interrupts */
4171 4171 if ((ret = ddi_intr_alloc(skdev->dip, skdev->htable, intr_type,
4172 4172 0, count, &actual, 0)) != DDI_SUCCESS) {
4173 4173 cmn_err(CE_WARN, "!intr_setup failed, intr_alloc ret=%xh, "
4174 4174 "count = %xh, " "actual=%xh", ret, count, actual);
4175 4175
4176 4176 skd_release_intr(skdev);
4177 4177
4178 4178 return (DDI_FAILURE);
4179 4179 }
4180 4180
4181 4181 skdev->intr_cnt = actual;
4182 4182
4183 4183 if (intr_type == DDI_INTR_TYPE_FIXED)
4184 4184 (void) ddi_intr_set_pri(skdev->htable[0], 10);
4185 4185
4186 4186 /* Get interrupt priority */
4187 4187 if ((ret = ddi_intr_get_pri(skdev->htable[0], &skdev->intr_pri)) !=
4188 4188 DDI_SUCCESS) {
4189 4189 cmn_err(CE_WARN, "!intr_setup failed, get_pri ret=%xh", ret);
4190 4190 skd_release_intr(skdev);
4191 4191
4192 4192 return (ret);
4193 4193 }
4194 4194
4195 4195 /* Add the interrupt handlers */
4196 4196 for (i = 0; i < actual; i++) {
4197 4197 if ((ret = ddi_intr_add_handler(skdev->htable[i],
4198 4198 skd_isr_aif, (void *)skdev, (void *)((ulong_t)i))) !=
4199 4199 DDI_SUCCESS) {
4200 4200 cmn_err(CE_WARN, "!intr_setup failed, addh#=%xh, "
4201 4201 "act=%xh, ret=%xh", i, actual, ret);
4202 4202 skd_release_intr(skdev);
4203 4203
4204 4204 return (ret);
4205 4205 }
4206 4206 }
4207 4207
4208 4208 /* Setup mutexes */
4209 4209 if ((ret = skd_init_mutex(skdev)) != DDI_SUCCESS) {
4210 4210 cmn_err(CE_WARN, "!intr_setup failed, mutex init ret=%xh", ret);
4211 4211 skd_release_intr(skdev);
4212 4212
4213 4213 return (ret);
4214 4214 }
4215 4215
4216 4216 /* Get the capabilities */
4217 4217 (void) ddi_intr_get_cap(skdev->htable[0], &skdev->intr_cap);
4218 4218
4219 4219 /* Enable interrupts */
4220 4220 if (skdev->intr_cap & DDI_INTR_FLAG_BLOCK) {
4221 4221 if ((ret = ddi_intr_block_enable(skdev->htable,
4222 4222 skdev->intr_cnt)) != DDI_SUCCESS) {
4223 4223 cmn_err(CE_WARN, "!failed, intr_setup block enable, "
4224 4224 "ret=%xh", ret);
4225 4225 skd_destroy_mutex(skdev);
4226 4226 skd_release_intr(skdev);
4227 4227
4228 4228 return (ret);
4229 4229 }
4230 4230 } else {
4231 4231 for (i = 0; i < skdev->intr_cnt; i++) {
4232 4232 if ((ret = ddi_intr_enable(skdev->htable[i])) !=
4233 4233 DDI_SUCCESS) {
4234 4234 cmn_err(CE_WARN, "!intr_setup failed, "
4235 4235 "intr enable, ret=%xh", ret);
4236 4236 skd_destroy_mutex(skdev);
4237 4237 skd_release_intr(skdev);
4238 4238
4239 4239 return (ret);
4240 4240 }
4241 4241 }
4242 4242 }
4243 4243
4244 4244 if (intr_type == DDI_INTR_TYPE_FIXED)
4245 4245 (void) ddi_intr_clr_mask(skdev->htable[0]);
4246 4246
4247 4247 skdev->irq_type = intr_type;
4248 4248
4249 4249 return (DDI_SUCCESS);
4250 4250 }
4251 4251
4252 4252 /*
4253 4253 *
4254 4254 * Name: skd_disable_intr, disable interrupt handling.
4255 4255 *
4256 4256 * Inputs: skdev - device state structure.
4257 4257 *
4258 4258 * Returns: Nothing.
4259 4259 *
4260 4260 */
4261 4261 static void
4262 4262 skd_disable_intr(skd_device_t *skdev)
4263 4263 {
4264 4264 uint32_t i, rval;
4265 4265
4266 4266 if (skdev->intr_cap & DDI_INTR_FLAG_BLOCK) {
4267 4267 /* Remove AIF block interrupts (MSI/MSI-X) */
4268 4268 if ((rval = ddi_intr_block_disable(skdev->htable,
4269 4269 skdev->intr_cnt)) != DDI_SUCCESS) {
4270 4270 cmn_err(CE_WARN, "!failed intr block disable, rval=%x",
4271 4271 rval);
4272 4272 }
4273 4273 } else {
4274 4274 /* Remove AIF non-block interrupts (fixed). */
4275 4275 for (i = 0; i < skdev->intr_cnt; i++) {
4276 4276 if ((rval = ddi_intr_disable(skdev->htable[i])) !=
4277 4277 DDI_SUCCESS) {
4278 4278 cmn_err(CE_WARN, "!failed intr disable, "
4279 4279 "intr#=%xh, " "rval=%xh", i, rval);
4280 4280 }
4281 4281 }
4282 4282 }
4283 4283 }
4284 4284
4285 4285 /*
4286 4286 *
4287 4287 * Name: skd_release_intr, disables interrupt handling.
4288 4288 *
4289 4289 * Inputs: skdev - device state structure.
4290 4290 *
4291 4291 * Returns: Nothing.
4292 4292 *
4293 4293 */
4294 4294 static void
4295 4295 skd_release_intr(skd_device_t *skdev)
4296 4296 {
4297 4297 int32_t i;
4298 4298 int rval;
4299 4299
4300 4300
4301 4301 Dcmn_err(CE_CONT, "REL_INTR intr_cnt=%d", skdev->intr_cnt);
4302 4302
4303 4303 if (skdev->irq_type == 0) {
4304 4304 Dcmn_err(CE_CONT, "release_intr: (%s%d): done",
4305 4305 DRV_NAME, skdev->instance);
4306 4306 return;
4307 4307 }
4308 4308
4309 4309 if (skdev->htable != NULL && skdev->hsize > 0) {
4310 4310 i = (int32_t)skdev->hsize / (int32_t)sizeof (ddi_intr_handle_t);
4311 4311
4312 4312 while (i-- > 0) {
4313 4313 if (skdev->htable[i] == 0) {
4314 4314 Dcmn_err(CE_NOTE, "htable[%x]=0h", i);
4315 4315 continue;
4316 4316 }
4317 4317
4318 4318 if ((rval = ddi_intr_disable(skdev->htable[i])) !=
4319 4319 DDI_SUCCESS)
4320 4320 Dcmn_err(CE_NOTE, "release_intr: intr_disable "
4321 4321 "htable[%d], rval=%d", i, rval);
4322 4322
4323 4323 if (i < skdev->intr_cnt) {
4324 4324 if ((rval = ddi_intr_remove_handler(
4325 4325 skdev->htable[i])) != DDI_SUCCESS)
4326 4326 cmn_err(CE_WARN, "!release_intr: "
4327 4327 "intr_remove_handler FAILED, "
4328 4328 "rval=%d", rval);
4329 4329
4330 4330 Dcmn_err(CE_NOTE, "release_intr: "
4331 4331 "remove_handler htable[%d]", i);
4332 4332 }
4333 4333
4334 4334 if ((rval = ddi_intr_free(skdev->htable[i])) !=
4335 4335 DDI_SUCCESS)
4336 4336 cmn_err(CE_WARN, "!release_intr: intr_free "
4337 4337 "FAILED, rval=%d", rval);
4338 4338 Dcmn_err(CE_NOTE, "release_intr: intr_free htable[%d]",
4339 4339 i);
4340 4340 }
4341 4341
4342 4342 kmem_free(skdev->htable, skdev->hsize);
4343 4343 skdev->htable = NULL;
4344 4344 }
4345 4345
4346 4346 skdev->hsize = 0;
4347 4347 skdev->intr_cnt = 0;
4348 4348 skdev->intr_pri = 0;
4349 4349 skdev->intr_cap = 0;
4350 4350 skdev->irq_type = 0;
4351 4351 }
4352 4352
4353 4353 /*
4354 4354 *
4355 4355 * Name: skd_dealloc_resources, deallocate resources allocated
4356 4356 * during attach.
4357 4357 *
4358 4358 * Inputs: dip - DDI device info pointer.
4359 4359 * skdev - device state structure.
4360 4360 * seq - bit flag representing allocated item.
4361 4361 * instance - device instance.
4362 4362 *
4363 4363 * Returns: Nothing.
4364 4364 *
4365 4365 */
4366 4366 /* ARGSUSED */ /* Upstream common source with other platforms. */
4367 4367 static void
4368 4368 skd_dealloc_resources(dev_info_t *dip, skd_device_t *skdev,
4369 4369 uint32_t seq, int instance)
4370 4370 {
4371 4371
4372 4372 if (skdev == NULL)
4373 4373 return;
4374 4374
4375 4375 if (seq & SKD_CONSTRUCTED)
4376 4376 skd_destruct(skdev);
4377 4377
4378 4378 if (seq & SKD_INTR_ADDED) {
4379 4379 skd_disable_intr(skdev);
4380 4380 skd_release_intr(skdev);
4381 4381 }
4382 4382
4383 4383 if (seq & SKD_DEV_IOBASE_MAPPED)
4384 4384 ddi_regs_map_free(&skdev->dev_handle);
4385 4385
4386 4386 if (seq & SKD_IOMAP_IOBASE_MAPPED)
4387 4387 ddi_regs_map_free(&skdev->iomap_handle);
4388 4388
4389 4389 if (seq & SKD_REGS_MAPPED)
4390 4390 ddi_regs_map_free(&skdev->iobase_handle);
4391 4391
4392 4392 if (seq & SKD_CONFIG_SPACE_SETUP)
4393 4393 pci_config_teardown(&skdev->pci_handle);
4394 4394
4395 4395 if (seq & SKD_SOFT_STATE_ALLOCED) {
4396 4396 if (skdev->pathname &&
4397 4397 (skdev->flags & SKD_PATHNAME_ALLOCED)) {
4398 4398 kmem_free(skdev->pathname,
4399 4399 strlen(skdev->pathname)+1);
4400 4400 }
4401 4401 }
4402 4402
4403 4403 if (skdev->s1120_devid)
4404 4404 ddi_devid_free(skdev->s1120_devid);
4405 4405 }
4406 4406
4407 4407 /*
4408 4408 *
4409 4409 * Name: skd_setup_interrupt, sets up the appropriate interrupt type
4410 4410 * msi, msix, or fixed.
4411 4411 *
4412 4412 * Inputs: skdev - device state structure.
4413 4413 *
4414 4414 * Returns: DDI_FAILURE on failure otherwise DDI_SUCCESS.
4415 4415 *
4416 4416 */
4417 4417 static int
4418 4418 skd_setup_interrupts(skd_device_t *skdev)
4419 4419 {
4420 4420 int32_t rval = DDI_FAILURE;
4421 4421 int32_t i;
4422 4422 int32_t itypes = 0;
4423 4423
4424 4424 /*
4425 4425 * See what types of interrupts this adapter and platform support
4426 4426 */
4427 4427 if ((i = ddi_intr_get_supported_types(skdev->dip, &itypes)) !=
4428 4428 DDI_SUCCESS) {
4429 4429 cmn_err(CE_NOTE, "intr supported types failed, rval=%xh, ", i);
4430 4430 return (DDI_FAILURE);
4431 4431 }
4432 4432
4433 4433 Dcmn_err(CE_NOTE, "%s:supported interrupts types: %x",
4434 4434 skdev->name, itypes);
4435 4435
4436 4436 itypes &= skdev->irq_type;
4437 4437
4438 4438 if (!skd_disable_msix && (itypes & DDI_INTR_TYPE_MSIX) &&
4439 4439 (rval = skd_setup_intr(skdev, DDI_INTR_TYPE_MSIX)) == DDI_SUCCESS) {
4440 4440 cmn_err(CE_NOTE, "!%s: successful MSI-X setup",
4441 4441 skdev->name);
4442 4442 } else if (!skd_disable_msi && (itypes & DDI_INTR_TYPE_MSI) &&
4443 4443 (rval = skd_setup_intr(skdev, DDI_INTR_TYPE_MSI)) == DDI_SUCCESS) {
4444 4444 cmn_err(CE_NOTE, "!%s: successful MSI setup",
4445 4445 skdev->name);
4446 4446 } else if ((itypes & DDI_INTR_TYPE_FIXED) &&
4447 4447 (rval = skd_setup_intr(skdev, DDI_INTR_TYPE_FIXED))
4448 4448 == DDI_SUCCESS) {
4449 4449 cmn_err(CE_NOTE, "!%s: successful fixed intr setup",
4450 4450 skdev->name);
4451 4451 } else {
4452 4452 cmn_err(CE_WARN, "!%s: no supported interrupt types",
4453 4453 skdev->name);
4454 4454 return (DDI_FAILURE);
4455 4455 }
4456 4456
4457 4457 Dcmn_err(CE_CONT, "%s: setup interrupts done", skdev->name);
4458 4458
4459 4459 return (rval);
4460 4460 }
4461 4461
4462 4462 /*
4463 4463 *
4464 4464 * Name: skd_get_properties, retrieves properties from skd.conf.
4465 4465 *
4466 4466 * Inputs: skdev - device state structure.
4467 4467 * dip - dev_info data structure.
4468 4468 *
4469 4469 * Returns: Nothing.
4470 4470 *
4471 4471 */
4472 4472 /* ARGSUSED */ /* Upstream common source with other platforms. */
4473 4473 static void
4474 4474 skd_get_properties(dev_info_t *dip, skd_device_t *skdev)
4475 4475 {
4476 4476 int prop_value;
4477 4477
4478 4478 skd_isr_type = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
4479 4479 "intr-type-cap", -1);
4480 4480
4481 4481 prop_value = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
4482 4482 "max-scsi-reqs", -1);
4483 4483 if (prop_value >= 1 && prop_value <= SKD_MAX_QUEUE_DEPTH)
4484 4484 skd_max_queue_depth = prop_value;
4485 4485
4486 4486 prop_value = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
4487 4487 "max-scsi-reqs-per-msg", -1);
4488 4488 if (prop_value >= 1 && prop_value <= SKD_MAX_REQ_PER_MSG)
4489 4489 skd_max_req_per_msg = prop_value;
4490 4490
4491 4491 prop_value = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
4492 4492 "max-sgs-per-req", -1);
4493 4493 if (prop_value >= 1 && prop_value <= SKD_MAX_N_SG_PER_REQ)
4494 4494 skd_sgs_per_request = prop_value;
4495 4495
4496 4496 prop_value = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
4497 4497 "dbg-level", -1);
4498 4498 if (prop_value >= 1 && prop_value <= 2)
4499 4499 skd_dbg_level = prop_value;
4500 4500 }
4501 4501
4502 4502 /*
4503 4503 *
4504 4504 * Name: skd_wait_for_s1120, wait for device to finish
4505 4505 * its initialization.
4506 4506 *
4507 4507 * Inputs: skdev - device state structure.
4508 4508 *
4509 4509 * Returns: DDI_SUCCESS or DDI_FAILURE.
4510 4510 *
4511 4511 */
4512 4512 static int
↓ open down ↓ |
1606 lines elided |
↑ open up ↑ |
4513 4513 skd_wait_for_s1120(skd_device_t *skdev)
4514 4514 {
4515 4515 clock_t cur_ticks, tmo;
4516 4516 int loop_cntr = 0;
4517 4517 int rc = DDI_FAILURE;
4518 4518
4519 4519 mutex_enter(&skdev->skd_internalio_mutex);
4520 4520
4521 4521 while (skdev->gendisk_on == 0) {
4522 4522 cur_ticks = ddi_get_lbolt();
4523 - tmo = cur_ticks + drv_usectohz(MICROSEC);
4523 + tmo = cur_ticks + drv_sectohz(1);
4524 4524 if (cv_timedwait(&skdev->cv_waitq,
4525 4525 &skdev->skd_internalio_mutex, tmo) == -1) {
4526 4526 /* Oops - timed out */
4527 4527 if (loop_cntr++ > 10)
4528 4528 break;
4529 4529 }
4530 4530 }
4531 4531
4532 4532 mutex_exit(&skdev->skd_internalio_mutex);
4533 4533
4534 4534 if (skdev->gendisk_on == 1)
4535 4535 rc = DDI_SUCCESS;
4536 4536
4537 4537 return (rc);
4538 4538 }
4539 4539
4540 4540 /*
4541 4541 *
4542 4542 * Name: skd_update_props, updates certain device properties.
4543 4543 *
4544 4544 * Inputs: skdev - device state structure.
4545 4545 * dip - dev info structure
4546 4546 *
4547 4547 * Returns: Nothing.
4548 4548 *
4549 4549 */
4550 4550 static void
4551 4551 skd_update_props(skd_device_t *skdev, dev_info_t *dip)
4552 4552 {
4553 4553 int blksize = 512;
4554 4554
4555 4555 if ((ddi_prop_update_int64(DDI_DEV_T_NONE, dip, "device-nblocks",
4556 4556 skdev->Nblocks) != DDI_SUCCESS) ||
4557 4557 (ddi_prop_update_int(DDI_DEV_T_NONE, dip, "device-blksize",
4558 4558 blksize) != DDI_SUCCESS)) {
4559 4559 cmn_err(CE_NOTE, "%s: FAILED to create driver properties",
4560 4560 skdev->name);
4561 4561 }
4562 4562 }
4563 4563
4564 4564 /*
4565 4565 *
4566 4566 * Name: skd_setup_devid, sets up device ID info.
4567 4567 *
4568 4568 * Inputs: skdev - device state structure.
4569 4569 * devid - Device ID for the DDI.
4570 4570 *
4571 4571 * Returns: DDI_SUCCESS or DDI_FAILURE.
4572 4572 *
4573 4573 */
4574 4574 static int
4575 4575 skd_setup_devid(skd_device_t *skdev, ddi_devid_t *devid)
4576 4576 {
4577 4577 int rc, sz_model, sz_sn, sz;
4578 4578
4579 4579 sz_model = strlen(skdev->inq_product_id);
4580 4580 sz_sn = strlen(skdev->inq_serial_num);
4581 4581 sz = sz_model + sz_sn + 1;
4582 4582
4583 4583 (void) snprintf(skdev->devid_str, sizeof (skdev->devid_str), "%s=%s",
4584 4584 skdev->inq_product_id, skdev->inq_serial_num);
4585 4585 rc = ddi_devid_init(skdev->dip, DEVID_SCSI_SERIAL, sz,
4586 4586 skdev->devid_str, devid);
4587 4587
4588 4588 if (rc != DDI_SUCCESS)
4589 4589 cmn_err(CE_WARN, "!%s: devid_init FAILED", skdev->name);
4590 4590
4591 4591 return (rc);
4592 4592
4593 4593 }
4594 4594
4595 4595 /*
4596 4596 *
4597 4597 * Name: skd_bd_attach, attach to blkdev driver
4598 4598 *
4599 4599 * Inputs: skdev - device state structure.
4600 4600 * dip - device info structure.
4601 4601 *
4602 4602 * Returns: DDI_SUCCESS or DDI_FAILURE.
4603 4603 *
4604 4604 */
4605 4605 static int
4606 4606 skd_bd_attach(dev_info_t *dip, skd_device_t *skdev)
4607 4607 {
4608 4608 int rv;
4609 4609
4610 4610 skdev->s_bdh = bd_alloc_handle(skdev, &skd_bd_ops,
4611 4611 &skd_64bit_io_dma_attr, KM_SLEEP);
4612 4612
4613 4613 if (skdev->s_bdh == NULL) {
4614 4614 cmn_err(CE_WARN, "!skd_bd_attach: FAILED");
4615 4615
4616 4616 return (DDI_FAILURE);
4617 4617 }
4618 4618
4619 4619 rv = bd_attach_handle(dip, skdev->s_bdh);
4620 4620
4621 4621 if (rv != DDI_SUCCESS) {
4622 4622 cmn_err(CE_WARN, "!bd_attach_handle FAILED\n");
4623 4623 } else {
4624 4624 Dcmn_err(CE_NOTE, "bd_attach_handle OK\n");
4625 4625 skdev->bd_attached++;
4626 4626 }
4627 4627
4628 4628 return (rv);
4629 4629 }
4630 4630
4631 4631 /*
4632 4632 *
4633 4633 * Name: skd_bd_detach, detach from the blkdev driver.
4634 4634 *
4635 4635 * Inputs: skdev - device state structure.
4636 4636 *
4637 4637 * Returns: Nothing.
4638 4638 *
4639 4639 */
4640 4640 static void
4641 4641 skd_bd_detach(skd_device_t *skdev)
4642 4642 {
4643 4643 if (skdev->bd_attached)
4644 4644 (void) bd_detach_handle(skdev->s_bdh);
4645 4645
4646 4646 bd_free_handle(skdev->s_bdh);
4647 4647 }
4648 4648
4649 4649 /*
4650 4650 *
4651 4651 * Name: skd_attach, attach sdk device driver
4652 4652 *
4653 4653 * Inputs: dip - device info structure.
4654 4654 * cmd - DDI attach argument (ATTACH, RESUME, etc.)
4655 4655 *
4656 4656 * Returns: DDI_SUCCESS or DDI_FAILURE.
4657 4657 *
4658 4658 */
4659 4659 static int
4660 4660 skd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
4661 4661 {
4662 4662 int instance;
4663 4663 int nregs;
4664 4664 skd_device_t *skdev = NULL;
4665 4665 int inx;
4666 4666 uint16_t cmd_reg;
4667 4667 int progress = 0;
4668 4668 char name[MAXPATHLEN];
4669 4669 off_t regsize;
4670 4670 char pci_str[32];
4671 4671 char fw_version[8];
4672 4672
4673 4673 instance = ddi_get_instance(dip);
4674 4674
4675 4675 (void) ddi_get_parent_data(dip);
4676 4676
4677 4677 switch (cmd) {
4678 4678 case DDI_ATTACH:
4679 4679 break;
4680 4680
4681 4681 case DDI_RESUME:
4682 4682 /* Re-enable timer */
4683 4683 skd_start_timer(skdev);
4684 4684
4685 4685 return (DDI_SUCCESS);
4686 4686
4687 4687 default:
4688 4688 return (DDI_FAILURE);
4689 4689 }
4690 4690
4691 4691 Dcmn_err(CE_NOTE, "sTec S1120 Driver v%s Instance: %d",
4692 4692 VERSIONSTR, instance);
4693 4693
4694 4694 /*
4695 4695 * Check that hardware is installed in a DMA-capable slot
4696 4696 */
4697 4697 if (ddi_slaveonly(dip) == DDI_SUCCESS) {
4698 4698 cmn_err(CE_WARN, "!%s%d: installed in a "
4699 4699 "slot that isn't DMA-capable slot", DRV_NAME, instance);
4700 4700 return (DDI_FAILURE);
4701 4701 }
4702 4702
4703 4703 /*
4704 4704 * No support for high-level interrupts
4705 4705 */
4706 4706 if (ddi_intr_hilevel(dip, 0) != 0) {
4707 4707 cmn_err(CE_WARN, "!%s%d: High level interrupt not supported",
4708 4708 DRV_NAME, instance);
4709 4709 return (DDI_FAILURE);
4710 4710 }
4711 4711
4712 4712 /*
4713 4713 * Allocate our per-device-instance structure
4714 4714 */
4715 4715 if (ddi_soft_state_zalloc(skd_state, instance) !=
4716 4716 DDI_SUCCESS) {
4717 4717 cmn_err(CE_WARN, "!%s%d: soft state zalloc failed ",
4718 4718 DRV_NAME, instance);
4719 4719 return (DDI_FAILURE);
4720 4720 }
4721 4721
4722 4722 progress |= SKD_SOFT_STATE_ALLOCED;
4723 4723
4724 4724 skdev = ddi_get_soft_state(skd_state, instance);
4725 4725 if (skdev == NULL) {
4726 4726 cmn_err(CE_WARN, "!%s%d: Unable to get soft state structure",
4727 4727 DRV_NAME, instance);
4728 4728 goto skd_attach_failed;
4729 4729 }
4730 4730
4731 4731 (void) snprintf(skdev->name, sizeof (skdev->name),
4732 4732 DRV_NAME "%d", instance);
4733 4733
4734 4734 skdev->dip = dip;
4735 4735 skdev->instance = instance;
4736 4736
4737 4737 ddi_set_driver_private(dip, skdev);
4738 4738
4739 4739 (void) ddi_pathname(dip, name);
4740 4740 for (inx = strlen(name); inx; inx--) {
4741 4741 if (name[inx] == ',') {
4742 4742 name[inx] = '\0';
4743 4743 break;
4744 4744 }
4745 4745 if (name[inx] == '@') {
4746 4746 break;
4747 4747 }
4748 4748 }
4749 4749
4750 4750 skdev->pathname = kmem_zalloc(strlen(name) + 1, KM_SLEEP);
4751 4751 (void) strlcpy(skdev->pathname, name, strlen(name) + 1);
4752 4752
4753 4753 progress |= SKD_PATHNAME_ALLOCED;
4754 4754 skdev->flags |= SKD_PATHNAME_ALLOCED;
4755 4755
4756 4756 if (pci_config_setup(dip, &skdev->pci_handle) != DDI_SUCCESS) {
4757 4757 cmn_err(CE_WARN, "!%s%d: pci_config_setup FAILED",
4758 4758 DRV_NAME, instance);
4759 4759 goto skd_attach_failed;
4760 4760 }
4761 4761
4762 4762 progress |= SKD_CONFIG_SPACE_SETUP;
4763 4763
4764 4764 /* Save adapter path. */
4765 4765
4766 4766 (void) ddi_dev_nregs(dip, &nregs);
4767 4767
4768 4768 /*
4769 4769 * 0x0 Configuration Space
4770 4770 * 0x1 I/O Space
4771 4771 * 0x2 s1120 register space
4772 4772 */
4773 4773 if (ddi_dev_regsize(dip, 1, ®size) != DDI_SUCCESS ||
4774 4774 ddi_regs_map_setup(dip, 1, &skdev->iobase, 0, regsize,
4775 4775 &dev_acc_attr, &skdev->iobase_handle) != DDI_SUCCESS) {
4776 4776 cmn_err(CE_WARN, "!%s%d: regs_map_setup(mem) failed",
4777 4777 DRV_NAME, instance);
4778 4778 goto skd_attach_failed;
4779 4779 }
4780 4780 progress |= SKD_REGS_MAPPED;
4781 4781
4782 4782 skdev->iomap_iobase = skdev->iobase;
4783 4783 skdev->iomap_handle = skdev->iobase_handle;
4784 4784
4785 4785 Dcmn_err(CE_NOTE, "%s: PCI iobase=%ph, iomap=%ph, regnum=%d, "
4786 4786 "regsize=%ld", skdev->name, (void *)skdev->iobase,
4787 4787 (void *)skdev->iomap_iobase, 1, regsize);
4788 4788
4789 4789 if (ddi_dev_regsize(dip, 2, ®size) != DDI_SUCCESS ||
4790 4790 ddi_regs_map_setup(dip, 2, &skdev->dev_iobase, 0, regsize,
4791 4791 &dev_acc_attr, &skdev->dev_handle) != DDI_SUCCESS) {
4792 4792 cmn_err(CE_WARN, "!%s%d: regs_map_setup(mem) failed",
4793 4793 DRV_NAME, instance);
4794 4794
4795 4795 goto skd_attach_failed;
4796 4796 }
4797 4797
4798 4798 skdev->dev_memsize = (int)regsize;
4799 4799
4800 4800 Dcmn_err(CE_NOTE, "%s: DEV iobase=%ph regsize=%d",
4801 4801 skdev->name, (void *)skdev->dev_iobase,
4802 4802 skdev->dev_memsize);
4803 4803
4804 4804 progress |= SKD_DEV_IOBASE_MAPPED;
4805 4805
4806 4806 cmd_reg = pci_config_get16(skdev->pci_handle, PCI_CONF_COMM);
4807 4807 cmd_reg |= (PCI_COMM_ME | PCI_COMM_INTX_DISABLE);
4808 4808 cmd_reg &= ~PCI_COMM_PARITY_DETECT;
4809 4809 pci_config_put16(skdev->pci_handle, PCI_CONF_COMM, cmd_reg);
4810 4810
4811 4811 /* Get adapter PCI device information. */
4812 4812 skdev->vendor_id = pci_config_get16(skdev->pci_handle, PCI_CONF_VENID);
4813 4813 skdev->device_id = pci_config_get16(skdev->pci_handle, PCI_CONF_DEVID);
4814 4814
4815 4815 Dcmn_err(CE_NOTE, "%s: %x-%x card detected",
4816 4816 skdev->name, skdev->vendor_id, skdev->device_id);
4817 4817
4818 4818 skd_get_properties(dip, skdev);
4819 4819
4820 4820 (void) skd_init(skdev);
4821 4821
4822 4822 if (skd_construct(skdev, instance)) {
4823 4823 cmn_err(CE_WARN, "!%s: construct FAILED", skdev->name);
4824 4824 goto skd_attach_failed;
4825 4825 }
4826 4826
4827 4827 progress |= SKD_PROBED;
4828 4828 progress |= SKD_CONSTRUCTED;
4829 4829
4830 4830 SIMPLEQ_INIT(&skdev->waitqueue);
4831 4831
4832 4832 /*
4833 4833 * Setup interrupt handler
4834 4834 */
4835 4835 if (skd_setup_interrupts(skdev) != DDI_SUCCESS) {
4836 4836 cmn_err(CE_WARN, "!%s: Unable to add interrupt",
4837 4837 skdev->name);
4838 4838 goto skd_attach_failed;
4839 4839 }
4840 4840
4841 4841 progress |= SKD_INTR_ADDED;
4842 4842
4843 4843 ADAPTER_STATE_LOCK(skdev);
4844 4844 skdev->flags |= SKD_ATTACHED;
4845 4845 ADAPTER_STATE_UNLOCK(skdev);
4846 4846
4847 4847 skdev->d_blkshift = 9;
4848 4848 progress |= SKD_ATTACHED;
4849 4849
4850 4850
4851 4851 skd_start_device(skdev);
4852 4852
4853 4853 ADAPTER_STATE_LOCK(skdev);
4854 4854 skdev->progress = progress;
4855 4855 ADAPTER_STATE_UNLOCK(skdev);
4856 4856
4857 4857 /*
4858 4858 * Give the board a chance to
4859 4859 * complete its initialization.
4860 4860 */
4861 4861 if (skdev->gendisk_on != 1)
4862 4862 (void) skd_wait_for_s1120(skdev);
4863 4863
4864 4864 if (skdev->gendisk_on != 1) {
4865 4865 cmn_err(CE_WARN, "!%s: s1120 failed to come ONLINE",
4866 4866 skdev->name);
4867 4867 goto skd_attach_failed;
4868 4868 }
4869 4869
4870 4870 ddi_report_dev(dip);
4871 4871
4872 4872 skd_send_internal_skspcl(skdev, &skdev->internal_skspcl, INQUIRY);
4873 4873
4874 4874 skdev->disks_initialized++;
4875 4875
4876 4876 (void) strcpy(fw_version, "???");
4877 4877 (void) skd_pci_info(skdev, pci_str, sizeof (pci_str));
4878 4878 Dcmn_err(CE_NOTE, " sTec S1120 Driver(%s) version %s-b%s",
4879 4879 DRV_NAME, DRV_VERSION, DRV_BUILD_ID);
4880 4880
4881 4881 Dcmn_err(CE_NOTE, " sTec S1120 %04x:%04x %s 64 bit",
4882 4882 skdev->vendor_id, skdev->device_id, pci_str);
4883 4883
4884 4884 Dcmn_err(CE_NOTE, " sTec S1120 %s\n", skdev->pathname);
4885 4885
4886 4886 if (*skdev->inq_serial_num)
4887 4887 Dcmn_err(CE_NOTE, " sTec S1120 serial#=%s",
4888 4888 skdev->inq_serial_num);
4889 4889
4890 4890 if (*skdev->inq_product_id &&
4891 4891 *skdev->inq_product_rev)
4892 4892 Dcmn_err(CE_NOTE, " sTec S1120 prod ID=%s prod rev=%s",
4893 4893 skdev->inq_product_id, skdev->inq_product_rev);
4894 4894
4895 4895 Dcmn_err(CE_NOTE, "%s: intr-type-cap: %d",
4896 4896 skdev->name, skdev->irq_type);
4897 4897 Dcmn_err(CE_NOTE, "%s: max-scsi-reqs: %d",
4898 4898 skdev->name, skd_max_queue_depth);
4899 4899 Dcmn_err(CE_NOTE, "%s: max-sgs-per-req: %d",
4900 4900 skdev->name, skd_sgs_per_request);
4901 4901 Dcmn_err(CE_NOTE, "%s: max-scsi-req-per-msg: %d",
4902 4902 skdev->name, skd_max_req_per_msg);
4903 4903
4904 4904 if (skd_bd_attach(dip, skdev) == DDI_FAILURE)
4905 4905 goto skd_attach_failed;
4906 4906
4907 4907 skd_update_props(skdev, dip);
4908 4908
4909 4909 /* Enable timer */
4910 4910 skd_start_timer(skdev);
4911 4911
4912 4912 ADAPTER_STATE_LOCK(skdev);
4913 4913 skdev->progress = progress;
4914 4914 ADAPTER_STATE_UNLOCK(skdev);
4915 4915
4916 4916 skdev->attached = 1;
4917 4917 return (DDI_SUCCESS);
4918 4918
4919 4919 skd_attach_failed:
4920 4920 skd_dealloc_resources(dip, skdev, progress, instance);
4921 4921
4922 4922 if ((skdev->flags & SKD_MUTEX_DESTROYED) == 0) {
4923 4923 skd_destroy_mutex(skdev);
4924 4924 }
4925 4925
4926 4926 ddi_soft_state_free(skd_state, instance);
4927 4927
4928 4928 cmn_err(CE_WARN, "!skd_attach FAILED: progress=%x", progress);
4929 4929 return (DDI_FAILURE);
4930 4930 }
4931 4931
4932 4932 /*
4933 4933 *
4934 4934 * Name: skd_halt
4935 4935 *
4936 4936 * Inputs: skdev - device state structure.
4937 4937 *
4938 4938 * Returns: Nothing.
4939 4939 *
4940 4940 */
4941 4941 static void
4942 4942 skd_halt(skd_device_t *skdev)
4943 4943 {
4944 4944 Dcmn_err(CE_NOTE, "%s: halt/suspend ......", skdev->name);
4945 4945 }
4946 4946
4947 4947 /*
4948 4948 *
4949 4949 * Name: skd_detach, detaches driver from the system.
4950 4950 *
4951 4951 * Inputs: dip - device info structure.
4952 4952 *
4953 4953 * Returns: DDI_SUCCESS on successful detach otherwise DDI_FAILURE.
4954 4954 *
4955 4955 */
4956 4956 static int
4957 4957 skd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
4958 4958 {
4959 4959 skd_buf_private_t *pbuf;
4960 4960 skd_device_t *skdev;
4961 4961 int instance;
4962 4962 timeout_id_t timer_id = NULL;
4963 4963 int rv1 = DDI_SUCCESS;
4964 4964 struct skd_special_context *skspcl;
4965 4965
4966 4966 instance = ddi_get_instance(dip);
4967 4967
4968 4968 skdev = ddi_get_soft_state(skd_state, instance);
4969 4969 if (skdev == NULL) {
4970 4970 cmn_err(CE_WARN, "!detach failed: NULL skd state");
4971 4971
4972 4972 return (DDI_FAILURE);
4973 4973 }
4974 4974
4975 4975 Dcmn_err(CE_CONT, "skd_detach(%d): entered", instance);
4976 4976
4977 4977 switch (cmd) {
4978 4978 case DDI_DETACH:
4979 4979 /* Test for packet cache inuse. */
4980 4980 ADAPTER_STATE_LOCK(skdev);
4981 4981
4982 4982 /* Stop command/event processing. */
4983 4983 skdev->flags |= (SKD_SUSPENDED | SKD_CMD_ABORT_TMO);
4984 4984
4985 4985 /* Disable driver timer if no adapters. */
4986 4986 if (skdev->skd_timer_timeout_id != 0) {
4987 4987 timer_id = skdev->skd_timer_timeout_id;
4988 4988 skdev->skd_timer_timeout_id = 0;
4989 4989 }
4990 4990 ADAPTER_STATE_UNLOCK(skdev);
4991 4991
4992 4992 if (timer_id != 0) {
4993 4993 (void) untimeout(timer_id);
4994 4994 }
4995 4995
4996 4996 #ifdef SKD_PM
4997 4997 if (skdev->power_level != LOW_POWER_LEVEL) {
4998 4998 skd_halt(skdev);
4999 4999 skdev->power_level = LOW_POWER_LEVEL;
5000 5000 }
5001 5001 #endif
5002 5002 skspcl = &skdev->internal_skspcl;
5003 5003 skd_send_internal_skspcl(skdev, skspcl, SYNCHRONIZE_CACHE);
5004 5004
5005 5005 skd_stop_device(skdev);
5006 5006
5007 5007 /*
5008 5008 * Clear request queue.
5009 5009 */
5010 5010 while (!SIMPLEQ_EMPTY(&skdev->waitqueue)) {
5011 5011 pbuf = skd_get_queued_pbuf(skdev);
5012 5012 skd_end_request_abnormal(skdev, pbuf, ECANCELED,
5013 5013 SKD_IODONE_WNIOC);
5014 5014 Dcmn_err(CE_NOTE,
5015 5015 "detach: cancelled pbuf %p %ld <%s> %lld\n",
5016 5016 (void *)pbuf, pbuf->x_xfer->x_nblks,
5017 5017 (pbuf->dir & B_READ) ? "Read" : "Write",
5018 5018 pbuf->x_xfer->x_blkno);
5019 5019 }
5020 5020
5021 5021 skd_bd_detach(skdev);
5022 5022
5023 5023 skd_dealloc_resources(dip, skdev, skdev->progress, instance);
5024 5024
5025 5025 if ((skdev->flags & SKD_MUTEX_DESTROYED) == 0) {
5026 5026 skd_destroy_mutex(skdev);
5027 5027 }
5028 5028
5029 5029 ddi_soft_state_free(skd_state, instance);
5030 5030
5031 5031 skd_exit();
5032 5032
5033 5033 break;
5034 5034
5035 5035 case DDI_SUSPEND:
5036 5036 /* Block timer. */
5037 5037
5038 5038 ADAPTER_STATE_LOCK(skdev);
5039 5039 skdev->flags |= SKD_SUSPENDED;
5040 5040
5041 5041 /* Disable driver timer if last adapter. */
5042 5042 if (skdev->skd_timer_timeout_id != 0) {
5043 5043 timer_id = skdev->skd_timer_timeout_id;
5044 5044 skdev->skd_timer_timeout_id = 0;
5045 5045 }
5046 5046 ADAPTER_STATE_UNLOCK(skdev);
5047 5047
5048 5048 if (timer_id != 0) {
5049 5049 (void) untimeout(timer_id);
5050 5050 }
5051 5051
5052 5052 ddi_prop_remove_all(dip);
5053 5053
5054 5054 skd_halt(skdev);
5055 5055
5056 5056 break;
5057 5057 default:
5058 5058 rv1 = DDI_FAILURE;
5059 5059 break;
5060 5060 }
5061 5061
5062 5062 if (rv1 != DDI_SUCCESS) {
5063 5063 cmn_err(CE_WARN, "!skd_detach, failed, rv1=%x", rv1);
5064 5064 } else {
5065 5065 Dcmn_err(CE_CONT, "skd_detach: exiting");
5066 5066 }
5067 5067
5068 5068 if (rv1 != DDI_SUCCESS)
5069 5069 return (DDI_FAILURE);
5070 5070
5071 5071 return (rv1);
5072 5072 }
5073 5073
5074 5074 /*
5075 5075 *
5076 5076 * Name: skd_devid_init, calls skd_setup_devid to setup
5077 5077 * the device's devid structure.
5078 5078 *
5079 5079 * Inputs: arg - device state structure.
5080 5080 * dip - dev_info structure.
5081 5081 * devid - devid structure.
5082 5082 *
5083 5083 * Returns: Nothing.
5084 5084 *
5085 5085 */
5086 5086 /* ARGSUSED */ /* Upstream common source with other platforms. */
5087 5087 static int
5088 5088 skd_devid_init(void *arg, dev_info_t *dip, ddi_devid_t *devid)
5089 5089 {
5090 5090 skd_device_t *skdev = arg;
5091 5091
5092 5092 (void) skd_setup_devid(skdev, devid);
5093 5093
5094 5094 return (0);
5095 5095 }
5096 5096
5097 5097 /*
5098 5098 *
5099 5099 * Name: skd_bd_driveinfo, retrieves device's info.
5100 5100 *
5101 5101 * Inputs: drive - drive data structure.
5102 5102 * arg - device state structure.
5103 5103 *
5104 5104 * Returns: Nothing.
5105 5105 *
5106 5106 */
5107 5107 static void
5108 5108 skd_bd_driveinfo(void *arg, bd_drive_t *drive)
5109 5109 {
5110 5110 skd_device_t *skdev = arg;
5111 5111
5112 5112 drive->d_qsize = (skdev->queue_depth_limit * 4) / 5;
5113 5113 drive->d_maxxfer = SKD_DMA_MAXXFER;
5114 5114 drive->d_removable = B_FALSE;
5115 5115 drive->d_hotpluggable = B_FALSE;
5116 5116 drive->d_target = 0;
5117 5117 drive->d_lun = 0;
5118 5118 }
5119 5119
5120 5120 /*
5121 5121 *
5122 5122 * Name: skd_bd_mediainfo, retrieves device media info.
5123 5123 *
5124 5124 * Inputs: arg - device state structure.
5125 5125 * media - container for media info.
5126 5126 *
5127 5127 * Returns: Zero.
5128 5128 *
5129 5129 */
5130 5130 static int
5131 5131 skd_bd_mediainfo(void *arg, bd_media_t *media)
5132 5132 {
5133 5133 skd_device_t *skdev = arg;
5134 5134
5135 5135 media->m_nblks = skdev->Nblocks;
5136 5136 media->m_blksize = 512;
5137 5137 media->m_pblksize = 4096;
5138 5138 media->m_readonly = B_FALSE;
5139 5139 media->m_solidstate = B_TRUE;
5140 5140
5141 5141 return (0);
5142 5142 }
5143 5143
5144 5144 /*
5145 5145 *
5146 5146 * Name: skd_rw, performs R/W requests for blkdev driver.
5147 5147 *
5148 5148 * Inputs: skdev - device state structure.
5149 5149 * xfer - tranfer structure.
5150 5150 * dir - I/O direction.
5151 5151 *
5152 5152 * Returns: EAGAIN if device is not online. EIO if blkdev wants us to
5153 5153 * be a dump device (for now).
5154 5154 * Value returned by skd_start().
5155 5155 *
5156 5156 */
5157 5157 static int
5158 5158 skd_rw(skd_device_t *skdev, bd_xfer_t *xfer, int dir)
5159 5159 {
5160 5160 skd_buf_private_t *pbuf;
5161 5161
5162 5162 /*
5163 5163 * The x_flags structure element is not defined in Oracle Solaris
5164 5164 */
5165 5165 /* We'll need to fix this in order to support dump on this device. */
5166 5166 if (xfer->x_flags & BD_XFER_POLL)
5167 5167 return (EIO);
5168 5168
5169 5169 if (skdev->state != SKD_DRVR_STATE_ONLINE) {
5170 5170 Dcmn_err(CE_NOTE, "Device - not ONLINE");
5171 5171
5172 5172 skd_request_fn_not_online(skdev);
5173 5173
5174 5174 return (EAGAIN);
5175 5175 }
5176 5176
5177 5177 pbuf = kmem_zalloc(sizeof (skd_buf_private_t), KM_NOSLEEP);
5178 5178 if (pbuf == NULL)
5179 5179 return (ENOMEM);
5180 5180
5181 5181 WAITQ_LOCK(skdev);
5182 5182 pbuf->dir = dir;
5183 5183 pbuf->x_xfer = xfer;
5184 5184
5185 5185 skd_queue(skdev, pbuf);
5186 5186 skdev->ios_queued++;
5187 5187 WAITQ_UNLOCK(skdev);
5188 5188
5189 5189 skd_start(skdev);
5190 5190
5191 5191 return (0);
5192 5192 }
5193 5193
5194 5194 /*
5195 5195 *
5196 5196 * Name: skd_bd_read, performs blkdev read requests.
5197 5197 *
5198 5198 * Inputs: arg - device state structure.
5199 5199 * xfer - tranfer request structure.
5200 5200 *
5201 5201 * Returns: Value return by skd_rw().
5202 5202 *
5203 5203 */
5204 5204 static int
5205 5205 skd_bd_read(void *arg, bd_xfer_t *xfer)
5206 5206 {
5207 5207 return (skd_rw(arg, xfer, B_READ));
5208 5208 }
5209 5209
5210 5210 /*
5211 5211 *
5212 5212 * Name: skd_bd_write, performs blkdev write requests.
5213 5213 *
5214 5214 * Inputs: arg - device state structure.
5215 5215 * xfer - tranfer request structure.
5216 5216 *
5217 5217 * Returns: Value return by skd_rw().
5218 5218 *
5219 5219 */
5220 5220 static int
5221 5221 skd_bd_write(void *arg, bd_xfer_t *xfer)
5222 5222 {
5223 5223 return (skd_rw(arg, xfer, B_WRITE));
5224 5224 }
↓ open down ↓ |
691 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX