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