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