1 /* $NetBSD: sd.c,v 1.68 1995/04/15 05:01:29 mycroft 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/conf.h> 54 #include <sys/file.h> 55 #include <sys/stat.h> 56 #include <sys/ioctl.h> 57 #include <sys/buf.h> 58 #include <sys/uio.h> 59 #include <sys/malloc.h> 60 #include <sys/errno.h> 61 #include <sys/device.h> 62 #include <sys/disklabel.h> 63 #include <sys/disk.h> 64 65 #include <scsi/scsi_all.h> 66 #include <scsi/scsi_disk.h> 67 #include <scsi/scsiconf.h> 68 69 #ifdef DDB 70 int Debugger(); 71 #else /* DDB */ 72 #define Debugger() 73 #endif /* DDB */ 74 75 #define SDOUTSTANDING 2 76 #define SDRETRIES 4 77 78 #define SDUNIT(dev) DISKUNIT(dev) 79 #define SDPART(dev) DISKPART(dev) 80 #define MAKESDDEV(maj, unit, part) MAKEDISKDEV(maj, unit, part) 81 82 #define SDLABELDEV(dev) (MAKESDDEV(major(dev), SDUNIT(dev), RAW_PART)) 83 84 struct sd_softc { 85 struct device sc_dev; 86 struct dkdevice sc_dk; 87 88 int flags; 89 #define SDF_LOCKED 0x01 90 #define SDF_WANTED 0x02 91 #define SDF_WLABEL 0x04 /* label is writable */ 92 #define SDF_LABELLING 0x08 /* writing label */ 93 struct scsi_link *sc_link; /* contains our targ, lun, etc. */ 94 struct disk_parms { 95 u_char heads; /* number of heads */ 96 u_short cyls; /* number of cylinders */ 97 u_char sectors; /* number of sectors/track */ 98 int blksize; /* number of bytes/sector */ 99 u_long disksize; /* total number sectors */ 100 } params; 101 struct buf buf_queue; 102 }; 103 104 int sdmatch __P((struct device *, void *, void *)); 105 void sdattach __P((struct device *, struct device *, void *)); 106 107 struct cfdriver sdcd = { 108 NULL, "sd", sdmatch, sdattach, DV_DISK, sizeof(struct sd_softc) 109 }; 110 111 void sdgetdisklabel __P((struct sd_softc *)); 112 int sd_get_parms __P((struct sd_softc *, int)); 113 void sdstrategy __P((struct buf *)); 114 void sdstart __P((struct sd_softc *)); 115 116 struct dkdriver sddkdriver = { sdstrategy }; 117 118 struct scsi_device sd_switch = { 119 NULL, /* Use default error handler */ 120 sdstart, /* have a queue, served by this */ 121 NULL, /* have no async handler */ 122 NULL, /* Use default 'done' routine */ 123 }; 124 125 struct scsi_inquiry_pattern sd_patterns[] = { 126 {T_DIRECT, T_FIXED, 127 "", "", ""}, 128 {T_DIRECT, T_REMOV, 129 "", "", ""}, 130 {T_OPTICAL, T_FIXED, 131 "", "", ""}, 132 {T_OPTICAL, T_REMOV, 133 "", "", ""}, 134 }; 135 136 int 137 sdmatch(parent, match, aux) 138 struct device *parent; 139 void *match, *aux; 140 { 141 struct cfdata *cf = match; 142 struct scsibus_attach_args *sa = aux; 143 int priority; 144 145 (void)scsi_inqmatch(sa->sa_inqbuf, 146 (caddr_t)sd_patterns, sizeof(sd_patterns)/sizeof(sd_patterns[0]), 147 sizeof(sd_patterns[0]), &priority); 148 return (priority); 149 } 150 151 /* 152 * The routine called by the low level scsi routine when it discovers 153 * a device suitable for this driver. 154 */ 155 void 156 sdattach(parent, self, aux) 157 struct device *parent, *self; 158 void *aux; 159 { 160 struct sd_softc *sd = (void *)self; 161 struct disk_parms *dp = &sd->params; 162 struct scsibus_attach_args *sa = aux; 163 struct scsi_link *sc_link = sa->sa_sc_link; 164 165 SC_DEBUG(sc_link, SDEV_DB2, ("sdattach: ")); 166 167 /* 168 * Store information needed to contact our base driver 169 */ 170 sd->sc_link = sc_link; 171 sc_link->device = &sd_switch; 172 sc_link->device_softc = sd; 173 if (sc_link->openings > SDOUTSTANDING) 174 sc_link->openings = SDOUTSTANDING; 175 176 sd->sc_dk.dk_driver = &sddkdriver; 177 #if !defined(i386) || defined(NEWCONFIG) 178 dk_establish(&sd->sc_dk, &sd->sc_dev); 179 #endif 180 181 /* 182 * Use the subdriver to request information regarding 183 * the drive. We cannot use interrupts yet, so the 184 * request must specify this. 185 */ 186 if (scsi_start(sd->sc_link, SSS_START, 187 SCSI_AUTOCONF | SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE | SCSI_SILENT) || 188 sd_get_parms(sd, SCSI_AUTOCONF) != 0) 189 printf(": drive offline\n"); 190 else 191 printf(": %dMB, %d cyl, %d head, %d sec, %d bytes/sec\n", 192 dp->disksize / (1048576 / dp->blksize), dp->cyls, 193 dp->heads, dp->sectors, dp->blksize); 194 } 195 196 /* 197 * Wait interruptibly for an exclusive lock. 198 * 199 * XXX 200 * Several drivers do this; it should be abstracted and made MP-safe. 201 */ 202 int 203 sdlock(sd) 204 struct sd_softc *sd; 205 { 206 int error; 207 208 while ((sd->flags & SDF_LOCKED) != 0) { 209 sd->flags |= SDF_WANTED; 210 if ((error = tsleep(sd, PRIBIO | PCATCH, "sdlck", 0)) != 0) 211 return error; 212 } 213 sd->flags |= SDF_LOCKED; 214 return 0; 215 } 216 217 /* 218 * Unlock and wake up any waiters. 219 */ 220 void 221 sdunlock(sd) 222 struct sd_softc *sd; 223 { 224 225 sd->flags &= ~SDF_LOCKED; 226 if ((sd->flags & SDF_WANTED) != 0) { 227 sd->flags &= ~SDF_WANTED; 228 wakeup(sd); 229 } 230 } 231 232 /* 233 * open the device. Make sure the partition info is a up-to-date as can be. 234 */ 235 int 236 sdopen(dev, flag, fmt) 237 dev_t dev; 238 int flag, fmt; 239 { 240 struct sd_softc *sd; 241 struct scsi_link *sc_link; 242 int unit, part; 243 int error; 244 245 unit = SDUNIT(dev); 246 if (unit >= sdcd.cd_ndevs) 247 return ENXIO; 248 sd = sdcd.cd_devs[unit]; 249 if (!sd) 250 return ENXIO; 251 252 sc_link = sd->sc_link; 253 254 SC_DEBUG(sc_link, SDEV_DB1, 255 ("sdopen: dev=0x%x (unit %d (of %d), partition %d)\n", dev, unit, 256 sdcd.cd_ndevs, part)); 257 258 if (error = sdlock(sd)) 259 return error; 260 261 if (sd->sc_dk.dk_openmask != 0) { 262 /* 263 * If any partition is open, but the disk has been invalidated, 264 * disallow further opens. 265 */ 266 if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) { 267 error = EIO; 268 goto bad3; 269 } 270 } else { 271 /* Check that it is still responding and ok. */ 272 if (error = scsi_test_unit_ready(sc_link, 273 SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE | SCSI_IGNORE_NOT_READY)) 274 goto bad3; 275 276 /* Start the pack spinning if necessary. */ 277 if (error = scsi_start(sc_link, SSS_START, 278 SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE | SCSI_SILENT)) 279 goto bad3; 280 281 sc_link->flags |= SDEV_OPEN; 282 283 /* Lock the pack in. */ 284 if (error = scsi_prevent(sc_link, PR_PREVENT, 285 SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE)) 286 goto bad; 287 288 if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) { 289 sc_link->flags |= SDEV_MEDIA_LOADED; 290 291 /* Load the physical device parameters. */ 292 if (sd_get_parms(sd, 0) != 0) { 293 error = ENXIO; 294 goto bad2; 295 } 296 SC_DEBUG(sc_link, SDEV_DB3, ("Params loaded ")); 297 298 /* Load the partition info if not already loaded. */ 299 sdgetdisklabel(sd); 300 SC_DEBUG(sc_link, SDEV_DB3, ("Disklabel loaded ")); 301 } 302 } 303 304 part = SDPART(dev); 305 306 /* Check that the partition exists. */ 307 if (part != RAW_PART && 308 (part >= sd->sc_dk.dk_label.d_npartitions || 309 sd->sc_dk.dk_label.d_partitions[part].p_fstype == FS_UNUSED)) { 310 error = ENXIO; 311 goto bad; 312 } 313 314 /* Insure only one open at a time. */ 315 switch (fmt) { 316 case S_IFCHR: 317 sd->sc_dk.dk_copenmask |= (1 << part); 318 break; 319 case S_IFBLK: 320 sd->sc_dk.dk_bopenmask |= (1 << part); 321 break; 322 } 323 sd->sc_dk.dk_openmask = sd->sc_dk.dk_copenmask | sd->sc_dk.dk_bopenmask; 324 325 SC_DEBUG(sc_link, SDEV_DB3, ("open complete\n")); 326 sdunlock(sd); 327 return 0; 328 329 bad2: 330 sc_link->flags &= ~SDEV_MEDIA_LOADED; 331 332 bad: 333 if (sd->sc_dk.dk_openmask == 0) { 334 scsi_prevent(sc_link, PR_ALLOW, 335 SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE); 336 sc_link->flags &= ~SDEV_OPEN; 337 } 338 339 bad3: 340 sdunlock(sd); 341 return error; 342 } 343 344 /* 345 * close the device.. only called if we are the LAST occurence of an open 346 * device. Convenient now but usually a pain. 347 */ 348 int 349 sdclose(dev, flag, fmt) 350 dev_t dev; 351 int flag, fmt; 352 { 353 struct sd_softc *sd = sdcd.cd_devs[SDUNIT(dev)]; 354 int part = SDPART(dev); 355 int error; 356 357 if (error = sdlock(sd)) 358 return error; 359 360 switch (fmt) { 361 case S_IFCHR: 362 sd->sc_dk.dk_copenmask &= ~(1 << part); 363 break; 364 case S_IFBLK: 365 sd->sc_dk.dk_bopenmask &= ~(1 << part); 366 break; 367 } 368 sd->sc_dk.dk_openmask = sd->sc_dk.dk_copenmask | sd->sc_dk.dk_bopenmask; 369 370 if (sd->sc_dk.dk_openmask == 0) { 371 /* XXXX Must wait for I/O to complete! */ 372 373 scsi_prevent(sd->sc_link, PR_ALLOW, 374 SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY); 375 sd->sc_link->flags &= ~SDEV_OPEN; 376 } 377 378 sdunlock(sd); 379 return 0; 380 } 381 382 /* 383 * trim the size of the transfer if needed, called by physio 384 * basically the smaller of our max and the scsi driver's 385 * minphys (note we have no max) 386 * 387 * Trim buffer length if buffer-size is bigger than page size 388 */ 389 void 390 sdminphys(bp) 391 struct buf *bp; 392 { 393 register struct sd_softc *sd = sdcd.cd_devs[SDUNIT(bp->b_dev)]; 394 395 (sd->sc_link->adapter->scsi_minphys) (bp); 396 } 397 398 /* 399 * Actually translate the requested transfer into one the physical driver 400 * can understand. The transfer is described by a buf and will include 401 * only one physical transfer. 402 */ 403 void 404 sdstrategy(bp) 405 struct buf *bp; 406 { 407 struct sd_softc *sd = sdcd.cd_devs[SDUNIT(bp->b_dev)]; 408 int opri; 409 410 SC_DEBUG(sd->sc_link, SDEV_DB2, ("sdstrategy ")); 411 SC_DEBUG(sd->sc_link, SDEV_DB1, 412 ("%d bytes @ blk %d\n", bp->b_bcount, bp->b_blkno)); 413 sdminphys(bp); 414 /* 415 * If the device has been made invalid, error out 416 */ 417 if ((sd->sc_link->flags & SDEV_MEDIA_LOADED) == 0) { 418 bp->b_error = EIO; 419 goto bad; 420 } 421 /* 422 * If it's a null transfer, return immediatly 423 */ 424 if (bp->b_bcount == 0) 425 goto done; 426 427 /* 428 * Do bounds checking, adjust transfer. if error, process. 429 * If end of partition, just return. 430 */ 431 if (SDPART(bp->b_dev) != RAW_PART && 432 bounds_check_with_label(bp, &sd->sc_dk.dk_label, 433 (sd->flags & (SDF_WLABEL|SDF_LABELLING)) != 0) <= 0) 434 goto done; 435 436 opri = splbio(); 437 438 /* 439 * Place it in the queue of disk activities for this disk 440 */ 441 disksort(&sd->buf_queue, bp); 442 443 /* 444 * Tell the device to get going on the transfer if it's 445 * not doing anything, otherwise just wait for completion 446 */ 447 sdstart(sd); 448 449 splx(opri); 450 return; 451 452 bad: 453 bp->b_flags |= B_ERROR; 454 done: 455 /* 456 * Correctly set the buf to indicate a completed xfer 457 */ 458 bp->b_resid = bp->b_bcount; 459 biodone(bp); 460 } 461 462 /* 463 * sdstart looks to see if there is a buf waiting for the device 464 * and that the device is not already busy. If both are true, 465 * It dequeues the buf and creates a scsi command to perform the 466 * transfer in the buf. The transfer request will call scsi_done 467 * on completion, which will in turn call this routine again 468 * so that the next queued transfer is performed. 469 * The bufs are queued by the strategy routine (sdstrategy) 470 * 471 * This routine is also called after other non-queued requests 472 * have been made of the scsi driver, to ensure that the queue 473 * continues to be drained. 474 * 475 * must be called at the correct (highish) spl level 476 * sdstart() is called at splbio from sdstrategy and scsi_done 477 */ 478 void 479 sdstart(sd) 480 register struct sd_softc *sd; 481 { 482 register struct scsi_link *sc_link = sd->sc_link; 483 struct buf *bp = 0; 484 struct buf *dp; 485 struct scsi_rw_big cmd; 486 int blkno, nblks; 487 struct partition *p; 488 489 SC_DEBUG(sc_link, SDEV_DB2, ("sdstart ")); 490 /* 491 * Check if the device has room for another command 492 */ 493 while (sc_link->openings > 0) { 494 /* 495 * there is excess capacity, but a special waits 496 * It'll need the adapter as soon as we clear out of the 497 * way and let it run (user level wait). 498 */ 499 if (sc_link->flags & SDEV_WAITING) { 500 sc_link->flags &= ~SDEV_WAITING; 501 wakeup((caddr_t)sc_link); 502 return; 503 } 504 505 /* 506 * See if there is a buf with work for us to do.. 507 */ 508 dp = &sd->buf_queue; 509 if ((bp = dp->b_actf) == NULL) /* yes, an assign */ 510 return; 511 dp->b_actf = bp->b_actf; 512 513 /* 514 * If the device has become invalid, abort all the 515 * reads and writes until all files have been closed and 516 * re-opened 517 */ 518 if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) { 519 bp->b_error = EIO; 520 bp->b_flags |= B_ERROR; 521 biodone(bp); 522 continue; 523 } 524 525 /* 526 * We have a buf, now we should make a command 527 * 528 * First, translate the block to absolute and put it in terms 529 * of the logical blocksize of the device. 530 */ 531 blkno = 532 bp->b_blkno / (sd->sc_dk.dk_label.d_secsize / DEV_BSIZE); 533 if (SDPART(bp->b_dev) != RAW_PART) { 534 p = &sd->sc_dk.dk_label.d_partitions[SDPART(bp->b_dev)]; 535 blkno += p->p_offset; 536 } 537 nblks = howmany(bp->b_bcount, sd->sc_dk.dk_label.d_secsize); 538 539 /* 540 * Fill out the scsi command 541 */ 542 bzero(&cmd, sizeof(cmd)); 543 cmd.opcode = (bp->b_flags & B_READ) ? READ_BIG : WRITE_BIG; 544 cmd.addr_3 = (blkno & 0xff000000) >> 24; 545 cmd.addr_2 = (blkno & 0xff0000) >> 16; 546 cmd.addr_1 = (blkno & 0xff00) >> 8; 547 cmd.addr_0 = blkno & 0xff; 548 cmd.length2 = (nblks & 0xff00) >> 8; 549 cmd.length1 = (nblks & 0xff); 550 551 /* 552 * Call the routine that chats with the adapter. 553 * Note: we cannot sleep as we may be an interrupt 554 */ 555 if (scsi_scsi_cmd(sc_link, (struct scsi_generic *)&cmd, 556 sizeof(cmd), (u_char *)bp->b_data, bp->b_bcount, 557 SDRETRIES, 10000, bp, SCSI_NOSLEEP | 558 ((bp->b_flags & B_READ) ? SCSI_DATA_IN : SCSI_DATA_OUT))) 559 printf("%s: not queued", sd->sc_dev.dv_xname); 560 } 561 } 562 563 /* 564 * Perform special action on behalf of the user 565 * Knows about the internals of this device 566 */ 567 int 568 sdioctl(dev, cmd, addr, flag, p) 569 dev_t dev; 570 u_long cmd; 571 caddr_t addr; 572 int flag; 573 struct proc *p; 574 { 575 struct sd_softc *sd = sdcd.cd_devs[SDUNIT(dev)]; 576 int error; 577 578 SC_DEBUG(sd->sc_link, SDEV_DB2, ("sdioctl 0x%lx ", cmd)); 579 580 /* 581 * If the device is not valid.. abandon ship 582 */ 583 if ((sd->sc_link->flags & SDEV_MEDIA_LOADED) == 0) 584 return EIO; 585 586 switch (cmd) { 587 case DIOCGDINFO: 588 *(struct disklabel *)addr = sd->sc_dk.dk_label; 589 return 0; 590 591 case DIOCGPART: 592 ((struct partinfo *)addr)->disklab = &sd->sc_dk.dk_label; 593 ((struct partinfo *)addr)->part = 594 &sd->sc_dk.dk_label.d_partitions[SDPART(dev)]; 595 return 0; 596 597 case DIOCWDINFO: 598 case DIOCSDINFO: 599 if ((flag & FWRITE) == 0) 600 return EBADF; 601 602 if (error = sdlock(sd)) 603 return error; 604 sd->flags |= SDF_LABELLING; 605 606 error = setdisklabel(&sd->sc_dk.dk_label, 607 (struct disklabel *)addr, /*sd->sc_dk.dk_openmask : */0, 608 &sd->sc_dk.dk_cpulabel); 609 if (error == 0) { 610 if (cmd == DIOCWDINFO) 611 error = writedisklabel(SDLABELDEV(dev), 612 sdstrategy, &sd->sc_dk.dk_label, 613 &sd->sc_dk.dk_cpulabel); 614 } 615 616 sd->flags &= ~SDF_LABELLING; 617 sdunlock(sd); 618 return error; 619 620 case DIOCWLABEL: 621 if ((flag & FWRITE) == 0) 622 return EBADF; 623 if (*(int *)addr) 624 sd->flags |= SDF_WLABEL; 625 else 626 sd->flags &= ~SDF_WLABEL; 627 return 0; 628 629 default: 630 if (SDPART(dev) != RAW_PART) 631 return ENOTTY; 632 return scsi_do_ioctl(sd->sc_link, dev, cmd, addr, flag, p); 633 } 634 635 #ifdef DIAGNOSTIC 636 panic("sdioctl: impossible"); 637 #endif 638 } 639 640 /* 641 * Load the label information on the named device 642 */ 643 void 644 sdgetdisklabel(sd) 645 struct sd_softc *sd; 646 { 647 char *errstring; 648 649 bzero(&sd->sc_dk.dk_label, sizeof(struct disklabel)); 650 bzero(&sd->sc_dk.dk_cpulabel, sizeof(struct cpu_disklabel)); 651 652 sd->sc_dk.dk_label.d_secsize = sd->params.blksize; 653 sd->sc_dk.dk_label.d_ntracks = sd->params.heads; 654 sd->sc_dk.dk_label.d_nsectors = sd->params.sectors; 655 sd->sc_dk.dk_label.d_ncylinders = sd->params.cyls; 656 sd->sc_dk.dk_label.d_secpercyl = 657 sd->sc_dk.dk_label.d_ntracks * sd->sc_dk.dk_label.d_nsectors; 658 if (sd->sc_dk.dk_label.d_secpercyl == 0) { 659 sd->sc_dk.dk_label.d_secpercyl = 100; 660 /* as long as it's not 0 - readdisklabel divides by it (?) */ 661 } 662 663 strncpy(sd->sc_dk.dk_label.d_typename, "SCSI disk", 16); 664 sd->sc_dk.dk_label.d_type = DTYPE_SCSI; 665 strncpy(sd->sc_dk.dk_label.d_packname, "fictitious", 16); 666 sd->sc_dk.dk_label.d_secperunit = sd->params.disksize; 667 sd->sc_dk.dk_label.d_rpm = 3600; 668 sd->sc_dk.dk_label.d_interleave = 1; 669 sd->sc_dk.dk_label.d_flags = 0; 670 671 sd->sc_dk.dk_label.d_partitions[RAW_PART].p_offset = 0; 672 sd->sc_dk.dk_label.d_partitions[RAW_PART].p_size = 673 sd->sc_dk.dk_label.d_secperunit * 674 (sd->sc_dk.dk_label.d_secsize / DEV_BSIZE); 675 sd->sc_dk.dk_label.d_partitions[RAW_PART].p_fstype = FS_UNUSED; 676 sd->sc_dk.dk_label.d_npartitions = RAW_PART + 1; 677 678 sd->sc_dk.dk_label.d_magic = DISKMAGIC; 679 sd->sc_dk.dk_label.d_magic2 = DISKMAGIC; 680 sd->sc_dk.dk_label.d_checksum = dkcksum(&sd->sc_dk.dk_label); 681 682 /* 683 * Call the generic disklabel extraction routine 684 */ 685 if (errstring = readdisklabel(MAKESDDEV(0, sd->sc_dev.dv_unit, 686 RAW_PART), sdstrategy, &sd->sc_dk.dk_label, 687 &sd->sc_dk.dk_cpulabel)) { 688 printf("%s: %s\n", sd->sc_dev.dv_xname, errstring); 689 return; 690 } 691 } 692 693 /* 694 * Find out from the device what it's capacity is 695 */ 696 u_long 697 sd_size(sd, flags) 698 struct sd_softc *sd; 699 int flags; 700 { 701 struct scsi_read_cap_data rdcap; 702 struct scsi_read_capacity scsi_cmd; 703 u_long size; 704 705 /* 706 * make up a scsi command and ask the scsi driver to do 707 * it for you. 708 */ 709 bzero(&scsi_cmd, sizeof(scsi_cmd)); 710 scsi_cmd.opcode = READ_CAPACITY; 711 712 /* 713 * If the command works, interpret the result as a 4 byte 714 * number of blocks 715 */ 716 if (scsi_scsi_cmd(sd->sc_link, (struct scsi_generic *)&scsi_cmd, 717 sizeof(scsi_cmd), (u_char *)&rdcap, sizeof(rdcap), SDRETRIES, 718 2000, NULL, flags | SCSI_DATA_IN) != 0) 719 return 0; 720 721 size = (rdcap.addr_3 << 24) + (rdcap.addr_2 << 16) + 722 (rdcap.addr_1 << 8) + rdcap.addr_0 + 1; 723 724 return size; 725 } 726 727 /* 728 * Tell the device to map out a defective block 729 */ 730 int 731 sd_reassign_blocks(sd, block) 732 struct sd_softc *sd; 733 u_long block; 734 { 735 struct scsi_reassign_blocks scsi_cmd; 736 struct scsi_reassign_blocks_data rbdata; 737 738 bzero(&scsi_cmd, sizeof(scsi_cmd)); 739 bzero(&rbdata, sizeof(rbdata)); 740 scsi_cmd.opcode = REASSIGN_BLOCKS; 741 742 rbdata.length_msb = 0; 743 rbdata.length_lsb = sizeof(rbdata.defect_descriptor[0]); 744 rbdata.defect_descriptor[0].dlbaddr_3 = ((block >> 24) & 0xff); 745 rbdata.defect_descriptor[0].dlbaddr_2 = ((block >> 16) & 0xff); 746 rbdata.defect_descriptor[0].dlbaddr_1 = ((block >> 8) & 0xff); 747 rbdata.defect_descriptor[0].dlbaddr_0 = ((block) & 0xff); 748 749 return scsi_scsi_cmd(sd->sc_link, (struct scsi_generic *)&scsi_cmd, 750 sizeof(scsi_cmd), (u_char *)&rbdata, sizeof(rbdata), SDRETRIES, 751 5000, NULL, SCSI_DATA_OUT); 752 } 753 754 #define b2tol(a) (((unsigned)(a##_1) << 8) + (unsigned)a##_0 ) 755 756 /* 757 * Get the scsi driver to send a full inquiry to the * device and use the 758 * results to fill out the disk parameter structure. 759 */ 760 int 761 sd_get_parms(sd, flags) 762 struct sd_softc *sd; 763 int flags; 764 { 765 struct disk_parms *dp = &sd->params; 766 struct scsi_mode_sense scsi_cmd; 767 struct scsi_mode_sense_data { 768 struct scsi_mode_header header; 769 struct scsi_blk_desc blk_desc; 770 union disk_pages pages; 771 } scsi_sense; 772 u_long sectors; 773 774 /* 775 * do a "mode sense page 4" 776 */ 777 bzero(&scsi_cmd, sizeof(scsi_cmd)); 778 scsi_cmd.opcode = MODE_SENSE; 779 scsi_cmd.page = 4; 780 scsi_cmd.length = 0x20; 781 /* 782 * If the command worked, use the results to fill out 783 * the parameter structure 784 */ 785 if (scsi_scsi_cmd(sd->sc_link, (struct scsi_generic *)&scsi_cmd, 786 sizeof(scsi_cmd), (u_char *)&scsi_sense, sizeof(scsi_sense), 787 SDRETRIES, 6000, NULL, flags | SCSI_DATA_IN) != 0) { 788 printf("%s: could not mode sense (4)", sd->sc_dev.dv_xname); 789 fake_it: 790 printf("; using fictitious geometry\n"); 791 /* 792 * use adaptec standard fictitious geometry 793 * this depends on which controller (e.g. 1542C is 794 * different. but we have to put SOMETHING here..) 795 */ 796 sectors = sd_size(sd, flags); 797 dp->heads = 64; 798 dp->sectors = 32; 799 dp->cyls = sectors / (64 * 32); 800 dp->blksize = 512; 801 dp->disksize = sectors; 802 } else { 803 SC_DEBUG(sd->sc_link, SDEV_DB3, 804 ("%d cyls, %d heads, %d precomp, %d red_write, %d land_zone\n", 805 _3btol(&scsi_sense.pages.rigid_geometry.ncyl_2), 806 scsi_sense.pages.rigid_geometry.nheads, 807 b2tol(scsi_sense.pages.rigid_geometry.st_cyl_wp), 808 b2tol(scsi_sense.pages.rigid_geometry.st_cyl_rwc), 809 b2tol(scsi_sense.pages.rigid_geometry.land_zone))); 810 811 /* 812 * KLUDGE!! (for zone recorded disks) 813 * give a number of sectors so that sec * trks * cyls 814 * is <= disk_size 815 * can lead to wasted space! THINK ABOUT THIS ! 816 */ 817 dp->heads = scsi_sense.pages.rigid_geometry.nheads; 818 dp->cyls = 819 _3btol(&scsi_sense.pages.rigid_geometry.ncyl_2); 820 dp->blksize = _3btol(scsi_sense.blk_desc.blklen); 821 822 if (dp->heads == 0 || dp->cyls == 0) { 823 printf("%s: mode sense (4) returned nonsense", 824 sd->sc_dev.dv_xname); 825 goto fake_it; 826 } 827 828 if (dp->blksize == 0) 829 dp->blksize = 512; 830 831 sectors = sd_size(sd, flags); 832 dp->disksize = sectors; 833 sectors /= (dp->heads * dp->cyls); 834 dp->sectors = sectors; /* XXX dubious on SCSI */ 835 } 836 837 return 0; 838 } 839 840 int 841 sdsize(dev) 842 dev_t dev; 843 { 844 struct sd_softc *sd; 845 int part; 846 int size; 847 848 if (sdopen(dev, 0, S_IFBLK) != 0) 849 return -1; 850 sd = sdcd.cd_devs[SDUNIT(dev)]; 851 part = SDPART(dev); 852 if (sd->sc_dk.dk_label.d_partitions[part].p_fstype != FS_SWAP) 853 size = -1; 854 else 855 size = sd->sc_dk.dk_label.d_partitions[part].p_size; 856 if (sdclose(dev, 0, S_IFBLK) != 0) 857 return -1; 858 return size; 859 } 860 861 862 #define SCSIDUMP 1 863 #undef SCSIDUMP 864 #define NOT_TRUSTED 1 865 866 #ifdef SCSIDUMP 867 #include <vm/vm.h> 868 869 static struct scsi_xfer sx; 870 #define MAXTRANSFER 8 /* 1 page at a time */ 871 872 /* 873 * dump all of physical memory into the partition specified, starting 874 * at offset 'dumplo' into the partition. 875 */ 876 int 877 sddump(dev_t dev) 878 { /* dump core after a system crash */ 879 register struct sd_softc *sd; /* disk unit to do the IO */ 880 int32 num; /* number of sectors to write */ 881 u_int32 unit, part; 882 int32 blkoff, blknum, blkcnt = MAXTRANSFER; 883 int32 nblocks; 884 char *addr; 885 struct scsi_rw_big cmd; 886 extern int Maxmem; 887 static int sddoingadump = 0; 888 #define MAPTO CADDR1 889 extern caddr_t MAPTO; /* map the page we are about to write, here */ 890 struct scsi_xfer *xs = &sx; 891 int retval; 892 int c; 893 894 addr = (char *) 0; /* starting address */ 895 896 /* toss any characters present prior to dump */ 897 while ((c = sgetc(1)) && (c != 0x100)); /*syscons and pccons differ */ 898 899 /* size of memory to dump */ 900 num = Maxmem; 901 unit = SDUNIT(dev); /* eventually support floppies? */ 902 part = SDPART(dev); /* file system */ 903 /* check for acceptable drive number */ 904 if (unit >= sdcd.cd_ndevs) 905 return ENXIO; 906 907 sd = sd_softc[unit]; 908 if (!sd) 909 return ENXIO; 910 if (sd->sc_link->flags & SDEV_MEDIA_LOADED != SDEV_MEDIA_LOADED) 911 return ENXIO; 912 913 /* Convert to disk sectors */ 914 num = (u_int32)num * NBPG / sd->sc_dk.dk_label.d_secsize; 915 916 /* check if controller active */ 917 if (sddoingadump) 918 return EFAULT; 919 920 nblocks = sd->sc_dk.dk_label.d_partitions[part].p_size; 921 blkoff = sd->sc_dk.dk_label.d_partitions[part].p_offset; 922 923 /* check transfer bounds against partition size */ 924 if ((dumplo < 0) || ((dumplo + num) > nblocks)) 925 return EINVAL; 926 927 sddoingadump = 1; 928 929 blknum = dumplo + blkoff; 930 while (num > 0) { 931 pmap_enter(pmap_kernel(), 932 MAPTO, 933 trunc_page(addr), 934 VM_PROT_READ, 935 TRUE); 936 #ifndef NOT_TRUSTED 937 /* 938 * Fill out the scsi command 939 */ 940 bzero(&cmd, sizeof(cmd)); 941 cmd.opcode = WRITE_BIG; 942 cmd.addr_3 = (blknum & 0xff000000) >> 24; 943 cmd.addr_2 = (blknum & 0xff0000) >> 16; 944 cmd.addr_1 = (blknum & 0xff00) >> 8; 945 cmd.addr_0 = blknum & 0xff; 946 cmd.length2 = (blkcnt & 0xff00) >> 8; 947 cmd.length1 = (blkcnt & 0xff); 948 /* 949 * Fill out the scsi_xfer structure 950 * Note: we cannot sleep as we may be an interrupt 951 * don't use scsi_scsi_cmd() as it may want 952 * to wait for an xs. 953 */ 954 bzero(xs, sizeof(sx)); 955 xs->flags |= SCSI_AUTOCONF | INUSE; 956 xs->sc_link = sd->sc_link; 957 xs->retries = SDRETRIES; 958 xs->timeout = 10000; /* 10000 millisecs for a disk ! */ 959 xs->cmd = (struct scsi_generic *)&cmd; 960 xs->cmdlen = sizeof(cmd); 961 xs->resid = blkcnt * 512; 962 xs->error = XS_NOERROR; 963 xs->bp = 0; 964 xs->data = (u_char *) MAPTO; 965 xs->datalen = blkcnt * 512; 966 967 /* 968 * Pass all this info to the scsi driver. 969 */ 970 retval = (*(sd->sc_link->adapter->scsi_cmd)) (xs); 971 if (retval != COMPLETE) 972 return ENXIO; 973 #else /* NOT_TRUSTED */ 974 /* lets just talk about this first... */ 975 printf("sd%d: dump addr 0x%x, blk %d\n", unit, addr, blknum); 976 #endif /* NOT_TRUSTED */ 977 978 if ((unsigned)addr % (1024 * 1024) == 0) 979 printf("%d ", num / 2048); 980 /* update block count */ 981 num -= blkcnt; 982 blknum += blkcnt; 983 (int)addr += 512 * blkcnt; 984 985 /* operator aborting dump? */ 986 if ((c = sgetc(1)) && (c != 0x100)) 987 return EINTR; 988 } 989 return 0; 990 } 991 #else /* SCSIDUMP */ 992 int 993 sddump() 994 { 995 printf("\nsddump() -- not implemented\n"); 996 delay(6000000); /* 6 seconds */ 997 return -1; 998 } 999 #endif /* SCSIDUMP */ 1000