1 /* $NetBSD: sd.c,v 1.102 1996/07/05 16:19:16 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Charles M. Hannum. 17 * 4. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Originally written by Julian Elischer (julian@dialix.oz.au) 34 * for TRW Financial Systems for use under the MACH(2.5) operating system. 35 * 36 * TRW Financial Systems, in accordance with their agreement with Carnegie 37 * Mellon University, makes this software available to CMU to distribute 38 * or use in any manner that they see fit as long as this message is kept with 39 * the software. For this reason TFS also grants any other persons or 40 * organisations permission to use or modify this software. 41 * 42 * TFS supplies this software to be publicly redistributed 43 * on the understanding that TFS is not responsible for the correct 44 * functioning of this software in any circumstances. 45 * 46 * Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992 47 */ 48 49 #include <sys/types.h> 50 #include <sys/param.h> 51 #include <sys/systm.h> 52 #include <sys/kernel.h> 53 #include <sys/file.h> 54 #include <sys/stat.h> 55 #include <sys/ioctl.h> 56 #include <sys/buf.h> 57 #include <sys/uio.h> 58 #include <sys/malloc.h> 59 #include <sys/errno.h> 60 #include <sys/device.h> 61 #include <sys/disklabel.h> 62 #include <sys/disk.h> 63 #include <sys/proc.h> 64 #include <sys/conf.h> 65 66 #include <scsi/scsi_all.h> 67 #include <scsi/scsi_disk.h> 68 #include <scsi/scsiconf.h> 69 70 #define SDOUTSTANDING 4 71 #define SDRETRIES 4 72 73 #define SDUNIT(dev) DISKUNIT(dev) 74 #define SDPART(dev) DISKPART(dev) 75 #define MAKESDDEV(maj, unit, part) MAKEDISKDEV(maj, unit, part) 76 77 #define SDLABELDEV(dev) (MAKESDDEV(major(dev), SDUNIT(dev), RAW_PART)) 78 79 struct sd_softc { 80 struct device sc_dev; 81 struct disk sc_dk; 82 83 int flags; 84 #define SDF_LOCKED 0x01 85 #define SDF_WANTED 0x02 86 #define SDF_WLABEL 0x04 /* label is writable */ 87 #define SDF_LABELLING 0x08 /* writing label */ 88 #define SDF_ANCIENT 0x10 /* disk is ancient; for minphys */ 89 struct scsi_link *sc_link; /* contains our targ, lun, etc. */ 90 struct disk_parms { 91 u_char heads; /* number of heads */ 92 u_short cyls; /* number of cylinders */ 93 u_char sectors; /* number of sectors/track */ 94 int blksize; /* number of bytes/sector */ 95 u_long disksize; /* total number sectors */ 96 } params; 97 struct buf buf_queue; 98 }; 99 100 struct scsi_mode_sense_data { 101 struct scsi_mode_header header; 102 struct scsi_blk_desc blk_desc; 103 union disk_pages pages; 104 } scsi_sense; 105 106 int sdmatch __P((struct device *, void *, void *)); 107 void sdattach __P((struct device *, struct device *, void *)); 108 int sdlock __P((struct sd_softc *)); 109 void sdunlock __P((struct sd_softc *)); 110 void sdminphys __P((struct buf *)); 111 void sdgetdisklabel __P((struct sd_softc *)); 112 void sdstart __P((void *)); 113 int sddone __P((struct scsi_xfer *, int)); 114 int sd_reassign_blocks __P((struct sd_softc *, u_long)); 115 int sd_get_parms __P((struct sd_softc *, int)); 116 static int sd_mode_sense __P((struct sd_softc *, struct scsi_mode_sense_data *, 117 int, int)); 118 119 struct cfattach sd_ca = { 120 sizeof(struct sd_softc), sdmatch, sdattach 121 }; 122 123 struct cfdriver sd_cd = { 124 NULL, "sd", DV_DISK 125 }; 126 127 struct dkdriver sddkdriver = { sdstrategy }; 128 129 struct scsi_device sd_switch = { 130 NULL, /* Use default error handler */ 131 sdstart, /* have a queue, served by this */ 132 NULL, /* have no async handler */ 133 sddone, /* deal with stats at interrupt time */ 134 }; 135 136 struct scsi_inquiry_pattern sd_patterns[] = { 137 {T_DIRECT, T_FIXED, 138 "", "", ""}, 139 {T_DIRECT, T_REMOV, 140 "", "", ""}, 141 {T_OPTICAL, T_FIXED, 142 "", "", ""}, 143 {T_OPTICAL, T_REMOV, 144 "", "", ""}, 145 }; 146 147 int 148 sdmatch(parent, match, aux) 149 struct device *parent; 150 void *match, *aux; 151 { 152 struct scsibus_attach_args *sa = aux; 153 int priority; 154 155 (void)scsi_inqmatch(sa->sa_inqbuf, 156 (caddr_t)sd_patterns, sizeof(sd_patterns)/sizeof(sd_patterns[0]), 157 sizeof(sd_patterns[0]), &priority); 158 return (priority); 159 } 160 161 /* 162 * The routine called by the low level scsi routine when it discovers 163 * a device suitable for this driver. 164 */ 165 void 166 sdattach(parent, self, aux) 167 struct device *parent, *self; 168 void *aux; 169 { 170 struct sd_softc *sd = (void *)self; 171 struct disk_parms *dp = &sd->params; 172 struct scsibus_attach_args *sa = aux; 173 struct scsi_link *sc_link = sa->sa_sc_link; 174 175 SC_DEBUG(sc_link, SDEV_DB2, ("sdattach: ")); 176 177 /* 178 * Store information needed to contact our base driver 179 */ 180 sd->sc_link = sc_link; 181 sc_link->device = &sd_switch; 182 sc_link->device_softc = sd; 183 if (sc_link->openings > SDOUTSTANDING) 184 sc_link->openings = SDOUTSTANDING; 185 186 /* 187 * Initialize and attach the disk structure. 188 */ 189 sd->sc_dk.dk_driver = &sddkdriver; 190 sd->sc_dk.dk_name = sd->sc_dev.dv_xname; 191 disk_attach(&sd->sc_dk); 192 193 #if !defined(i386) 194 dk_establish(&sd->sc_dk, &sd->sc_dev); /* XXX */ 195 #endif 196 197 /* 198 * Note if this device is ancient. This is used in sdminphys(). 199 */ 200 if ((sa->sa_inqbuf->version & SID_ANSII) == 0) 201 sd->flags |= SDF_ANCIENT; 202 203 /* 204 * Use the subdriver to request information regarding 205 * the drive. We cannot use interrupts yet, so the 206 * request must specify this. 207 */ 208 printf("\n"); 209 printf("%s: ", sd->sc_dev.dv_xname); 210 if (scsi_start(sd->sc_link, SSS_START, 211 SCSI_AUTOCONF | SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE | SCSI_SILENT) || 212 sd_get_parms(sd, SCSI_AUTOCONF) != 0) 213 printf("drive offline\n"); 214 else 215 printf("%ldMB, %d cyl, %d head, %d sec, %d bytes/sec\n", 216 dp->disksize / (1048576 / dp->blksize), dp->cyls, 217 dp->heads, dp->sectors, dp->blksize); 218 } 219 220 /* 221 * Wait interruptibly for an exclusive lock. 222 * 223 * XXX 224 * Several drivers do this; it should be abstracted and made MP-safe. 225 */ 226 int 227 sdlock(sd) 228 struct sd_softc *sd; 229 { 230 int error; 231 232 while ((sd->flags & SDF_LOCKED) != 0) { 233 sd->flags |= SDF_WANTED; 234 if ((error = tsleep(sd, PRIBIO | PCATCH, "sdlck", 0)) != 0) 235 return error; 236 } 237 sd->flags |= SDF_LOCKED; 238 return 0; 239 } 240 241 /* 242 * Unlock and wake up any waiters. 243 */ 244 void 245 sdunlock(sd) 246 struct sd_softc *sd; 247 { 248 249 sd->flags &= ~SDF_LOCKED; 250 if ((sd->flags & SDF_WANTED) != 0) { 251 sd->flags &= ~SDF_WANTED; 252 wakeup(sd); 253 } 254 } 255 256 /* 257 * open the device. Make sure the partition info is a up-to-date as can be. 258 */ 259 int 260 sdopen(dev, flag, fmt, p) 261 dev_t dev; 262 int flag, fmt; 263 struct proc *p; 264 { 265 struct sd_softc *sd; 266 struct scsi_link *sc_link; 267 int unit, part; 268 int error; 269 270 unit = SDUNIT(dev); 271 if (unit >= sd_cd.cd_ndevs) 272 return ENXIO; 273 sd = sd_cd.cd_devs[unit]; 274 if (!sd) 275 return ENXIO; 276 277 sc_link = sd->sc_link; 278 279 SC_DEBUG(sc_link, SDEV_DB1, 280 ("sdopen: dev=0x%x (unit %d (of %d), partition %d)\n", dev, unit, 281 sd_cd.cd_ndevs, SDPART(dev))); 282 283 if ((error = sdlock(sd)) != 0) 284 return error; 285 286 if (sd->sc_dk.dk_openmask != 0) { 287 /* 288 * If any partition is open, but the disk has been invalidated, 289 * disallow further opens. 290 */ 291 if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) { 292 error = EIO; 293 goto bad3; 294 } 295 } else { 296 /* Check that it is still responding and ok. */ 297 error = scsi_test_unit_ready(sc_link, 298 SCSI_IGNORE_ILLEGAL_REQUEST | 299 SCSI_IGNORE_MEDIA_CHANGE | 300 SCSI_IGNORE_NOT_READY); 301 if (error) 302 goto bad3; 303 304 /* Start the pack spinning if necessary. */ 305 error = scsi_start(sc_link, SSS_START, 306 SCSI_IGNORE_ILLEGAL_REQUEST | 307 SCSI_IGNORE_MEDIA_CHANGE | SCSI_SILENT); 308 if (error) 309 goto bad3; 310 311 sc_link->flags |= SDEV_OPEN; 312 313 /* Lock the pack in. */ 314 error = scsi_prevent(sc_link, PR_PREVENT, 315 SCSI_IGNORE_ILLEGAL_REQUEST | 316 SCSI_IGNORE_MEDIA_CHANGE); 317 if (error) 318 goto bad; 319 320 if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) { 321 sc_link->flags |= SDEV_MEDIA_LOADED; 322 323 /* Load the physical device parameters. */ 324 if (sd_get_parms(sd, 0) != 0) { 325 error = ENXIO; 326 goto bad2; 327 } 328 SC_DEBUG(sc_link, SDEV_DB3, ("Params loaded ")); 329 330 /* Load the partition info if not already loaded. */ 331 sdgetdisklabel(sd); 332 SC_DEBUG(sc_link, SDEV_DB3, ("Disklabel loaded ")); 333 } 334 } 335 336 part = SDPART(dev); 337 338 /* Check that the partition exists. */ 339 if (part != RAW_PART && 340 (part >= sd->sc_dk.dk_label->d_npartitions || 341 sd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) { 342 error = ENXIO; 343 goto bad; 344 } 345 346 /* Insure only one open at a time. */ 347 switch (fmt) { 348 case S_IFCHR: 349 sd->sc_dk.dk_copenmask |= (1 << part); 350 break; 351 case S_IFBLK: 352 sd->sc_dk.dk_bopenmask |= (1 << part); 353 break; 354 } 355 sd->sc_dk.dk_openmask = sd->sc_dk.dk_copenmask | sd->sc_dk.dk_bopenmask; 356 357 SC_DEBUG(sc_link, SDEV_DB3, ("open complete\n")); 358 sdunlock(sd); 359 return 0; 360 361 bad2: 362 sc_link->flags &= ~SDEV_MEDIA_LOADED; 363 364 bad: 365 if (sd->sc_dk.dk_openmask == 0) { 366 scsi_prevent(sc_link, PR_ALLOW, 367 SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE); 368 sc_link->flags &= ~SDEV_OPEN; 369 } 370 371 bad3: 372 sdunlock(sd); 373 return error; 374 } 375 376 /* 377 * close the device.. only called if we are the LAST occurence of an open 378 * device. Convenient now but usually a pain. 379 */ 380 int 381 sdclose(dev, flag, fmt, p) 382 dev_t dev; 383 int flag, fmt; 384 struct proc *p; 385 { 386 struct sd_softc *sd = sd_cd.cd_devs[SDUNIT(dev)]; 387 int part = SDPART(dev); 388 int error; 389 390 if ((error = sdlock(sd)) != 0) 391 return error; 392 393 switch (fmt) { 394 case S_IFCHR: 395 sd->sc_dk.dk_copenmask &= ~(1 << part); 396 break; 397 case S_IFBLK: 398 sd->sc_dk.dk_bopenmask &= ~(1 << part); 399 break; 400 } 401 sd->sc_dk.dk_openmask = sd->sc_dk.dk_copenmask | sd->sc_dk.dk_bopenmask; 402 403 if (sd->sc_dk.dk_openmask == 0) { 404 /* XXXX Must wait for I/O to complete! */ 405 406 scsi_prevent(sd->sc_link, PR_ALLOW, 407 SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY); 408 sd->sc_link->flags &= ~(SDEV_OPEN|SDEV_MEDIA_LOADED); 409 } 410 411 sdunlock(sd); 412 return 0; 413 } 414 415 /* 416 * Actually translate the requested transfer into one the physical driver 417 * can understand. The transfer is described by a buf and will include 418 * only one physical transfer. 419 */ 420 void 421 sdstrategy(bp) 422 struct buf *bp; 423 { 424 struct sd_softc *sd = sd_cd.cd_devs[SDUNIT(bp->b_dev)]; 425 int s; 426 427 SC_DEBUG(sd->sc_link, SDEV_DB2, ("sdstrategy ")); 428 SC_DEBUG(sd->sc_link, SDEV_DB1, 429 ("%ld bytes @ blk %d\n", bp->b_bcount, bp->b_blkno)); 430 /* 431 * The transfer must be a whole number of blocks. 432 */ 433 if ((bp->b_bcount % sd->sc_dk.dk_label->d_secsize) != 0) { 434 bp->b_error = EINVAL; 435 goto bad; 436 } 437 /* 438 * If the device has been made invalid, error out 439 */ 440 if ((sd->sc_link->flags & SDEV_MEDIA_LOADED) == 0) { 441 bp->b_error = EIO; 442 goto bad; 443 } 444 /* 445 * If it's a null transfer, return immediatly 446 */ 447 if (bp->b_bcount == 0) 448 goto done; 449 450 /* 451 * Do bounds checking, adjust transfer. if error, process. 452 * If end of partition, just return. 453 */ 454 if (SDPART(bp->b_dev) != RAW_PART && 455 bounds_check_with_label(bp, sd->sc_dk.dk_label, 456 (sd->flags & (SDF_WLABEL|SDF_LABELLING)) != 0) <= 0) 457 goto done; 458 459 s = splbio(); 460 461 /* 462 * Place it in the queue of disk activities for this disk 463 */ 464 disksort(&sd->buf_queue, bp); 465 466 /* 467 * Tell the device to get going on the transfer if it's 468 * not doing anything, otherwise just wait for completion 469 */ 470 sdstart(sd); 471 472 splx(s); 473 return; 474 475 bad: 476 bp->b_flags |= B_ERROR; 477 done: 478 /* 479 * Correctly set the buf to indicate a completed xfer 480 */ 481 bp->b_resid = bp->b_bcount; 482 biodone(bp); 483 } 484 485 /* 486 * sdstart looks to see if there is a buf waiting for the device 487 * and that the device is not already busy. If both are true, 488 * It dequeues the buf and creates a scsi command to perform the 489 * transfer in the buf. The transfer request will call scsi_done 490 * on completion, which will in turn call this routine again 491 * so that the next queued transfer is performed. 492 * The bufs are queued by the strategy routine (sdstrategy) 493 * 494 * This routine is also called after other non-queued requests 495 * have been made of the scsi driver, to ensure that the queue 496 * continues to be drained. 497 * 498 * must be called at the correct (highish) spl level 499 * sdstart() is called at splbio from sdstrategy and scsi_done 500 */ 501 void 502 sdstart(v) 503 register void *v; 504 { 505 register struct sd_softc *sd = v; 506 register struct scsi_link *sc_link = sd->sc_link; 507 struct buf *bp = 0; 508 struct buf *dp; 509 struct scsi_rw_big cmd_big; 510 struct scsi_rw cmd_small; 511 struct scsi_generic *cmdp; 512 int blkno, nblks, cmdlen, error; 513 struct partition *p; 514 515 SC_DEBUG(sc_link, SDEV_DB2, ("sdstart ")); 516 /* 517 * Check if the device has room for another command 518 */ 519 while (sc_link->openings > 0) { 520 /* 521 * there is excess capacity, but a special waits 522 * It'll need the adapter as soon as we clear out of the 523 * way and let it run (user level wait). 524 */ 525 if (sc_link->flags & SDEV_WAITING) { 526 sc_link->flags &= ~SDEV_WAITING; 527 wakeup((caddr_t)sc_link); 528 return; 529 } 530 531 /* 532 * See if there is a buf with work for us to do.. 533 */ 534 dp = &sd->buf_queue; 535 if ((bp = dp->b_actf) == NULL) /* yes, an assign */ 536 return; 537 dp->b_actf = bp->b_actf; 538 539 /* 540 * If the device has become invalid, abort all the 541 * reads and writes until all files have been closed and 542 * re-opened 543 */ 544 if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) { 545 bp->b_error = EIO; 546 bp->b_flags |= B_ERROR; 547 biodone(bp); 548 continue; 549 } 550 551 /* 552 * We have a buf, now we should make a command 553 * 554 * First, translate the block to absolute and put it in terms 555 * of the logical blocksize of the device. 556 */ 557 blkno = 558 bp->b_blkno / (sd->sc_dk.dk_label->d_secsize / DEV_BSIZE); 559 if (SDPART(bp->b_dev) != RAW_PART) { 560 p = &sd->sc_dk.dk_label->d_partitions[SDPART(bp->b_dev)]; 561 blkno += p->p_offset; 562 } 563 nblks = howmany(bp->b_bcount, sd->sc_dk.dk_label->d_secsize); 564 565 /* 566 * Fill out the scsi command. If the transfer will 567 * fit in a "small" cdb, use it. 568 */ 569 if (((blkno & 0x1fffff) == blkno) && 570 ((nblks & 0xff) == nblks)) { 571 /* 572 * We can fit in a small cdb. 573 */ 574 bzero(&cmd_small, sizeof(cmd_small)); 575 cmd_small.opcode = (bp->b_flags & B_READ) ? 576 READ_COMMAND : WRITE_COMMAND; 577 _lto3b(blkno, cmd_small.addr); 578 cmd_small.length = nblks & 0xff; 579 cmdlen = sizeof(cmd_small); 580 cmdp = (struct scsi_generic *)&cmd_small; 581 } else { 582 /* 583 * Need a large cdb. 584 */ 585 bzero(&cmd_big, sizeof(cmd_big)); 586 cmd_big.opcode = (bp->b_flags & B_READ) ? 587 READ_BIG : WRITE_BIG; 588 _lto4b(blkno, cmd_big.addr); 589 _lto2b(nblks, cmd_big.length); 590 cmdlen = sizeof(cmd_big); 591 cmdp = (struct scsi_generic *)&cmd_big; 592 } 593 594 /* Instrumentation. */ 595 disk_busy(&sd->sc_dk); 596 597 /* 598 * Call the routine that chats with the adapter. 599 * Note: we cannot sleep as we may be an interrupt 600 */ 601 error = scsi_scsi_cmd(sc_link, cmdp, cmdlen, 602 (u_char *)bp->b_data, bp->b_bcount, 603 SDRETRIES, 10000, bp, SCSI_NOSLEEP | 604 ((bp->b_flags & B_READ) ? SCSI_DATA_IN : SCSI_DATA_OUT)); 605 if (error) 606 printf("%s: not queued, error %d\n", 607 sd->sc_dev.dv_xname, error); 608 } 609 } 610 611 int 612 sddone(xs, complete) 613 struct scsi_xfer *xs; 614 int complete; 615 { 616 struct sd_softc *sd = xs->sc_link->device_softc; 617 618 if (complete && (xs->bp != NULL)) 619 disk_unbusy(&sd->sc_dk, (xs->bp->b_bcount - xs->bp->b_resid)); 620 621 return (0); 622 } 623 624 void 625 sdminphys(bp) 626 struct buf *bp; 627 { 628 struct sd_softc *sd = sd_cd.cd_devs[SDUNIT(bp->b_dev)]; 629 long max; 630 631 /* 632 * If the device is ancient, we want to make sure that 633 * the transfer fits into a 6-byte cdb. 634 * 635 * XXX Note that the SCSI-I spec says that 256-block transfers 636 * are allowed in a 6-byte read/write, and are specified 637 * by settng the "length" to 0. However, we're conservative 638 * here, allowing only 255-block transfers in case an 639 * ancient device gets confused by length == 0. A length of 0 640 * in a 10-byte read/write actually means 0 blocks. 641 */ 642 if (sd->flags & SDF_ANCIENT) { 643 max = sd->sc_dk.dk_label->d_secsize * 0xff; 644 645 if (bp->b_bcount > max) 646 bp->b_bcount = max; 647 } 648 649 (*sd->sc_link->adapter->scsi_minphys)(bp); 650 } 651 652 int 653 sdread(dev, uio, ioflag) 654 dev_t dev; 655 struct uio *uio; 656 int ioflag; 657 { 658 659 return (physio(sdstrategy, NULL, dev, B_READ, sdminphys, uio)); 660 } 661 662 int 663 sdwrite(dev, uio, ioflag) 664 dev_t dev; 665 struct uio *uio; 666 int ioflag; 667 { 668 669 return (physio(sdstrategy, NULL, dev, B_WRITE, sdminphys, uio)); 670 } 671 672 /* 673 * Perform special action on behalf of the user 674 * Knows about the internals of this device 675 */ 676 int 677 sdioctl(dev, cmd, addr, flag, p) 678 dev_t dev; 679 u_long cmd; 680 caddr_t addr; 681 int flag; 682 struct proc *p; 683 { 684 struct sd_softc *sd = sd_cd.cd_devs[SDUNIT(dev)]; 685 int error; 686 687 SC_DEBUG(sd->sc_link, SDEV_DB2, ("sdioctl 0x%lx ", cmd)); 688 689 /* 690 * If the device is not valid.. abandon ship 691 */ 692 if ((sd->sc_link->flags & SDEV_MEDIA_LOADED) == 0) 693 return EIO; 694 695 switch (cmd) { 696 case DIOCGDINFO: 697 *(struct disklabel *)addr = *(sd->sc_dk.dk_label); 698 return 0; 699 700 case DIOCGPART: 701 ((struct partinfo *)addr)->disklab = sd->sc_dk.dk_label; 702 ((struct partinfo *)addr)->part = 703 &sd->sc_dk.dk_label->d_partitions[SDPART(dev)]; 704 return 0; 705 706 case DIOCWDINFO: 707 case DIOCSDINFO: 708 if ((flag & FWRITE) == 0) 709 return EBADF; 710 711 if ((error = sdlock(sd)) != 0) 712 return error; 713 sd->flags |= SDF_LABELLING; 714 715 error = setdisklabel(sd->sc_dk.dk_label, 716 (struct disklabel *)addr, /*sd->sc_dk.dk_openmask : */0, 717 sd->sc_dk.dk_cpulabel); 718 if (error == 0) { 719 if (cmd == DIOCWDINFO) 720 error = writedisklabel(SDLABELDEV(dev), 721 sdstrategy, sd->sc_dk.dk_label, 722 sd->sc_dk.dk_cpulabel); 723 } 724 725 sd->flags &= ~SDF_LABELLING; 726 sdunlock(sd); 727 return error; 728 729 case DIOCWLABEL: 730 if ((flag & FWRITE) == 0) 731 return EBADF; 732 if (*(int *)addr) 733 sd->flags |= SDF_WLABEL; 734 else 735 sd->flags &= ~SDF_WLABEL; 736 return 0; 737 738 case DIOCLOCK: 739 return scsi_prevent(sd->sc_link, 740 (*(int *)addr) ? PR_PREVENT : PR_ALLOW, 0); 741 742 case DIOCEJECT: 743 return ((sd->sc_link->flags & SDEV_REMOVABLE) == 0 ? ENOTTY : 744 scsi_start(sd->sc_link, SSS_STOP|SSS_LOEJ, 0)); 745 746 default: 747 if (SDPART(dev) != RAW_PART) 748 return ENOTTY; 749 return scsi_do_ioctl(sd->sc_link, dev, cmd, addr, flag, p); 750 } 751 752 #ifdef DIAGNOSTIC 753 panic("sdioctl: impossible"); 754 #endif 755 } 756 757 /* 758 * Load the label information on the named device 759 */ 760 void 761 sdgetdisklabel(sd) 762 struct sd_softc *sd; 763 { 764 struct disklabel *lp = sd->sc_dk.dk_label; 765 char *errstring; 766 767 bzero(lp, sizeof(struct disklabel)); 768 bzero(sd->sc_dk.dk_cpulabel, sizeof(struct cpu_disklabel)); 769 770 lp->d_secsize = sd->params.blksize; 771 lp->d_ntracks = sd->params.heads; 772 lp->d_nsectors = sd->params.sectors; 773 lp->d_ncylinders = sd->params.cyls; 774 lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors; 775 if (lp->d_secpercyl == 0) { 776 lp->d_secpercyl = 100; 777 /* as long as it's not 0 - readdisklabel divides by it (?) */ 778 } 779 780 strncpy(lp->d_typename, "SCSI disk", 16); 781 lp->d_type = DTYPE_SCSI; 782 strncpy(lp->d_packname, "fictitious", 16); 783 lp->d_secperunit = sd->params.disksize; 784 lp->d_rpm = 3600; 785 lp->d_interleave = 1; 786 lp->d_flags = 0; 787 788 lp->d_partitions[RAW_PART].p_offset = 0; 789 lp->d_partitions[RAW_PART].p_size = 790 lp->d_secperunit * (lp->d_secsize / DEV_BSIZE); 791 lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED; 792 lp->d_npartitions = RAW_PART + 1; 793 794 lp->d_magic = DISKMAGIC; 795 lp->d_magic2 = DISKMAGIC; 796 lp->d_checksum = dkcksum(lp); 797 798 /* 799 * Call the generic disklabel extraction routine 800 */ 801 errstring = readdisklabel(MAKESDDEV(0, sd->sc_dev.dv_unit, RAW_PART), 802 sdstrategy, lp, sd->sc_dk.dk_cpulabel); 803 if (errstring) { 804 printf("%s: %s\n", sd->sc_dev.dv_xname, errstring); 805 return; 806 } 807 } 808 809 /* 810 * Tell the device to map out a defective block 811 */ 812 int 813 sd_reassign_blocks(sd, blkno) 814 struct sd_softc *sd; 815 u_long blkno; 816 { 817 struct scsi_reassign_blocks scsi_cmd; 818 struct scsi_reassign_blocks_data rbdata; 819 820 bzero(&scsi_cmd, sizeof(scsi_cmd)); 821 bzero(&rbdata, sizeof(rbdata)); 822 scsi_cmd.opcode = REASSIGN_BLOCKS; 823 824 _lto2b(sizeof(rbdata.defect_descriptor[0]), rbdata.length); 825 _lto4b(blkno, rbdata.defect_descriptor[0].dlbaddr); 826 827 return scsi_scsi_cmd(sd->sc_link, (struct scsi_generic *)&scsi_cmd, 828 sizeof(scsi_cmd), (u_char *)&rbdata, sizeof(rbdata), SDRETRIES, 829 5000, NULL, SCSI_DATA_OUT); 830 } 831 832 833 834 static int 835 sd_mode_sense(sd, scsi_sense, page, flags) 836 struct sd_softc *sd; 837 struct scsi_mode_sense_data *scsi_sense; 838 int page, flags; 839 { 840 struct scsi_mode_sense scsi_cmd; 841 842 bzero(&scsi_cmd, sizeof(scsi_cmd)); 843 scsi_cmd.opcode = MODE_SENSE; 844 scsi_cmd.page = page; 845 scsi_cmd.length = 0x20; 846 /* 847 * If the command worked, use the results to fill out 848 * the parameter structure 849 */ 850 return scsi_scsi_cmd(sd->sc_link, (struct scsi_generic *)&scsi_cmd, 851 sizeof(scsi_cmd), (u_char *)scsi_sense, sizeof(*scsi_sense), 852 SDRETRIES, 6000, NULL, flags | SCSI_DATA_IN | SCSI_SILENT); 853 } 854 855 /* 856 * Get the scsi driver to send a full inquiry to the * device and use the 857 * results to fill out the disk parameter structure. 858 */ 859 int 860 sd_get_parms(sd, flags) 861 struct sd_softc *sd; 862 int flags; 863 { 864 struct disk_parms *dp = &sd->params; 865 struct scsi_mode_sense_data scsi_sense; 866 u_long sectors; 867 int page; 868 int error; 869 870 if ((error = sd_mode_sense(sd, &scsi_sense, page = 4, flags)) == 0) { 871 SC_DEBUG(sd->sc_link, SDEV_DB3, 872 ("%d cyls, %d heads, %d precomp, %d red_write, %d land_zone\n", 873 _3btol(scsi_sense.pages.rigid_geometry.ncyl), 874 scsi_sense.pages.rigid_geometry.nheads, 875 _2btol(scsi_sense.pages.rigid_geometry.st_cyl_wp), 876 _2btol(scsi_sense.pages.rigid_geometry.st_cyl_rwc), 877 _2btol(scsi_sense.pages.rigid_geometry.land_zone))); 878 879 /* 880 * KLUDGE!! (for zone recorded disks) 881 * give a number of sectors so that sec * trks * cyls 882 * is <= disk_size 883 * can lead to wasted space! THINK ABOUT THIS ! 884 */ 885 dp->heads = scsi_sense.pages.rigid_geometry.nheads; 886 dp->cyls = _3btol(scsi_sense.pages.rigid_geometry.ncyl); 887 dp->blksize = _3btol(scsi_sense.blk_desc.blklen); 888 889 if (dp->heads == 0 || dp->cyls == 0) 890 goto fake_it; 891 892 if (dp->blksize == 0) 893 dp->blksize = 512; 894 895 sectors = scsi_size(sd->sc_link, flags); 896 dp->disksize = sectors; 897 sectors /= (dp->heads * dp->cyls); 898 dp->sectors = sectors; /* XXX dubious on SCSI */ 899 900 return 0; 901 } 902 903 if ((error = sd_mode_sense(sd, &scsi_sense, page = 5, flags)) == 0) { 904 dp->heads = scsi_sense.pages.flex_geometry.nheads; 905 dp->cyls = _2btol(scsi_sense.pages.flex_geometry.ncyl); 906 dp->blksize = _3btol(scsi_sense.blk_desc.blklen); 907 dp->sectors = scsi_sense.pages.flex_geometry.ph_sec_tr; 908 dp->disksize = dp->heads * dp->cyls * dp->sectors; 909 if (dp->disksize == 0) 910 goto fake_it; 911 912 if (dp->blksize == 0) 913 dp->blksize = 512; 914 915 return 0; 916 } 917 918 fake_it: 919 if ((sd->sc_link->quirks & SDEV_NOMODESENSE) == 0) { 920 if (error == 0) 921 printf("%s: mode sense (%d) returned nonsense", 922 sd->sc_dev.dv_xname, page); 923 else 924 printf("%s: could not mode sense (4/5)", 925 sd->sc_dev.dv_xname); 926 printf("; using fictitious geometry\n"); 927 } 928 /* 929 * use adaptec standard fictitious geometry 930 * this depends on which controller (e.g. 1542C is 931 * different. but we have to put SOMETHING here..) 932 */ 933 sectors = scsi_size(sd->sc_link, flags); 934 dp->heads = 64; 935 dp->sectors = 32; 936 dp->cyls = sectors / (64 * 32); 937 dp->blksize = 512; 938 dp->disksize = sectors; 939 return 0; 940 } 941 942 int 943 sdsize(dev) 944 dev_t dev; 945 { 946 struct sd_softc *sd; 947 int part; 948 int size; 949 950 if (sdopen(dev, 0, S_IFBLK, NULL) != 0) 951 return -1; 952 sd = sd_cd.cd_devs[SDUNIT(dev)]; 953 part = SDPART(dev); 954 if (sd->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP) 955 size = -1; 956 else 957 size = sd->sc_dk.dk_label->d_partitions[part].p_size; 958 if (sdclose(dev, 0, S_IFBLK, NULL) != 0) 959 return -1; 960 return size; 961 } 962 963 #ifndef __BDEVSW_DUMP_OLD_TYPE 964 /* #define SD_DUMP_NOT_TRUSTED if you just want to watch */ 965 static struct scsi_xfer sx; 966 static int sddoingadump; 967 968 /* 969 * dump all of physical memory into the partition specified, starting 970 * at offset 'dumplo' into the partition. 971 */ 972 int 973 sddump(dev, blkno, va, size) 974 dev_t dev; 975 daddr_t blkno; 976 caddr_t va; 977 size_t size; 978 { 979 struct sd_softc *sd; /* disk unit to do the I/O */ 980 struct disklabel *lp; /* disk's disklabel */ 981 int unit, part; 982 int sectorsize; /* size of a disk sector */ 983 int nsects; /* number of sectors in partition */ 984 int sectoff; /* sector offset of partition */ 985 int totwrt; /* total number of sectors left to write */ 986 int nwrt; /* current number of sectors to write */ 987 struct scsi_rw_big cmd; /* write command */ 988 struct scsi_xfer *xs; /* ... convenience */ 989 int retval; 990 991 /* Check if recursive dump; if so, punt. */ 992 if (sddoingadump) 993 return EFAULT; 994 995 /* Mark as active early. */ 996 sddoingadump = 1; 997 998 unit = SDUNIT(dev); /* Decompose unit & partition. */ 999 part = SDPART(dev); 1000 1001 /* Check for acceptable drive number. */ 1002 if (unit >= sd_cd.cd_ndevs || (sd = sd_cd.cd_devs[unit]) == NULL) 1003 return ENXIO; 1004 1005 /* 1006 * XXX Can't do this check, since the media might have been 1007 * XXX marked `invalid' by successful unmounting of all 1008 * XXX filesystems. 1009 */ 1010 #if 0 1011 /* Make sure it was initialized. */ 1012 if ((sd->sc_link->flags & SDEV_MEDIA_LOADED) != SDEV_MEDIA_LOADED) 1013 return ENXIO; 1014 #endif 1015 1016 /* Convert to disk sectors. Request must be a multiple of size. */ 1017 lp = sd->sc_dk.dk_label; 1018 sectorsize = lp->d_secsize; 1019 if ((size % sectorsize) != 0) 1020 return EFAULT; 1021 totwrt = size / sectorsize; 1022 blkno = dbtob(blkno) / sectorsize; /* blkno in DEV_BSIZE units */ 1023 1024 nsects = lp->d_partitions[part].p_size; 1025 sectoff = lp->d_partitions[part].p_offset; 1026 1027 /* Check transfer bounds against partition size. */ 1028 if ((blkno < 0) || ((blkno + totwrt) > nsects)) 1029 return EINVAL; 1030 1031 /* Offset block number to start of partition. */ 1032 blkno += sectoff; 1033 1034 xs = &sx; 1035 1036 while (totwrt > 0) { 1037 nwrt = totwrt; /* XXX */ 1038 #ifndef SD_DUMP_NOT_TRUSTED 1039 /* 1040 * Fill out the scsi command 1041 */ 1042 bzero(&cmd, sizeof(cmd)); 1043 cmd.opcode = WRITE_BIG; 1044 _lto4b(blkno, cmd.addr); 1045 _lto2b(nwrt, cmd.length); 1046 /* 1047 * Fill out the scsi_xfer structure 1048 * Note: we cannot sleep as we may be an interrupt 1049 * don't use scsi_scsi_cmd() as it may want 1050 * to wait for an xs. 1051 */ 1052 bzero(xs, sizeof(sx)); 1053 xs->flags |= SCSI_AUTOCONF | INUSE | SCSI_DATA_OUT; 1054 xs->sc_link = sd->sc_link; 1055 xs->retries = SDRETRIES; 1056 xs->timeout = 10000; /* 10000 millisecs for a disk ! */ 1057 xs->cmd = (struct scsi_generic *)&cmd; 1058 xs->cmdlen = sizeof(cmd); 1059 xs->resid = nwrt * sectorsize; 1060 xs->error = XS_NOERROR; 1061 xs->bp = 0; 1062 xs->data = va; 1063 xs->datalen = nwrt * sectorsize; 1064 1065 /* 1066 * Pass all this info to the scsi driver. 1067 */ 1068 retval = (*(sd->sc_link->adapter->scsi_cmd)) (xs); 1069 if (retval != COMPLETE) 1070 return ENXIO; 1071 #else /* SD_DUMP_NOT_TRUSTED */ 1072 /* Let's just talk about this first... */ 1073 printf("sd%d: dump addr 0x%x, blk %d\n", unit, va, blkno); 1074 delay(500 * 1000); /* half a second */ 1075 #endif /* SD_DUMP_NOT_TRUSTED */ 1076 1077 /* update block count */ 1078 totwrt -= nwrt; 1079 blkno += nwrt; 1080 va += sectorsize * nwrt; 1081 } 1082 sddoingadump = 0; 1083 return 0; 1084 } 1085 #else /* __BDEVSW_DUMP_NEW_TYPE */ 1086 int 1087 sddump(dev, blkno, va, size) 1088 dev_t dev; 1089 daddr_t blkno; 1090 caddr_t va; 1091 size_t size; 1092 { 1093 1094 /* Not implemented. */ 1095 return ENXIO; 1096 } 1097 #endif /* __BDEVSW_DUMP_NEW_TYPE */ 1098