1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Direct Attached Disk 29 */ 30 31 #include <sys/file.h> 32 #include <sys/scsi/scsi.h> 33 #include <sys/var.h> 34 #include <sys/proc.h> 35 #include <sys/dktp/cm.h> 36 #include <sys/vtoc.h> 37 #include <sys/dkio.h> 38 #include <sys/policy.h> 39 #include <sys/priv.h> 40 41 #include <sys/dktp/dadev.h> 42 #include <sys/dktp/fctypes.h> 43 #include <sys/dktp/flowctrl.h> 44 #include <sys/dktp/tgcom.h> 45 #include <sys/dktp/tgdk.h> 46 #include <sys/dktp/bbh.h> 47 #include <sys/dktp/dadkio.h> 48 #include <sys/dktp/dadk.h> 49 #include <sys/cdio.h> 50 51 /* 52 * Local Function Prototypes 53 */ 54 static void dadk_restart(void *pktp); 55 static void dadk_pktcb(struct cmpkt *pktp); 56 static void dadk_iodone(struct buf *bp); 57 static void dadk_polldone(struct buf *bp); 58 static void dadk_setcap(struct dadk *dadkp); 59 static void dadk_create_errstats(struct dadk *dadkp, int instance); 60 static void dadk_destroy_errstats(struct dadk *dadkp); 61 62 static int dadk_chkerr(struct cmpkt *pktp); 63 static int dadk_ioprep(struct dadk *dadkp, struct cmpkt *pktp); 64 static int dadk_iosetup(struct dadk *dadkp, struct cmpkt *pktp); 65 static int dadk_ioretry(struct cmpkt *pktp, int action); 66 67 static struct cmpkt *dadk_pktprep(struct dadk *dadkp, struct cmpkt *in_pktp, 68 struct buf *bp, void (*cb_func)(struct buf *), int (*func)(caddr_t), 69 caddr_t arg); 70 71 static int dadk_pkt(opaque_t com_data, struct buf *bp, int (*func)(caddr_t), 72 caddr_t arg); 73 static void dadk_transport(opaque_t com_data, struct buf *bp); 74 static int dadk_ctl_ioctl(struct dadk *, uint32_t, uintptr_t, int); 75 76 struct tgcom_objops dadk_com_ops = { 77 nodev, 78 nodev, 79 dadk_pkt, 80 dadk_transport, 81 0, 0 82 }; 83 84 /* 85 * architecture dependent allocation restrictions for dadk_iob_alloc(). For 86 * x86, we'll set dma_attr_addr_hi to dadk_max_phys_addr and dma_attr_sgllen 87 * to dadk_sgl_size during _init(). 88 */ 89 #if defined(__sparc) 90 static ddi_dma_attr_t dadk_alloc_attr = { 91 DMA_ATTR_V0, /* version number */ 92 0x0, /* lowest usable address */ 93 0xFFFFFFFFull, /* high DMA address range */ 94 0xFFFFFFFFull, /* DMA counter register */ 95 1, /* DMA address alignment */ 96 1, /* DMA burstsizes */ 97 1, /* min effective DMA size */ 98 0xFFFFFFFFull, /* max DMA xfer size */ 99 0xFFFFFFFFull, /* segment boundary */ 100 1, /* s/g list length */ 101 512, /* granularity of device */ 102 0, /* DMA transfer flags */ 103 }; 104 #elif defined(__x86) 105 static ddi_dma_attr_t dadk_alloc_attr = { 106 DMA_ATTR_V0, /* version number */ 107 0x0, /* lowest usable address */ 108 0x0, /* high DMA address range [set in _init()] */ 109 0xFFFFull, /* DMA counter register */ 110 512, /* DMA address alignment */ 111 1, /* DMA burstsizes */ 112 1, /* min effective DMA size */ 113 0xFFFFFFFFull, /* max DMA xfer size */ 114 0xFFFFFFFFull, /* segment boundary */ 115 0, /* s/g list length [set in _init()] */ 116 512, /* granularity of device */ 117 0, /* DMA transfer flags */ 118 }; 119 120 uint64_t dadk_max_phys_addr = 0xFFFFFFFFull; 121 int dadk_sgl_size = 0xFF; 122 #endif 123 124 static int dadk_rmb_ioctl(struct dadk *dadkp, int cmd, intptr_t arg, int flags, 125 int silent); 126 static void dadk_rmb_iodone(struct buf *bp); 127 128 static int dadk_dk_buf_setup(struct dadk *dadkp, opaque_t *cmdp, 129 dev_t dev, enum uio_seg dataspace, int rw); 130 static void dadk_dk(struct dadk *dadkp, struct dadkio_rwcmd *scmdp, 131 struct buf *bp); 132 static void dadkmin(struct buf *bp); 133 static int dadk_dk_strategy(struct buf *bp); 134 static void dadk_recorderr(struct cmpkt *pktp, struct dadkio_rwcmd *rwcmdp); 135 136 struct tgdk_objops dadk_ops = { 137 dadk_init, 138 dadk_free, 139 dadk_probe, 140 dadk_attach, 141 dadk_open, 142 dadk_close, 143 dadk_ioctl, 144 dadk_strategy, 145 dadk_setgeom, 146 dadk_getgeom, 147 dadk_iob_alloc, 148 dadk_iob_free, 149 dadk_iob_htoc, 150 dadk_iob_xfer, 151 dadk_dump, 152 dadk_getphygeom, 153 dadk_set_bbhobj, 154 dadk_check_media, 155 dadk_inquiry, 156 dadk_cleanup, 157 0 158 }; 159 160 /* 161 * Local static data 162 */ 163 164 #ifdef DADK_DEBUG 165 #define DENT 0x0001 166 #define DERR 0x0002 167 #define DIO 0x0004 168 #define DGEOM 0x0010 169 #define DSTATE 0x0020 170 static int dadk_debug = DGEOM; 171 172 #endif /* DADK_DEBUG */ 173 174 static int dadk_check_media_time = 3000000; /* 3 Second State Check */ 175 static int dadk_dk_maxphys = 0x80000; 176 177 static char *dadk_cmds[] = { 178 "\000Unknown", /* unknown */ 179 "\001read sector", /* DCMD_READ 1 */ 180 "\002write sector", /* DCMD_WRITE 2 */ 181 "\003format track", /* DCMD_FMTTRK 3 */ 182 "\004format whole drive", /* DCMD_FMTDRV 4 */ 183 "\005recalibrate", /* DCMD_RECAL 5 */ 184 "\006seek sector", /* DCMD_SEEK 6 */ 185 "\007read verify", /* DCMD_RDVER 7 */ 186 "\010read defect list", /* DCMD_GETDEF 8 */ 187 "\011lock door", /* DCMD_LOCK 9 */ 188 "\012unlock door", /* DCMD_UNLOCK 10 */ 189 "\013start motor", /* DCMD_START_MOTOR 11 */ 190 "\014stop motor", /* DCMD_STOP_MOTOR 12 */ 191 "\015eject", /* DCMD_EJECT 13 */ 192 "\016update geometry", /* DCMD_UPDATE_GEOM 14 */ 193 "\017get state", /* DCMD_GET_STATE 15 */ 194 "\020cdrom pause", /* DCMD_PAUSE 16 */ 195 "\021cdrom resume", /* DCMD_RESUME 17 */ 196 "\022cdrom play track index", /* DCMD_PLAYTRKIND 18 */ 197 "\023cdrom play msf", /* DCMD_PLAYMSF 19 */ 198 "\024cdrom sub channel", /* DCMD_SUBCHNL 20 */ 199 "\025cdrom read mode 1", /* DCMD_READMODE1 21 */ 200 "\026cdrom read toc header", /* DCMD_READTOCHDR 22 */ 201 "\027cdrom read toc entry", /* DCMD_READTOCENT 23 */ 202 "\030cdrom read offset", /* DCMD_READOFFSET 24 */ 203 "\031cdrom read mode 2", /* DCMD_READMODE2 25 */ 204 "\032cdrom volume control", /* DCMD_VOLCTRL 26 */ 205 "\033flush cache", /* DCMD_FLUSH_CACHE 27 */ 206 NULL 207 }; 208 209 static char *dadk_sense[] = { 210 "\000Success", /* DERR_SUCCESS */ 211 "\001address mark not found", /* DERR_AMNF */ 212 "\002track 0 not found", /* DERR_TKONF */ 213 "\003aborted command", /* DERR_ABORT */ 214 "\004write fault", /* DERR_DWF */ 215 "\005ID not found", /* DERR_IDNF */ 216 "\006drive busy", /* DERR_BUSY */ 217 "\007uncorrectable data error", /* DERR_UNC */ 218 "\010bad block detected", /* DERR_BBK */ 219 "\011invalid command", /* DERR_INVCDB */ 220 "\012device hard error", /* DERR_HARD */ 221 "\013illegal length indicated", /* DERR_ILI */ 222 "\014end of media", /* DERR_EOM */ 223 "\015media change requested", /* DERR_MCR */ 224 "\016recovered from error", /* DERR_RECOVER */ 225 "\017device not ready", /* DERR_NOTREADY */ 226 "\020medium error", /* DERR_MEDIUM */ 227 "\021hardware error", /* DERR_HW */ 228 "\022illegal request", /* DERR_ILL */ 229 "\023unit attention", /* DERR_UNIT_ATTN */ 230 "\024data protection", /* DERR_DATA_PROT */ 231 "\025miscompare", /* DERR_MISCOMPARE */ 232 "\026ICRC error during UDMA", /* DERR_ICRC */ 233 "\027reserved", /* DERR_RESV */ 234 NULL 235 }; 236 237 static char *dadk_name = "Disk"; 238 239 /* 240 * This is the loadable module wrapper 241 */ 242 #include <sys/modctl.h> 243 244 extern struct mod_ops mod_miscops; 245 246 static struct modlmisc modlmisc = { 247 &mod_miscops, /* Type of module */ 248 "Direct Attached Disk" 249 }; 250 251 static struct modlinkage modlinkage = { 252 MODREV_1, (void *)&modlmisc, NULL 253 }; 254 255 int 256 _init(void) 257 { 258 #ifdef DADK_DEBUG 259 if (dadk_debug & DENT) 260 PRF("dadk_init: call\n"); 261 #endif 262 263 #if defined(__x86) 264 /* set the max physical address for iob allocs on x86 */ 265 dadk_alloc_attr.dma_attr_addr_hi = dadk_max_phys_addr; 266 267 /* 268 * set the sgllen for iob allocs on x86. If this is set less than 269 * the number of pages the buffer will take (taking into account 270 * alignment), it would force the allocator to try and allocate 271 * contiguous pages. 272 */ 273 dadk_alloc_attr.dma_attr_sgllen = dadk_sgl_size; 274 #endif 275 276 return (mod_install(&modlinkage)); 277 } 278 279 int 280 _fini(void) 281 { 282 #ifdef DADK_DEBUG 283 if (dadk_debug & DENT) 284 PRF("dadk_fini: call\n"); 285 #endif 286 287 return (mod_remove(&modlinkage)); 288 } 289 290 int 291 _info(struct modinfo *modinfop) 292 { 293 return (mod_info(&modlinkage, modinfop)); 294 } 295 296 struct tgdk_obj * 297 dadk_create() 298 { 299 struct tgdk_obj *dkobjp; 300 struct dadk *dadkp; 301 302 dkobjp = kmem_zalloc((sizeof (*dkobjp) + sizeof (*dadkp)), KM_NOSLEEP); 303 if (!dkobjp) 304 return (NULL); 305 dadkp = (struct dadk *)(dkobjp+1); 306 307 dkobjp->tg_ops = (struct tgdk_objops *)&dadk_ops; 308 dkobjp->tg_data = (opaque_t)dadkp; 309 dkobjp->tg_ext = &(dkobjp->tg_extblk); 310 dadkp->dad_extp = &(dkobjp->tg_extblk); 311 312 #ifdef DADK_DEBUG 313 if (dadk_debug & DENT) 314 PRF("dadk_create: tgdkobjp= 0x%x dadkp= 0x%x\n", dkobjp, dadkp); 315 #endif 316 return (dkobjp); 317 } 318 319 int 320 dadk_init(opaque_t objp, opaque_t devp, opaque_t flcobjp, opaque_t queobjp, 321 opaque_t bbhobjp, void *lkarg) 322 { 323 struct dadk *dadkp = (struct dadk *)objp; 324 struct scsi_device *sdevp = (struct scsi_device *)devp; 325 326 dadkp->dad_sd = devp; 327 dadkp->dad_ctlobjp = (opaque_t)sdevp->sd_address.a_hba_tran; 328 sdevp->sd_private = (caddr_t)dadkp; 329 330 /* initialize the communication object */ 331 dadkp->dad_com.com_data = (opaque_t)dadkp; 332 dadkp->dad_com.com_ops = &dadk_com_ops; 333 334 dadkp->dad_bbhobjp = bbhobjp; 335 BBH_INIT(bbhobjp); 336 337 dadkp->dad_flcobjp = flcobjp; 338 mutex_init(&dadkp->dad_cmd_mutex, NULL, MUTEX_DRIVER, NULL); 339 dadkp->dad_cmd_count = 0; 340 return (FLC_INIT(flcobjp, &(dadkp->dad_com), queobjp, lkarg)); 341 } 342 343 int 344 dadk_free(struct tgdk_obj *dkobjp) 345 { 346 TGDK_CLEANUP(dkobjp); 347 kmem_free(dkobjp, (sizeof (*dkobjp) + sizeof (struct dadk))); 348 349 return (DDI_SUCCESS); 350 } 351 352 void 353 dadk_cleanup(struct tgdk_obj *dkobjp) 354 { 355 struct dadk *dadkp; 356 357 dadkp = (struct dadk *)(dkobjp->tg_data); 358 if (dadkp->dad_sd) 359 dadkp->dad_sd->sd_private = NULL; 360 if (dadkp->dad_bbhobjp) { 361 BBH_FREE(dadkp->dad_bbhobjp); 362 dadkp->dad_bbhobjp = NULL; 363 } 364 if (dadkp->dad_flcobjp) { 365 FLC_FREE(dadkp->dad_flcobjp); 366 dadkp->dad_flcobjp = NULL; 367 } 368 mutex_destroy(&dadkp->dad_cmd_mutex); 369 } 370 371 /* ARGSUSED */ 372 int 373 dadk_probe(opaque_t objp, int kmsflg) 374 { 375 struct dadk *dadkp = (struct dadk *)objp; 376 struct scsi_device *devp; 377 char name[80]; 378 379 devp = dadkp->dad_sd; 380 if (!devp->sd_inq || (devp->sd_inq->inq_dtype == DTYPE_NOTPRESENT) || 381 (devp->sd_inq->inq_dtype == DTYPE_UNKNOWN)) { 382 return (DDI_PROBE_FAILURE); 383 } 384 385 switch (devp->sd_inq->inq_dtype) { 386 case DTYPE_DIRECT: 387 dadkp->dad_ctype = DKC_DIRECT; 388 dadkp->dad_extp->tg_nodetype = DDI_NT_BLOCK; 389 dadkp->dad_extp->tg_ctype = DKC_DIRECT; 390 break; 391 case DTYPE_RODIRECT: /* eg cdrom */ 392 dadkp->dad_ctype = DKC_CDROM; 393 dadkp->dad_extp->tg_rdonly = 1; 394 dadkp->dad_rdonly = 1; 395 dadkp->dad_cdrom = 1; 396 dadkp->dad_extp->tg_nodetype = DDI_NT_CD; 397 dadkp->dad_extp->tg_ctype = DKC_CDROM; 398 break; 399 case DTYPE_WORM: 400 case DTYPE_OPTICAL: 401 default: 402 return (DDI_PROBE_FAILURE); 403 } 404 405 dadkp->dad_extp->tg_rmb = dadkp->dad_rmb = devp->sd_inq->inq_rmb; 406 407 dadkp->dad_secshf = SCTRSHFT; 408 dadkp->dad_blkshf = 0; 409 410 /* display the device name */ 411 (void) strcpy(name, "Vendor '"); 412 gda_inqfill((caddr_t)devp->sd_inq->inq_vid, 8, &name[strlen(name)]); 413 (void) strcat(name, "' Product '"); 414 gda_inqfill((caddr_t)devp->sd_inq->inq_pid, 16, &name[strlen(name)]); 415 (void) strcat(name, "'"); 416 gda_log(devp->sd_dev, dadk_name, CE_NOTE, "!<%s>\n", name); 417 418 return (DDI_PROBE_SUCCESS); 419 } 420 421 422 /* ARGSUSED */ 423 int 424 dadk_attach(opaque_t objp) 425 { 426 return (DDI_SUCCESS); 427 } 428 429 int 430 dadk_set_bbhobj(opaque_t objp, opaque_t bbhobjp) 431 { 432 struct dadk *dadkp = (struct dadk *)objp; 433 /* free the old bbh object */ 434 if (dadkp->dad_bbhobjp) 435 BBH_FREE(dadkp->dad_bbhobjp); 436 437 /* initialize the new bbh object */ 438 dadkp->dad_bbhobjp = bbhobjp; 439 BBH_INIT(bbhobjp); 440 441 return (DDI_SUCCESS); 442 } 443 444 /* ARGSUSED */ 445 int 446 dadk_open(opaque_t objp, int flag) 447 { 448 struct dadk *dadkp = (struct dadk *)objp; 449 int error; 450 int wce; 451 452 if (!dadkp->dad_rmb) { 453 if (dadkp->dad_phyg.g_cap) { 454 FLC_START_KSTAT(dadkp->dad_flcobjp, "disk", 455 ddi_get_instance(CTL_DIP_DEV(dadkp->dad_ctlobjp))); 456 return (DDI_SUCCESS); 457 } 458 } else { 459 mutex_enter(&dadkp->dad_mutex); 460 dadkp->dad_iostate = DKIO_NONE; 461 cv_broadcast(&dadkp->dad_state_cv); 462 mutex_exit(&dadkp->dad_mutex); 463 464 if (dadk_rmb_ioctl(dadkp, DCMD_START_MOTOR, 0, 0, 465 DADK_SILENT) || 466 dadk_rmb_ioctl(dadkp, DCMD_LOCK, 0, 0, DADK_SILENT) || 467 dadk_rmb_ioctl(dadkp, DCMD_UPDATE_GEOM, 0, 0, 468 DADK_SILENT)) { 469 return (DDI_FAILURE); 470 } 471 472 mutex_enter(&dadkp->dad_mutex); 473 dadkp->dad_iostate = DKIO_INSERTED; 474 cv_broadcast(&dadkp->dad_state_cv); 475 mutex_exit(&dadkp->dad_mutex); 476 } 477 478 /* 479 * get write cache enable state 480 * If there is an error, must assume that write cache 481 * is enabled. 482 * NOTE: Since there is currently no Solaris mechanism to 483 * change the state of the Write Cache Enable feature, 484 * this code just checks the value of the WCE bit 485 * obtained at device init time. If a mechanism 486 * is added to the driver to change WCE, dad_wce 487 * must be updated appropriately. 488 */ 489 error = dadk_ctl_ioctl(dadkp, DIOCTL_GETWCE, 490 (uintptr_t)&wce, FKIOCTL | FNATIVE); 491 mutex_enter(&dadkp->dad_mutex); 492 dadkp->dad_wce = (error != 0) || (wce != 0); 493 mutex_exit(&dadkp->dad_mutex); 494 495 /* logical disk geometry */ 496 (void) dadk_ctl_ioctl(dadkp, DIOCTL_GETGEOM, 497 (uintptr_t)&dadkp->dad_logg, FKIOCTL | FNATIVE); 498 if (dadkp->dad_logg.g_cap == 0) 499 return (DDI_FAILURE); 500 501 /* get physical disk geometry */ 502 (void) dadk_ctl_ioctl(dadkp, DIOCTL_GETPHYGEOM, 503 (uintptr_t)&dadkp->dad_phyg, FKIOCTL | FNATIVE); 504 if (dadkp->dad_phyg.g_cap == 0) 505 return (DDI_FAILURE); 506 507 dadk_setcap(dadkp); 508 509 dadk_create_errstats(dadkp, 510 ddi_get_instance(CTL_DIP_DEV(dadkp->dad_ctlobjp))); 511 512 /* start profiling */ 513 FLC_START_KSTAT(dadkp->dad_flcobjp, "disk", 514 ddi_get_instance(CTL_DIP_DEV(dadkp->dad_ctlobjp))); 515 516 return (DDI_SUCCESS); 517 } 518 519 static void 520 dadk_setcap(struct dadk *dadkp) 521 { 522 int totsize; 523 int i; 524 525 totsize = dadkp->dad_phyg.g_secsiz; 526 527 if (totsize == 0) { 528 if (dadkp->dad_cdrom) { 529 totsize = 2048; 530 } else { 531 totsize = NBPSCTR; 532 } 533 } else { 534 /* Round down sector size to multiple of 512B */ 535 totsize &= ~(NBPSCTR-1); 536 } 537 dadkp->dad_phyg.g_secsiz = totsize; 538 539 /* set sec,block shift factor - (512->0, 1024->1, 2048->2, etc.) */ 540 totsize >>= SCTRSHFT; 541 for (i = 0; totsize != 1; i++, totsize >>= 1) 542 ; 543 dadkp->dad_blkshf = i; 544 dadkp->dad_secshf = i + SCTRSHFT; 545 } 546 547 548 static void 549 dadk_create_errstats(struct dadk *dadkp, int instance) 550 { 551 dadk_errstats_t *dep; 552 char kstatname[KSTAT_STRLEN]; 553 dadk_ioc_string_t dadk_ioc_string; 554 555 if (dadkp->dad_errstats) 556 return; 557 558 (void) sprintf(kstatname, "cmdk%d,error", instance); 559 dadkp->dad_errstats = kstat_create("cmdkerror", instance, 560 kstatname, "device_error", KSTAT_TYPE_NAMED, 561 sizeof (dadk_errstats_t) / sizeof (kstat_named_t), 562 KSTAT_FLAG_PERSISTENT); 563 564 if (!dadkp->dad_errstats) 565 return; 566 567 dep = (dadk_errstats_t *)dadkp->dad_errstats->ks_data; 568 569 kstat_named_init(&dep->dadk_softerrs, 570 "Soft Errors", KSTAT_DATA_UINT32); 571 kstat_named_init(&dep->dadk_harderrs, 572 "Hard Errors", KSTAT_DATA_UINT32); 573 kstat_named_init(&dep->dadk_transerrs, 574 "Transport Errors", KSTAT_DATA_UINT32); 575 kstat_named_init(&dep->dadk_model, 576 "Model", KSTAT_DATA_CHAR); 577 kstat_named_init(&dep->dadk_revision, 578 "Revision", KSTAT_DATA_CHAR); 579 kstat_named_init(&dep->dadk_serial, 580 "Serial No", KSTAT_DATA_CHAR); 581 kstat_named_init(&dep->dadk_capacity, 582 "Size", KSTAT_DATA_ULONGLONG); 583 kstat_named_init(&dep->dadk_rq_media_err, 584 "Media Error", KSTAT_DATA_UINT32); 585 kstat_named_init(&dep->dadk_rq_ntrdy_err, 586 "Device Not Ready", KSTAT_DATA_UINT32); 587 kstat_named_init(&dep->dadk_rq_nodev_err, 588 "No Device", KSTAT_DATA_UINT32); 589 kstat_named_init(&dep->dadk_rq_recov_err, 590 "Recoverable", KSTAT_DATA_UINT32); 591 kstat_named_init(&dep->dadk_rq_illrq_err, 592 "Illegal Request", KSTAT_DATA_UINT32); 593 594 dadkp->dad_errstats->ks_private = dep; 595 dadkp->dad_errstats->ks_update = nulldev; 596 kstat_install(dadkp->dad_errstats); 597 598 /* get model */ 599 dep->dadk_model.value.c[0] = 0; 600 dadk_ioc_string.is_buf = &dep->dadk_model.value.c[0]; 601 dadk_ioc_string.is_size = sizeof (dep->dadk_model.value.c); 602 (void) dadk_ctl_ioctl(dadkp, DIOCTL_GETMODEL, 603 (uintptr_t)&dadk_ioc_string, FKIOCTL | FNATIVE); 604 605 /* get serial */ 606 dep->dadk_serial.value.c[0] = 0; 607 dadk_ioc_string.is_buf = &dep->dadk_serial.value.c[0]; 608 dadk_ioc_string.is_size = sizeof (dep->dadk_serial.value.c); 609 (void) dadk_ctl_ioctl(dadkp, DIOCTL_GETSERIAL, 610 (uintptr_t)&dadk_ioc_string, FKIOCTL | FNATIVE); 611 612 /* Get revision */ 613 dep->dadk_revision.value.c[0] = 0; 614 615 /* Get capacity */ 616 617 dep->dadk_capacity.value.ui64 = 618 (uint64_t)dadkp->dad_logg.g_cap * 619 (uint64_t)dadkp->dad_logg.g_secsiz; 620 } 621 622 623 int 624 dadk_close(opaque_t objp) 625 { 626 struct dadk *dadkp = (struct dadk *)objp; 627 628 if (dadkp->dad_rmb) { 629 (void) dadk_rmb_ioctl(dadkp, DCMD_STOP_MOTOR, 0, 0, 630 DADK_SILENT); 631 (void) dadk_rmb_ioctl(dadkp, DCMD_UNLOCK, 0, 0, DADK_SILENT); 632 } 633 FLC_STOP_KSTAT(dadkp->dad_flcobjp); 634 635 dadk_destroy_errstats(dadkp); 636 637 return (DDI_SUCCESS); 638 } 639 640 static void 641 dadk_destroy_errstats(struct dadk *dadkp) 642 { 643 if (!dadkp->dad_errstats) 644 return; 645 646 kstat_delete(dadkp->dad_errstats); 647 dadkp->dad_errstats = NULL; 648 } 649 650 651 int 652 dadk_strategy(opaque_t objp, struct buf *bp) 653 { 654 struct dadk *dadkp = (struct dadk *)objp; 655 656 if (dadkp->dad_rdonly && !(bp->b_flags & B_READ)) { 657 bioerror(bp, EROFS); 658 return (DDI_FAILURE); 659 } 660 661 if (bp->b_bcount & (dadkp->DAD_SECSIZ-1)) { 662 bioerror(bp, ENXIO); 663 return (DDI_FAILURE); 664 } 665 666 SET_BP_SEC(bp, (LBLK2SEC(GET_BP_SEC(bp), dadkp->dad_blkshf))); 667 mutex_enter(&dadkp->dad_cmd_mutex); 668 dadkp->dad_cmd_count++; 669 mutex_exit(&dadkp->dad_cmd_mutex); 670 FLC_ENQUE(dadkp->dad_flcobjp, bp); 671 672 return (DDI_SUCCESS); 673 } 674 675 int 676 dadk_dump(opaque_t objp, struct buf *bp) 677 { 678 struct dadk *dadkp = (struct dadk *)objp; 679 struct cmpkt *pktp; 680 681 if (dadkp->dad_rdonly) { 682 bioerror(bp, EROFS); 683 return (DDI_FAILURE); 684 } 685 686 if (bp->b_bcount & (dadkp->DAD_SECSIZ-1)) { 687 bioerror(bp, ENXIO); 688 return (DDI_FAILURE); 689 } 690 691 SET_BP_SEC(bp, (LBLK2SEC(GET_BP_SEC(bp), dadkp->dad_blkshf))); 692 693 pktp = dadk_pktprep(dadkp, NULL, bp, dadk_polldone, NULL, NULL); 694 if (!pktp) { 695 cmn_err(CE_WARN, "no resources for dumping"); 696 bioerror(bp, EIO); 697 return (DDI_FAILURE); 698 } 699 pktp->cp_flags |= CPF_NOINTR; 700 701 (void) dadk_ioprep(dadkp, pktp); 702 dadk_transport(dadkp, bp); 703 pktp->cp_byteleft -= pktp->cp_bytexfer; 704 705 while (geterror(bp) == 0 && pktp->cp_byteleft != 0) { 706 (void) dadk_iosetup(dadkp, pktp); 707 dadk_transport(dadkp, bp); 708 pktp->cp_byteleft -= pktp->cp_bytexfer; 709 } 710 711 if (pktp->cp_private) 712 BBH_FREEHANDLE(dadkp->dad_bbhobjp, pktp->cp_private); 713 gda_free(dadkp->dad_ctlobjp, pktp, NULL); 714 return (DDI_SUCCESS); 715 } 716 717 /* ARGSUSED */ 718 int 719 dadk_ioctl(opaque_t objp, dev_t dev, int cmd, intptr_t arg, int flag, 720 cred_t *cred_p, int *rval_p) 721 { 722 struct dadk *dadkp = (struct dadk *)objp; 723 724 switch (cmd) { 725 case DKIOCGETDEF: 726 { 727 struct buf *bp; 728 int err, head; 729 unsigned char *secbuf; 730 STRUCT_DECL(defect_header, adh); 731 732 STRUCT_INIT(adh, flag & FMODELS); 733 734 /* 735 * copyin header .... 736 * yields head number and buffer address 737 */ 738 if (ddi_copyin((caddr_t)arg, STRUCT_BUF(adh), STRUCT_SIZE(adh), 739 flag)) 740 return (EFAULT); 741 head = STRUCT_FGET(adh, head); 742 if (head < 0 || head >= dadkp->dad_phyg.g_head) 743 return (ENXIO); 744 secbuf = kmem_zalloc(NBPSCTR, KM_SLEEP); 745 if (!secbuf) 746 return (ENOMEM); 747 bp = getrbuf(KM_SLEEP); 748 if (!bp) { 749 kmem_free(secbuf, NBPSCTR); 750 return (ENOMEM); 751 } 752 753 bp->b_edev = dev; 754 bp->b_dev = cmpdev(dev); 755 bp->b_flags = B_BUSY; 756 bp->b_resid = 0; 757 bp->b_bcount = NBPSCTR; 758 bp->b_un.b_addr = (caddr_t)secbuf; 759 bp->b_blkno = head; /* I had to put it somwhere! */ 760 bp->b_forw = (struct buf *)dadkp; 761 bp->b_back = (struct buf *)DCMD_GETDEF; 762 763 mutex_enter(&dadkp->dad_cmd_mutex); 764 dadkp->dad_cmd_count++; 765 mutex_exit(&dadkp->dad_cmd_mutex); 766 FLC_ENQUE(dadkp->dad_flcobjp, bp); 767 err = biowait(bp); 768 if (!err) { 769 if (ddi_copyout((caddr_t)secbuf, 770 STRUCT_FGETP(adh, buffer), NBPSCTR, flag)) 771 err = ENXIO; 772 } 773 kmem_free(secbuf, NBPSCTR); 774 freerbuf(bp); 775 return (err); 776 } 777 case DIOCTL_RWCMD: 778 { 779 struct dadkio_rwcmd *rwcmdp; 780 int status, rw; 781 782 /* 783 * copied in by cmdk and, if necessary, converted to the 784 * correct datamodel 785 */ 786 rwcmdp = (struct dadkio_rwcmd *)(intptr_t)arg; 787 788 /* 789 * handle the complex cases here; we pass these 790 * through to the driver, which will queue them and 791 * handle the requests asynchronously. The simpler 792 * cases ,which can return immediately, fail here, and 793 * the request reverts to the dadk_ioctl routine, while 794 * will reroute them directly to the ata driver. 795 */ 796 switch (rwcmdp->cmd) { 797 case DADKIO_RWCMD_READ : 798 /*FALLTHROUGH*/ 799 case DADKIO_RWCMD_WRITE: 800 rw = ((rwcmdp->cmd == DADKIO_RWCMD_WRITE) ? 801 B_WRITE : B_READ); 802 status = dadk_dk_buf_setup(dadkp, 803 (opaque_t)rwcmdp, dev, ((flag &FKIOCTL) ? 804 UIO_SYSSPACE : UIO_USERSPACE), rw); 805 return (status); 806 default: 807 return (EINVAL); 808 } 809 } 810 case DKIOC_UPDATEFW: 811 812 /* 813 * Require PRIV_ALL privilege to invoke DKIOC_UPDATEFW 814 * to protect the firmware update from malicious use 815 */ 816 if (PRIV_POLICY(cred_p, PRIV_ALL, B_FALSE, EPERM, NULL) != 0) 817 return (EPERM); 818 else 819 return (dadk_ctl_ioctl(dadkp, cmd, arg, flag)); 820 821 case DKIOCFLUSHWRITECACHE: 822 { 823 struct buf *bp; 824 int err = 0; 825 struct dk_callback *dkc = (struct dk_callback *)arg; 826 struct cmpkt *pktp; 827 int is_sync = 1; 828 829 mutex_enter(&dadkp->dad_mutex); 830 if (dadkp->dad_noflush || ! dadkp->dad_wce) { 831 err = dadkp->dad_noflush ? ENOTSUP : 0; 832 mutex_exit(&dadkp->dad_mutex); 833 /* 834 * If a callback was requested: a 835 * callback will always be done if the 836 * caller saw the DKIOCFLUSHWRITECACHE 837 * ioctl return 0, and never done if the 838 * caller saw the ioctl return an error. 839 */ 840 if ((flag & FKIOCTL) && dkc != NULL && 841 dkc->dkc_callback != NULL) { 842 (*dkc->dkc_callback)(dkc->dkc_cookie, 843 err); 844 /* 845 * Did callback and reported error. 846 * Since we did a callback, ioctl 847 * should return 0. 848 */ 849 err = 0; 850 } 851 return (err); 852 } 853 mutex_exit(&dadkp->dad_mutex); 854 855 bp = getrbuf(KM_SLEEP); 856 857 bp->b_edev = dev; 858 bp->b_dev = cmpdev(dev); 859 bp->b_flags = B_BUSY; 860 bp->b_resid = 0; 861 bp->b_bcount = 0; 862 SET_BP_SEC(bp, 0); 863 864 if ((flag & FKIOCTL) && dkc != NULL && 865 dkc->dkc_callback != NULL) { 866 struct dk_callback *dkc2 = 867 (struct dk_callback *)kmem_zalloc( 868 sizeof (struct dk_callback), KM_SLEEP); 869 870 bcopy(dkc, dkc2, sizeof (*dkc2)); 871 /* 872 * Borrow b_list to carry private data 873 * to the b_iodone func. 874 */ 875 bp->b_list = (struct buf *)dkc2; 876 bp->b_iodone = dadk_flushdone; 877 is_sync = 0; 878 } 879 880 /* 881 * Setup command pkt 882 * dadk_pktprep() can't fail since DDI_DMA_SLEEP set 883 */ 884 pktp = dadk_pktprep(dadkp, NULL, bp, 885 dadk_iodone, DDI_DMA_SLEEP, NULL); 886 887 pktp->cp_time = DADK_FLUSH_CACHE_TIME; 888 889 *((char *)(pktp->cp_cdbp)) = DCMD_FLUSH_CACHE; 890 pktp->cp_byteleft = 0; 891 pktp->cp_private = NULL; 892 pktp->cp_secleft = 0; 893 pktp->cp_srtsec = -1; 894 pktp->cp_bytexfer = 0; 895 896 CTL_IOSETUP(dadkp->dad_ctlobjp, pktp); 897 898 mutex_enter(&dadkp->dad_cmd_mutex); 899 dadkp->dad_cmd_count++; 900 mutex_exit(&dadkp->dad_cmd_mutex); 901 FLC_ENQUE(dadkp->dad_flcobjp, bp); 902 903 if (is_sync) { 904 err = biowait(bp); 905 freerbuf(bp); 906 } 907 return (err); 908 } 909 default: 910 if (!dadkp->dad_rmb) 911 return (dadk_ctl_ioctl(dadkp, cmd, arg, flag)); 912 } 913 914 switch (cmd) { 915 case CDROMSTOP: 916 return (dadk_rmb_ioctl(dadkp, DCMD_STOP_MOTOR, 0, 917 0, DADK_SILENT)); 918 case CDROMSTART: 919 return (dadk_rmb_ioctl(dadkp, DCMD_START_MOTOR, 0, 920 0, DADK_SILENT)); 921 case DKIOCLOCK: 922 return (dadk_rmb_ioctl(dadkp, DCMD_LOCK, 0, 0, DADK_SILENT)); 923 case DKIOCUNLOCK: 924 return (dadk_rmb_ioctl(dadkp, DCMD_UNLOCK, 0, 0, DADK_SILENT)); 925 case DKIOCEJECT: 926 case CDROMEJECT: 927 { 928 int ret; 929 930 if (ret = dadk_rmb_ioctl(dadkp, DCMD_UNLOCK, 0, 0, 931 DADK_SILENT)) { 932 return (ret); 933 } 934 if (ret = dadk_rmb_ioctl(dadkp, DCMD_EJECT, 0, 0, 935 DADK_SILENT)) { 936 return (ret); 937 } 938 mutex_enter(&dadkp->dad_mutex); 939 dadkp->dad_iostate = DKIO_EJECTED; 940 cv_broadcast(&dadkp->dad_state_cv); 941 mutex_exit(&dadkp->dad_mutex); 942 943 return (0); 944 945 } 946 default: 947 return (ENOTTY); 948 /* 949 * cdrom audio commands 950 */ 951 case CDROMPAUSE: 952 cmd = DCMD_PAUSE; 953 break; 954 case CDROMRESUME: 955 cmd = DCMD_RESUME; 956 break; 957 case CDROMPLAYMSF: 958 cmd = DCMD_PLAYMSF; 959 break; 960 case CDROMPLAYTRKIND: 961 cmd = DCMD_PLAYTRKIND; 962 break; 963 case CDROMREADTOCHDR: 964 cmd = DCMD_READTOCHDR; 965 break; 966 case CDROMREADTOCENTRY: 967 cmd = DCMD_READTOCENT; 968 break; 969 case CDROMVOLCTRL: 970 cmd = DCMD_VOLCTRL; 971 break; 972 case CDROMSUBCHNL: 973 cmd = DCMD_SUBCHNL; 974 break; 975 case CDROMREADMODE2: 976 cmd = DCMD_READMODE2; 977 break; 978 case CDROMREADMODE1: 979 cmd = DCMD_READMODE1; 980 break; 981 case CDROMREADOFFSET: 982 cmd = DCMD_READOFFSET; 983 break; 984 } 985 return (dadk_rmb_ioctl(dadkp, cmd, arg, flag, 0)); 986 } 987 988 int 989 dadk_flushdone(struct buf *bp) 990 { 991 struct dk_callback *dkc = (struct dk_callback *)bp->b_list; 992 993 ASSERT(dkc != NULL && dkc->dkc_callback != NULL); 994 995 (*dkc->dkc_callback)(dkc->dkc_cookie, geterror(bp)); 996 997 kmem_free(dkc, sizeof (*dkc)); 998 freerbuf(bp); 999 return (0); 1000 } 1001 1002 int 1003 dadk_getphygeom(opaque_t objp, struct tgdk_geom *dkgeom_p) 1004 { 1005 struct dadk *dadkp = (struct dadk *)objp; 1006 1007 bcopy((caddr_t)&dadkp->dad_phyg, (caddr_t)dkgeom_p, 1008 sizeof (struct tgdk_geom)); 1009 return (DDI_SUCCESS); 1010 } 1011 1012 int 1013 dadk_getgeom(opaque_t objp, struct tgdk_geom *dkgeom_p) 1014 { 1015 struct dadk *dadkp = (struct dadk *)objp; 1016 bcopy((caddr_t)&dadkp->dad_logg, (caddr_t)dkgeom_p, 1017 sizeof (struct tgdk_geom)); 1018 return (DDI_SUCCESS); 1019 } 1020 1021 int 1022 dadk_setgeom(opaque_t objp, struct tgdk_geom *dkgeom_p) 1023 { 1024 struct dadk *dadkp = (struct dadk *)objp; 1025 1026 dadkp->dad_logg.g_cyl = dkgeom_p->g_cyl; 1027 dadkp->dad_logg.g_head = dkgeom_p->g_head; 1028 dadkp->dad_logg.g_sec = dkgeom_p->g_sec; 1029 dadkp->dad_logg.g_cap = dkgeom_p->g_cap; 1030 return (DDI_SUCCESS); 1031 } 1032 1033 1034 tgdk_iob_handle 1035 dadk_iob_alloc(opaque_t objp, daddr_t blkno, ssize_t xfer, int kmsflg) 1036 { 1037 struct dadk *dadkp = (struct dadk *)objp; 1038 struct buf *bp; 1039 struct tgdk_iob *iobp; 1040 size_t rlen; 1041 1042 iobp = kmem_zalloc(sizeof (*iobp), kmsflg); 1043 if (iobp == NULL) 1044 return (NULL); 1045 if ((bp = getrbuf(kmsflg)) == NULL) { 1046 kmem_free(iobp, sizeof (*iobp)); 1047 return (NULL); 1048 } 1049 1050 iobp->b_psec = LBLK2SEC(blkno, dadkp->dad_blkshf); 1051 iobp->b_pbyteoff = (blkno & ((1<<dadkp->dad_blkshf) - 1)) << SCTRSHFT; 1052 iobp->b_pbytecnt = ((iobp->b_pbyteoff + xfer + dadkp->DAD_SECSIZ - 1) 1053 >> dadkp->dad_secshf) << dadkp->dad_secshf; 1054 1055 bp->b_un.b_addr = 0; 1056 /* 1057 * use i_ddi_mem_alloc() for now until we have an interface to allocate 1058 * memory for DMA which doesn't require a DMA handle. ddi_iopb_alloc() 1059 * is obsolete and we want more flexibility in controlling the DMA 1060 * address constraints.. 1061 */ 1062 if (i_ddi_mem_alloc((dadkp->dad_sd)->sd_dev, &dadk_alloc_attr, 1063 (size_t)iobp->b_pbytecnt, ((kmsflg == KM_SLEEP) ? 1 : 0), 0, NULL, 1064 &bp->b_un.b_addr, &rlen, NULL) != DDI_SUCCESS) { 1065 freerbuf(bp); 1066 kmem_free(iobp, sizeof (*iobp)); 1067 return (NULL); 1068 } 1069 iobp->b_flag |= IOB_BPALLOC | IOB_BPBUFALLOC; 1070 iobp->b_bp = bp; 1071 iobp->b_lblk = blkno; 1072 iobp->b_xfer = xfer; 1073 iobp->b_lblk = blkno; 1074 iobp->b_xfer = xfer; 1075 return (iobp); 1076 } 1077 1078 /* ARGSUSED */ 1079 int 1080 dadk_iob_free(opaque_t objp, struct tgdk_iob *iobp) 1081 { 1082 struct buf *bp; 1083 1084 if (iobp) { 1085 if (iobp->b_bp && (iobp->b_flag & IOB_BPALLOC)) { 1086 bp = iobp->b_bp; 1087 if (bp->b_un.b_addr && (iobp->b_flag & IOB_BPBUFALLOC)) 1088 i_ddi_mem_free((caddr_t)bp->b_un.b_addr, NULL); 1089 freerbuf(bp); 1090 } 1091 kmem_free(iobp, sizeof (*iobp)); 1092 } 1093 return (DDI_SUCCESS); 1094 } 1095 1096 /* ARGSUSED */ 1097 caddr_t 1098 dadk_iob_htoc(opaque_t objp, struct tgdk_iob *iobp) 1099 { 1100 return (iobp->b_bp->b_un.b_addr+iobp->b_pbyteoff); 1101 } 1102 1103 1104 caddr_t 1105 dadk_iob_xfer(opaque_t objp, struct tgdk_iob *iobp, int rw) 1106 { 1107 struct dadk *dadkp = (struct dadk *)objp; 1108 struct buf *bp; 1109 int err; 1110 1111 bp = iobp->b_bp; 1112 if (dadkp->dad_rdonly && !(rw & B_READ)) { 1113 bioerror(bp, EROFS); 1114 return (NULL); 1115 } 1116 1117 bp->b_flags |= (B_BUSY | rw); 1118 bp->b_bcount = iobp->b_pbytecnt; 1119 SET_BP_SEC(bp, iobp->b_psec); 1120 bp->av_back = (struct buf *)0; 1121 bp->b_resid = 0; 1122 1123 /* call flow control */ 1124 mutex_enter(&dadkp->dad_cmd_mutex); 1125 dadkp->dad_cmd_count++; 1126 mutex_exit(&dadkp->dad_cmd_mutex); 1127 FLC_ENQUE(dadkp->dad_flcobjp, bp); 1128 err = biowait(bp); 1129 1130 bp->b_bcount = iobp->b_xfer; 1131 bp->b_flags &= ~(B_DONE|B_BUSY); 1132 1133 if (err) 1134 return (NULL); 1135 1136 return (bp->b_un.b_addr+iobp->b_pbyteoff); 1137 } 1138 1139 static void 1140 dadk_transport(opaque_t com_data, struct buf *bp) 1141 { 1142 struct dadk *dadkp = (struct dadk *)com_data; 1143 1144 if (CTL_TRANSPORT(dadkp->dad_ctlobjp, GDA_BP_PKT(bp)) == 1145 CTL_SEND_SUCCESS) 1146 return; 1147 dadk_restart((void*)GDA_BP_PKT(bp)); 1148 } 1149 1150 static int 1151 dadk_pkt(opaque_t com_data, struct buf *bp, int (*func)(caddr_t), caddr_t arg) 1152 { 1153 struct cmpkt *pktp; 1154 struct dadk *dadkp = (struct dadk *)com_data; 1155 1156 if (GDA_BP_PKT(bp)) 1157 return (DDI_SUCCESS); 1158 1159 pktp = dadk_pktprep(dadkp, NULL, bp, dadk_iodone, func, arg); 1160 if (!pktp) 1161 return (DDI_FAILURE); 1162 1163 return (dadk_ioprep(dadkp, pktp)); 1164 } 1165 1166 /* 1167 * Read, Write preparation 1168 */ 1169 static int 1170 dadk_ioprep(struct dadk *dadkp, struct cmpkt *pktp) 1171 { 1172 struct buf *bp; 1173 1174 bp = pktp->cp_bp; 1175 if (bp->b_forw == (struct buf *)dadkp) 1176 *((char *)(pktp->cp_cdbp)) = (char)(intptr_t)bp->b_back; 1177 1178 else if (bp->b_flags & B_READ) 1179 *((char *)(pktp->cp_cdbp)) = DCMD_READ; 1180 else 1181 *((char *)(pktp->cp_cdbp)) = DCMD_WRITE; 1182 pktp->cp_byteleft = bp->b_bcount; 1183 1184 /* setup the bad block list handle */ 1185 pktp->cp_private = BBH_GETHANDLE(dadkp->dad_bbhobjp, bp); 1186 return (dadk_iosetup(dadkp, pktp)); 1187 } 1188 1189 static int 1190 dadk_iosetup(struct dadk *dadkp, struct cmpkt *pktp) 1191 { 1192 struct buf *bp; 1193 bbh_cookie_t bbhckp; 1194 int seccnt; 1195 1196 seccnt = pktp->cp_bytexfer >> dadkp->dad_secshf; 1197 pktp->cp_secleft -= seccnt; 1198 1199 if (pktp->cp_secleft) { 1200 pktp->cp_srtsec += seccnt; 1201 } else { 1202 /* get the first cookie from the bad block list */ 1203 if (!pktp->cp_private) { 1204 bp = pktp->cp_bp; 1205 pktp->cp_srtsec = GET_BP_SEC(bp); 1206 pktp->cp_secleft = (bp->b_bcount >> dadkp->dad_secshf); 1207 } else { 1208 bbhckp = BBH_HTOC(dadkp->dad_bbhobjp, 1209 pktp->cp_private); 1210 pktp->cp_srtsec = BBH_GETCK_SECTOR(dadkp->dad_bbhobjp, 1211 bbhckp); 1212 pktp->cp_secleft = BBH_GETCK_SECLEN(dadkp->dad_bbhobjp, 1213 bbhckp); 1214 } 1215 } 1216 1217 pktp->cp_bytexfer = pktp->cp_secleft << dadkp->dad_secshf; 1218 1219 if (CTL_IOSETUP(dadkp->dad_ctlobjp, pktp)) { 1220 return (DDI_SUCCESS); 1221 } else { 1222 return (DDI_FAILURE); 1223 } 1224 1225 1226 1227 1228 } 1229 1230 static struct cmpkt * 1231 dadk_pktprep(struct dadk *dadkp, struct cmpkt *in_pktp, struct buf *bp, 1232 void (*cb_func)(struct buf *), int (*func)(caddr_t), caddr_t arg) 1233 { 1234 struct cmpkt *pktp; 1235 1236 pktp = gda_pktprep(dadkp->dad_ctlobjp, in_pktp, (opaque_t)bp, func, 1237 arg); 1238 1239 if (pktp) { 1240 pktp->cp_callback = dadk_pktcb; 1241 pktp->cp_time = DADK_IO_TIME; 1242 pktp->cp_flags = 0; 1243 pktp->cp_iodone = cb_func; 1244 pktp->cp_dev_private = (opaque_t)dadkp; 1245 1246 } 1247 1248 return (pktp); 1249 } 1250 1251 1252 static void 1253 dadk_restart(void *vpktp) 1254 { 1255 struct cmpkt *pktp = (struct cmpkt *)vpktp; 1256 1257 if (dadk_ioretry(pktp, QUE_COMMAND) == JUST_RETURN) 1258 return; 1259 pktp->cp_iodone(pktp->cp_bp); 1260 } 1261 1262 static int 1263 dadk_ioretry(struct cmpkt *pktp, int action) 1264 { 1265 struct buf *bp; 1266 struct dadk *dadkp = PKT2DADK(pktp); 1267 1268 switch (action) { 1269 case QUE_COMMAND: 1270 if (pktp->cp_retry++ < DADK_RETRY_COUNT) { 1271 CTL_IOSETUP(dadkp->dad_ctlobjp, pktp); 1272 if (CTL_TRANSPORT(dadkp->dad_ctlobjp, pktp) == 1273 CTL_SEND_SUCCESS) { 1274 return (JUST_RETURN); 1275 } 1276 gda_log(dadkp->dad_sd->sd_dev, dadk_name, 1277 CE_WARN, "transport of command fails\n"); 1278 } else 1279 gda_log(dadkp->dad_sd->sd_dev, 1280 dadk_name, CE_WARN, 1281 "exceeds maximum number of retries\n"); 1282 bioerror(pktp->cp_bp, ENXIO); 1283 /*FALLTHROUGH*/ 1284 case COMMAND_DONE_ERROR: 1285 bp = pktp->cp_bp; 1286 bp->b_resid += pktp->cp_byteleft - pktp->cp_bytexfer + 1287 pktp->cp_resid; 1288 if (geterror(bp) == 0) { 1289 if ((*((char *)(pktp->cp_cdbp)) == DCMD_FLUSH_CACHE) && 1290 (pktp->cp_dev_private == (opaque_t)dadkp) && 1291 ((int)(*(char *)pktp->cp_scbp) == DERR_ABORT)) { 1292 /* 1293 * Flag "unimplemented" responses for 1294 * DCMD_FLUSH_CACHE as ENOTSUP 1295 */ 1296 bioerror(bp, ENOTSUP); 1297 mutex_enter(&dadkp->dad_mutex); 1298 dadkp->dad_noflush = 1; 1299 mutex_exit(&dadkp->dad_mutex); 1300 } else { 1301 bioerror(bp, EIO); 1302 } 1303 } 1304 /*FALLTHROUGH*/ 1305 case COMMAND_DONE: 1306 default: 1307 return (COMMAND_DONE); 1308 } 1309 } 1310 1311 1312 static void 1313 dadk_pktcb(struct cmpkt *pktp) 1314 { 1315 int action; 1316 struct dadkio_rwcmd *rwcmdp; 1317 1318 rwcmdp = (struct dadkio_rwcmd *)pktp->cp_passthru; /* ioctl packet */ 1319 1320 if (pktp->cp_reason == CPS_SUCCESS) { 1321 if (rwcmdp && (rwcmdp != (opaque_t)DADK_SILENT)) 1322 rwcmdp->status.status = DADKIO_STAT_NO_ERROR; 1323 pktp->cp_iodone(pktp->cp_bp); 1324 return; 1325 } 1326 1327 if (rwcmdp && (rwcmdp != (opaque_t)DADK_SILENT)) { 1328 if (pktp->cp_reason == CPS_CHKERR) 1329 dadk_recorderr(pktp, rwcmdp); 1330 dadk_iodone(pktp->cp_bp); 1331 return; 1332 } 1333 1334 if (pktp->cp_reason == CPS_CHKERR) 1335 action = dadk_chkerr(pktp); 1336 else 1337 action = COMMAND_DONE_ERROR; 1338 1339 if (action == JUST_RETURN) 1340 return; 1341 1342 /* 1343 * If we are panicking don't retry the command 1344 * just fail it so we can go down completing all 1345 * of the buffers. 1346 */ 1347 if (ddi_in_panic() && action == QUE_COMMAND) 1348 action = COMMAND_DONE_ERROR; 1349 1350 if (action != COMMAND_DONE) { 1351 if ((dadk_ioretry(pktp, action)) == JUST_RETURN) 1352 return; 1353 } 1354 pktp->cp_iodone(pktp->cp_bp); 1355 } 1356 1357 1358 1359 static struct dadkio_derr dadk_errtab[] = { 1360 {COMMAND_DONE, GDA_INFORMATIONAL}, /* 0 DERR_SUCCESS */ 1361 {QUE_COMMAND, GDA_FATAL}, /* 1 DERR_AMNF */ 1362 {QUE_COMMAND, GDA_FATAL}, /* 2 DERR_TKONF */ 1363 {COMMAND_DONE_ERROR, GDA_INFORMATIONAL}, /* 3 DERR_ABORT */ 1364 {QUE_COMMAND, GDA_RETRYABLE}, /* 4 DERR_DWF */ 1365 {QUE_COMMAND, GDA_FATAL}, /* 5 DERR_IDNF */ 1366 {JUST_RETURN, GDA_INFORMATIONAL}, /* 6 DERR_BUSY */ 1367 {QUE_COMMAND, GDA_FATAL}, /* 7 DERR_UNC */ 1368 {QUE_COMMAND, GDA_RETRYABLE}, /* 8 DERR_BBK */ 1369 {COMMAND_DONE_ERROR, GDA_FATAL}, /* 9 DERR_INVCDB */ 1370 {COMMAND_DONE_ERROR, GDA_FATAL}, /* 10 DERR_HARD */ 1371 {COMMAND_DONE_ERROR, GDA_FATAL}, /* 11 DERR_ILI */ 1372 {COMMAND_DONE_ERROR, GDA_FATAL}, /* 12 DERR_EOM */ 1373 {COMMAND_DONE, GDA_INFORMATIONAL}, /* 13 DERR_MCR */ 1374 {COMMAND_DONE, GDA_INFORMATIONAL}, /* 14 DERR_RECOVER */ 1375 {COMMAND_DONE_ERROR, GDA_FATAL}, /* 15 DERR_NOTREADY */ 1376 {QUE_COMMAND, GDA_RETRYABLE}, /* 16 DERR_MEDIUM */ 1377 {COMMAND_DONE_ERROR, GDA_FATAL}, /* 17 DERR_HW */ 1378 {COMMAND_DONE, GDA_FATAL}, /* 18 DERR_ILL */ 1379 {COMMAND_DONE, GDA_FATAL}, /* 19 DERR_UNIT_ATTN */ 1380 {COMMAND_DONE_ERROR, GDA_FATAL}, /* 20 DERR_DATA_PROT */ 1381 {COMMAND_DONE_ERROR, GDA_FATAL}, /* 21 DERR_MISCOMPARE */ 1382 {QUE_COMMAND, GDA_RETRYABLE}, /* 22 DERR_ICRC */ 1383 {COMMAND_DONE_ERROR, GDA_FATAL}, /* 23 DERR_RESV */ 1384 }; 1385 1386 static int 1387 dadk_chkerr(struct cmpkt *pktp) 1388 { 1389 daddr_t err_blkno; 1390 struct dadk *dadkp = PKT2DADK(pktp); 1391 dadk_errstats_t *dep; 1392 int scb = *(char *)pktp->cp_scbp; 1393 1394 if (scb == DERR_SUCCESS) { 1395 if (pktp->cp_retry != 0 && dadkp->dad_errstats != NULL) { 1396 dep = (dadk_errstats_t *) 1397 dadkp->dad_errstats->ks_data; 1398 dep->dadk_rq_recov_err.value.ui32++; 1399 } 1400 return (COMMAND_DONE); 1401 } 1402 1403 if (pktp->cp_retry) { 1404 err_blkno = pktp->cp_srtsec + ((pktp->cp_bytexfer - 1405 pktp->cp_resid) >> dadkp->dad_secshf); 1406 } else 1407 err_blkno = -1; 1408 1409 if (dadkp->dad_errstats != NULL) { 1410 dep = (dadk_errstats_t *)dadkp->dad_errstats->ks_data; 1411 1412 switch (dadk_errtab[scb].d_severity) { 1413 case GDA_RETRYABLE: 1414 dep->dadk_softerrs.value.ui32++; 1415 break; 1416 1417 case GDA_FATAL: 1418 dep->dadk_harderrs.value.ui32++; 1419 break; 1420 1421 default: 1422 break; 1423 } 1424 1425 switch (scb) { 1426 case DERR_INVCDB: 1427 case DERR_ILI: 1428 case DERR_EOM: 1429 case DERR_HW: 1430 case DERR_ICRC: 1431 dep->dadk_transerrs.value.ui32++; 1432 break; 1433 1434 case DERR_AMNF: 1435 case DERR_TKONF: 1436 case DERR_DWF: 1437 case DERR_BBK: 1438 case DERR_UNC: 1439 case DERR_HARD: 1440 case DERR_MEDIUM: 1441 case DERR_DATA_PROT: 1442 case DERR_MISCOMP: 1443 dep->dadk_rq_media_err.value.ui32++; 1444 break; 1445 1446 case DERR_NOTREADY: 1447 dep->dadk_rq_ntrdy_err.value.ui32++; 1448 break; 1449 1450 case DERR_IDNF: 1451 case DERR_UNIT_ATTN: 1452 dep->dadk_rq_nodev_err.value.ui32++; 1453 break; 1454 1455 case DERR_ILL: 1456 case DERR_RESV: 1457 dep->dadk_rq_illrq_err.value.ui32++; 1458 break; 1459 1460 default: 1461 break; 1462 } 1463 } 1464 1465 /* if attempting to read a sector from a cdrom audio disk */ 1466 if ((dadkp->dad_cdrom) && 1467 (*((char *)(pktp->cp_cdbp)) == DCMD_READ) && 1468 (scb == DERR_ILL)) { 1469 return (COMMAND_DONE); 1470 } 1471 if (pktp->cp_passthru == NULL) { 1472 gda_errmsg(dadkp->dad_sd, pktp, dadk_name, 1473 dadk_errtab[scb].d_severity, pktp->cp_srtsec, 1474 err_blkno, dadk_cmds, dadk_sense); 1475 } 1476 1477 if (scb == DERR_BUSY) { 1478 (void) timeout(dadk_restart, (void *)pktp, DADK_BSY_TIMEOUT); 1479 } 1480 1481 return (dadk_errtab[scb].d_action); 1482 } 1483 1484 static void 1485 dadk_recorderr(struct cmpkt *pktp, struct dadkio_rwcmd *rwcmdp) 1486 { 1487 struct dadk *dadkp; 1488 int scb; 1489 1490 dadkp = PKT2DADK(pktp); 1491 scb = (int)(*(char *)pktp->cp_scbp); 1492 1493 1494 rwcmdp->status.failed_blk = rwcmdp->blkaddr + 1495 ((pktp->cp_bytexfer - pktp->cp_resid) >> dadkp->dad_secshf); 1496 1497 rwcmdp->status.resid = pktp->cp_bp->b_resid + 1498 pktp->cp_byteleft - pktp->cp_bytexfer + pktp->cp_resid; 1499 switch ((int)(* (char *)pktp->cp_scbp)) { 1500 case DERR_AMNF: 1501 case DERR_ABORT: 1502 rwcmdp->status.status = DADKIO_STAT_ILLEGAL_REQUEST; 1503 break; 1504 case DERR_DWF: 1505 case DERR_IDNF: 1506 rwcmdp->status.status = DADKIO_STAT_ILLEGAL_ADDRESS; 1507 break; 1508 case DERR_TKONF: 1509 case DERR_UNC: 1510 case DERR_BBK: 1511 rwcmdp->status.status = DADKIO_STAT_MEDIUM_ERROR; 1512 rwcmdp->status.failed_blk_is_valid = 1; 1513 rwcmdp->status.resid = 0; 1514 break; 1515 case DERR_BUSY: 1516 rwcmdp->status.status = DADKIO_STAT_NOT_READY; 1517 break; 1518 case DERR_INVCDB: 1519 case DERR_HARD: 1520 rwcmdp->status.status = DADKIO_STAT_HARDWARE_ERROR; 1521 break; 1522 case DERR_ICRC: 1523 default: 1524 rwcmdp->status.status = DADKIO_STAT_NOT_SUPPORTED; 1525 } 1526 1527 if (rwcmdp->flags & DADKIO_FLAG_SILENT) 1528 return; 1529 gda_errmsg(dadkp->dad_sd, pktp, dadk_name, dadk_errtab[scb].d_severity, 1530 rwcmdp->blkaddr, rwcmdp->status.failed_blk, 1531 dadk_cmds, dadk_sense); 1532 } 1533 1534 /*ARGSUSED*/ 1535 static void 1536 dadk_polldone(struct buf *bp) 1537 { 1538 struct cmpkt *pktp; 1539 struct dadk *dadkp; 1540 1541 pktp = GDA_BP_PKT(bp); 1542 dadkp = PKT2DADK(pktp); 1543 mutex_enter(&dadkp->dad_cmd_mutex); 1544 dadkp->dad_cmd_count--; 1545 mutex_exit(&dadkp->dad_cmd_mutex); 1546 } 1547 1548 static void 1549 dadk_iodone(struct buf *bp) 1550 { 1551 struct cmpkt *pktp; 1552 struct dadk *dadkp; 1553 1554 pktp = GDA_BP_PKT(bp); 1555 dadkp = PKT2DADK(pktp); 1556 1557 /* check for all iodone */ 1558 pktp->cp_byteleft -= pktp->cp_bytexfer; 1559 if (geterror(bp) == 0 && pktp->cp_byteleft != 0) { 1560 pktp->cp_retry = 0; 1561 (void) dadk_iosetup(dadkp, pktp); 1562 1563 1564 /* transport the next one */ 1565 if (CTL_TRANSPORT(dadkp->dad_ctlobjp, pktp) == CTL_SEND_SUCCESS) 1566 return; 1567 if ((dadk_ioretry(pktp, QUE_COMMAND)) == JUST_RETURN) 1568 return; 1569 } 1570 1571 /* start next one */ 1572 FLC_DEQUE(dadkp->dad_flcobjp, bp); 1573 1574 /* free pkt */ 1575 if (pktp->cp_private) 1576 BBH_FREEHANDLE(dadkp->dad_bbhobjp, pktp->cp_private); 1577 gda_free(dadkp->dad_ctlobjp, pktp, NULL); 1578 mutex_enter(&dadkp->dad_cmd_mutex); 1579 dadkp->dad_cmd_count--; 1580 mutex_exit(&dadkp->dad_cmd_mutex); 1581 biodone(bp); 1582 } 1583 1584 int 1585 dadk_check_media(opaque_t objp, int *state) 1586 { 1587 struct dadk *dadkp = (struct dadk *)objp; 1588 1589 if (!dadkp->dad_rmb) { 1590 return (ENXIO); 1591 } 1592 #ifdef DADK_DEBUG 1593 if (dadk_debug & DSTATE) 1594 PRF("dadk_check_media: user state %x disk state %x\n", 1595 *state, dadkp->dad_iostate); 1596 #endif 1597 /* 1598 * If state already changed just return 1599 */ 1600 if (*state != dadkp->dad_iostate) { 1601 *state = dadkp->dad_iostate; 1602 return (0); 1603 } 1604 1605 /* 1606 * Startup polling on thread state 1607 */ 1608 mutex_enter(&dadkp->dad_mutex); 1609 if (dadkp->dad_thread_cnt == 0) { 1610 /* 1611 * One thread per removable dadk device 1612 */ 1613 (void) thread_create(NULL, 0, dadk_watch_thread, dadkp, 0, &p0, 1614 TS_RUN, v.v_maxsyspri - 2); 1615 } 1616 dadkp->dad_thread_cnt++; 1617 1618 /* 1619 * Wait for state to change 1620 */ 1621 do { 1622 if (cv_wait_sig(&dadkp->dad_state_cv, &dadkp->dad_mutex) == 0) { 1623 dadkp->dad_thread_cnt--; 1624 mutex_exit(&dadkp->dad_mutex); 1625 return (EINTR); 1626 } 1627 } while (*state == dadkp->dad_iostate); 1628 *state = dadkp->dad_iostate; 1629 dadkp->dad_thread_cnt--; 1630 mutex_exit(&dadkp->dad_mutex); 1631 return (0); 1632 } 1633 1634 1635 #define MEDIA_ACCESS_DELAY 2000000 1636 1637 static void 1638 dadk_watch_thread(struct dadk *dadkp) 1639 { 1640 enum dkio_state state; 1641 int interval; 1642 1643 interval = drv_usectohz(dadk_check_media_time); 1644 1645 do { 1646 if (dadk_rmb_ioctl(dadkp, DCMD_GET_STATE, (intptr_t)&state, 0, 1647 DADK_SILENT)) { 1648 /* 1649 * Assume state remained the same 1650 */ 1651 state = dadkp->dad_iostate; 1652 } 1653 1654 /* 1655 * now signal the waiting thread if this is *not* the 1656 * specified state; 1657 * delay the signal if the state is DKIO_INSERTED 1658 * to allow the target to recover 1659 */ 1660 if (state != dadkp->dad_iostate) { 1661 1662 dadkp->dad_iostate = state; 1663 if (state == DKIO_INSERTED) { 1664 /* 1665 * delay the signal to give the drive a chance 1666 * to do what it apparently needs to do 1667 */ 1668 (void) timeout((void(*)(void *))cv_broadcast, 1669 (void *)&dadkp->dad_state_cv, 1670 drv_usectohz((clock_t)MEDIA_ACCESS_DELAY)); 1671 } else { 1672 cv_broadcast(&dadkp->dad_state_cv); 1673 } 1674 } 1675 delay(interval); 1676 } while (dadkp->dad_thread_cnt); 1677 } 1678 1679 int 1680 dadk_inquiry(opaque_t objp, opaque_t *inqpp) 1681 { 1682 struct dadk *dadkp = (struct dadk *)objp; 1683 struct scsi_inquiry **sinqpp = (struct scsi_inquiry **)inqpp; 1684 1685 if (dadkp && dadkp->dad_sd && dadkp->dad_sd->sd_inq) { 1686 *sinqpp = dadkp->dad_sd->sd_inq; 1687 return (DDI_SUCCESS); 1688 } 1689 1690 return (DDI_FAILURE); 1691 } 1692 1693 static int 1694 dadk_rmb_ioctl(struct dadk *dadkp, int cmd, intptr_t arg, int flags, int silent) 1695 1696 { 1697 struct buf *bp; 1698 int err; 1699 struct cmpkt *pktp; 1700 1701 if ((bp = getrbuf(KM_SLEEP)) == NULL) { 1702 return (ENOMEM); 1703 } 1704 pktp = dadk_pktprep(dadkp, NULL, bp, dadk_rmb_iodone, NULL, NULL); 1705 if (!pktp) { 1706 freerbuf(bp); 1707 return (ENOMEM); 1708 } 1709 bp->b_back = (struct buf *)arg; 1710 bp->b_forw = (struct buf *)dadkp->dad_flcobjp; 1711 pktp->cp_passthru = (opaque_t)(intptr_t)silent; 1712 1713 err = dadk_ctl_ioctl(dadkp, cmd, (uintptr_t)pktp, flags); 1714 freerbuf(bp); 1715 gda_free(dadkp->dad_ctlobjp, pktp, NULL); 1716 return (err); 1717 1718 1719 } 1720 1721 static void 1722 dadk_rmb_iodone(struct buf *bp) 1723 { 1724 struct cmpkt *pktp; 1725 struct dadk *dadkp; 1726 1727 pktp = GDA_BP_PKT(bp); 1728 dadkp = PKT2DADK(pktp); 1729 1730 bp->b_flags &= ~(B_DONE|B_BUSY); 1731 1732 /* Start next one */ 1733 FLC_DEQUE(dadkp->dad_flcobjp, bp); 1734 1735 mutex_enter(&dadkp->dad_cmd_mutex); 1736 dadkp->dad_cmd_count--; 1737 mutex_exit(&dadkp->dad_cmd_mutex); 1738 biodone(bp); 1739 } 1740 1741 static int 1742 dadk_dk_buf_setup(struct dadk *dadkp, opaque_t *cmdp, dev_t dev, 1743 enum uio_seg dataspace, int rw) 1744 { 1745 struct dadkio_rwcmd *rwcmdp = (struct dadkio_rwcmd *)cmdp; 1746 struct buf *bp; 1747 struct iovec aiov; 1748 struct uio auio; 1749 struct uio *uio = &auio; 1750 int status; 1751 1752 bp = getrbuf(KM_SLEEP); 1753 1754 bp->av_forw = bp->b_forw = (struct buf *)dadkp; 1755 bp->b_back = (struct buf *)rwcmdp; /* ioctl packet */ 1756 1757 bzero((caddr_t)&auio, sizeof (struct uio)); 1758 bzero((caddr_t)&aiov, sizeof (struct iovec)); 1759 aiov.iov_base = rwcmdp->bufaddr; 1760 aiov.iov_len = rwcmdp->buflen; 1761 uio->uio_iov = &aiov; 1762 1763 uio->uio_iovcnt = 1; 1764 uio->uio_resid = rwcmdp->buflen; 1765 uio->uio_segflg = dataspace; 1766 1767 /* Let physio do the rest... */ 1768 status = physio(dadk_dk_strategy, bp, dev, rw, dadkmin, uio); 1769 1770 freerbuf(bp); 1771 return (status); 1772 1773 } 1774 1775 /* Do not let a user gendisk request get too big or */ 1776 /* else we could use to many resources. */ 1777 1778 static void 1779 dadkmin(struct buf *bp) 1780 { 1781 if (bp->b_bcount > dadk_dk_maxphys) 1782 bp->b_bcount = dadk_dk_maxphys; 1783 } 1784 1785 static int 1786 dadk_dk_strategy(struct buf *bp) 1787 { 1788 dadk_dk((struct dadk *)bp->av_forw, (struct dadkio_rwcmd *)bp->b_back, 1789 bp); 1790 return (0); 1791 } 1792 1793 static void 1794 dadk_dk(struct dadk *dadkp, struct dadkio_rwcmd *rwcmdp, struct buf *bp) 1795 { 1796 struct cmpkt *pktp; 1797 1798 pktp = dadk_pktprep(dadkp, NULL, bp, dadk_iodone, NULL, NULL); 1799 if (!pktp) { 1800 bioerror(bp, ENOMEM); 1801 biodone(bp); 1802 return; 1803 } 1804 1805 pktp->cp_passthru = rwcmdp; 1806 1807 (void) dadk_ioprep(dadkp, pktp); 1808 1809 mutex_enter(&dadkp->dad_cmd_mutex); 1810 dadkp->dad_cmd_count++; 1811 mutex_exit(&dadkp->dad_cmd_mutex); 1812 FLC_ENQUE(dadkp->dad_flcobjp, bp); 1813 } 1814 1815 /* 1816 * There is no existing way to notify cmdk module 1817 * when the command completed, so add this function 1818 * to calculate how many on-going commands. 1819 */ 1820 int 1821 dadk_getcmds(opaque_t objp) 1822 { 1823 struct dadk *dadkp = (struct dadk *)objp; 1824 int count; 1825 1826 mutex_enter(&dadkp->dad_cmd_mutex); 1827 count = dadkp->dad_cmd_count; 1828 mutex_exit(&dadkp->dad_cmd_mutex); 1829 return (count); 1830 } 1831 1832 /* 1833 * this function was used to calc the cmd for CTL_IOCTL 1834 */ 1835 static int 1836 dadk_ctl_ioctl(struct dadk *dadkp, uint32_t cmd, uintptr_t arg, int flag) 1837 { 1838 int error; 1839 mutex_enter(&dadkp->dad_cmd_mutex); 1840 dadkp->dad_cmd_count++; 1841 mutex_exit(&dadkp->dad_cmd_mutex); 1842 error = CTL_IOCTL(dadkp->dad_ctlobjp, cmd, arg, flag); 1843 mutex_enter(&dadkp->dad_cmd_mutex); 1844 dadkp->dad_cmd_count--; 1845 mutex_exit(&dadkp->dad_cmd_mutex); 1846 return (error); 1847 } 1848