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