1 /* 2 * Copyright (c) 1994 Charles Hannum. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. All advertising materials mentioning features or use of this software 13 * must display the following acknowledgement: 14 * This product includes software developed by Charles Hannum. 15 * 4. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * $Id: sd.c,v 1.30 1994/05/09 07:40:53 chopps Exp $ 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 MAKESDDEV(maj, unit, part) (makedev(maj,(unit<<3)|part)) 79 #define SDPART(z) (minor(z) & 0x07) 80 #define SDUNIT(z) (minor(z) >> 3) 81 #ifndef RAW_PART 82 #define RAW_PART 3 /* XXX should be 2 */ 83 #endif 84 85 struct sd_data { 86 struct device sc_dev; 87 struct dkdevice sc_dk; 88 89 int flags; 90 #define SDHAVELABEL 0x01 /* have read the label */ 91 #define SDDOSPART 0x02 /* Have read the DOS partition table */ 92 #define SDWRITEPROT 0x04 /* Device in readonly mode (S/W) */ 93 struct scsi_link *sc_link; /* contains our targ, lun etc. */ 94 u_int32 ad_info; /* info about the adapter */ 95 u_int32 cmdscount; /* cmds allowed outstanding by board */ 96 boolean wlabel; /* label is writable */ 97 struct disk_parms { 98 u_char heads; /* Number of heads */ 99 u_int16 cyls; /* Number of cylinders */ 100 u_char sectors; /* Number of sectors/track */ 101 u_int32 blksize; /* Number of bytes/sector */ 102 u_long disksize; /* total number sectors */ 103 } params; 104 int partflags[MAXPARTITIONS]; /* per partition flags */ 105 #define SDOPEN 0x01 106 u_int32 openparts; /* one bit for each open partition */ 107 u_int32 xfer_block_wait; 108 struct buf buf_queue; 109 }; 110 111 void sdattach __P((struct device *, struct device *, void *)); 112 113 struct cfdriver sdcd = { 114 NULL, "sd", scsi_targmatch, sdattach, DV_DISK, sizeof(struct sd_data) 115 }; 116 117 int sdgetdisklabel __P((struct sd_data *)); 118 int sd_get_parms __P((struct sd_data *, int)); 119 void sdstrategy __P((struct buf *)); 120 void sdstart __P((int)); 121 122 struct dkdriver sddkdriver = { sdstrategy }; 123 124 struct scsi_device sd_switch = { 125 NULL, /* Use default error handler */ 126 sdstart, /* have a queue, served by this */ 127 NULL, /* have no async handler */ 128 NULL, /* Use default 'done' routine */ 129 "sd", 130 0 131 }; 132 133 /* 134 * The routine called by the low level scsi routine when it discovers 135 * a device suitable for this driver. 136 */ 137 void 138 sdattach(parent, self, aux) 139 struct device *parent, *self; 140 void *aux; 141 { 142 struct sd_data *sd = (void *)self; 143 struct disk_parms *dp = &sd->params; 144 struct scsi_link *sc_link = aux; 145 146 SC_DEBUG(sc_link, SDEV_DB2, ("sdattach: ")); 147 148 /* 149 * Store information needed to contact our base driver 150 */ 151 sd->sc_link = sc_link; 152 sc_link->device = &sd_switch; 153 sc_link->dev_unit = self->dv_unit; 154 155 sd->sc_dk.dk_driver = &sddkdriver; 156 #if !defined(i386) || defined(NEWCONFIG) 157 dk_establish(&sd->sc_dk, &sd->sc_dev); 158 #endif 159 160 if (sd->sc_link->adapter->adapter_info) { 161 sd->ad_info = ((*(sd->sc_link->adapter->adapter_info)) (sc_link->adapter_softc)); 162 sd->cmdscount = sd->ad_info & AD_INF_MAX_CMDS; 163 if (sd->cmdscount > SDOUTSTANDING) 164 sd->cmdscount = SDOUTSTANDING; 165 } else { 166 sd->ad_info = 1; 167 sd->cmdscount = 1; 168 } 169 sc_link->opennings = sd->cmdscount; 170 171 /* 172 * Use the subdriver to request information regarding 173 * the drive. We cannot use interrupts yet, so the 174 * request must specify this. 175 */ 176 sd_get_parms(sd, SCSI_NOSLEEP | SCSI_NOMASK); 177 printf(": %dMB, %d cyl, %d head, %d sec, %d bytes/sec\n", 178 dp->disksize / ((1024L * 1024L) / dp->blksize), dp->cyls, 179 dp->heads, dp->sectors, dp->blksize); 180 } 181 182 /* 183 * open the device. Make sure the partition info is a up-to-date as can be. 184 */ 185 int 186 sdopen(dev) 187 dev_t dev; 188 { 189 int error = 0; 190 int unit, part; 191 struct sd_data *sd; 192 struct scsi_link *sc_link; 193 194 unit = SDUNIT(dev); 195 part = SDPART(dev); 196 197 if (unit >= sdcd.cd_ndevs) 198 return ENXIO; 199 sd = sdcd.cd_devs[unit]; 200 if (!sd) 201 return ENXIO; 202 203 sc_link = sd->sc_link; 204 205 SC_DEBUG(sc_link, SDEV_DB1, 206 ("sdopen: dev=0x%x (unit %d (of %d), partition %d)\n", dev, unit, 207 sdcd.cd_ndevs, part)); 208 209 /* 210 * If it's been invalidated, then forget the label 211 */ 212 if (!(sc_link->flags & SDEV_MEDIA_LOADED)) { 213 sd->flags &= ~SDHAVELABEL; 214 215 /* 216 * If somebody still has it open, then forbid re-entry. 217 */ 218 if (sd->openparts) 219 return ENXIO; 220 } 221 222 /* 223 * "unit attention" errors should occur here if the 224 * drive has been restarted or the pack changed. 225 * just ingnore the result, it's a decoy instruction 226 * The error code will act on the error though 227 * and invalidate any media information we had. 228 */ 229 scsi_test_unit_ready(sc_link, SCSI_SILENT); 230 231 /* 232 * In case it is a funny one, tell it to start 233 * not needed for most hard drives (ignore failure) 234 */ 235 scsi_start(sc_link, SSS_START, SCSI_ERR_OK | SCSI_SILENT); 236 237 /* 238 * Check that it is still responding and ok. 239 */ 240 sc_link->flags |= SDEV_OPEN; /* unit attn becomes an err now */ 241 if (scsi_test_unit_ready(sc_link, 0)) { 242 SC_DEBUG(sc_link, SDEV_DB3, ("device not reponding\n")); 243 error = ENXIO; 244 goto bad; 245 } 246 SC_DEBUG(sc_link, SDEV_DB3, ("device ok\n")); 247 248 /* Lock the pack in. */ 249 scsi_prevent(sc_link, PR_PREVENT, SCSI_ERR_OK | SCSI_SILENT); 250 251 /* 252 * Load the physical device parameters 253 */ 254 if (sd_get_parms(sd, 0)) { 255 error = ENXIO; 256 goto bad; 257 } 258 SC_DEBUG(sc_link, SDEV_DB3, ("Params loaded ")); 259 260 /* 261 * Load the partition info if not already loaded. 262 */ 263 if ((error = sdgetdisklabel(sd)) && (part != RAW_PART)) 264 goto bad; 265 SC_DEBUG(sc_link, SDEV_DB3, ("Disklabel loaded ")); 266 267 /* 268 * Check the partition is legal 269 */ 270 if (part >= sd->sc_dk.dk_label.d_npartitions && part != RAW_PART) { 271 error = ENXIO; 272 goto bad; 273 } 274 SC_DEBUG(sc_link, SDEV_DB3, ("partition ok")); 275 276 /* 277 * Check that the partition exists 278 */ 279 if (sd->sc_dk.dk_label.d_partitions[part].p_fstype == FS_UNUSED && 280 part != RAW_PART) { 281 error = ENXIO; 282 goto bad; 283 } 284 sd->partflags[part] |= SDOPEN; 285 sd->openparts |= (1 << part); 286 SC_DEBUG(sc_link, SDEV_DB3, ("open complete\n")); 287 sc_link->flags |= SDEV_MEDIA_LOADED; 288 return 0; 289 290 bad: 291 if (!sd->openparts) { 292 scsi_prevent(sc_link, PR_ALLOW, SCSI_ERR_OK | SCSI_SILENT); 293 sc_link->flags &= ~SDEV_OPEN; 294 } 295 return error; 296 } 297 298 /* 299 * close the device.. only called if we are the LAST occurence of an open 300 * device. Convenient now but usually a pain. 301 */ 302 int 303 sdclose(dev) 304 dev_t dev; 305 { 306 int unit, part; 307 struct sd_data *sd; 308 309 unit = SDUNIT(dev); 310 part = SDPART(dev); 311 sd = sdcd.cd_devs[unit]; 312 sd->partflags[part] &= ~SDOPEN; 313 sd->openparts &= ~(1 << part); 314 if (!sd->openparts) { 315 scsi_prevent(sd->sc_link, PR_ALLOW, SCSI_ERR_OK | SCSI_SILENT); 316 sd->sc_link->flags &= ~SDEV_OPEN; 317 } 318 return 0; 319 } 320 321 /* 322 * trim the size of the transfer if needed, called by physio 323 * basically the smaller of our max and the scsi driver's 324 * minphys (note we have no max) 325 * 326 * Trim buffer length if buffer-size is bigger than page size 327 */ 328 void 329 sdminphys(bp) 330 struct buf *bp; 331 { 332 register struct sd_data *sd = sdcd.cd_devs[SDUNIT(bp->b_dev)]; 333 334 (sd->sc_link->adapter->scsi_minphys) (bp); 335 } 336 337 /* 338 * Actually translate the requested transfer into one the physical driver 339 * can understand. The transfer is described by a buf and will include 340 * only one physical transfer. 341 */ 342 void 343 sdstrategy(bp) 344 struct buf *bp; 345 { 346 struct buf *dp; 347 int opri; 348 struct sd_data *sd; 349 int unit; 350 351 unit = SDUNIT(bp->b_dev); 352 sd = sdcd.cd_devs[unit]; 353 SC_DEBUG(sd->sc_link, SDEV_DB2, ("sdstrategy ")); 354 SC_DEBUG(sd->sc_link, SDEV_DB1, 355 ("%d bytes @ blk %d\n", bp->b_bcount, bp->b_blkno)); 356 sdminphys(bp); 357 /* 358 * If the device has been made invalid, error out 359 */ 360 if (!(sd->sc_link->flags & SDEV_MEDIA_LOADED)) { 361 sd->flags &= ~SDHAVELABEL; 362 bp->b_error = EIO; 363 goto bad; 364 } 365 /* 366 * "soft" write protect check 367 */ 368 if ((sd->flags & SDWRITEPROT) && (bp->b_flags & B_READ) == 0) { 369 bp->b_error = EROFS; 370 goto bad; 371 } 372 /* 373 * If it's a null transfer, return immediatly 374 */ 375 if (bp->b_bcount == 0) 376 goto done; 377 /* 378 * Decide which unit and partition we are talking about 379 * only raw is ok if no label 380 */ 381 if (SDPART(bp->b_dev) != RAW_PART) { 382 if (!(sd->flags & SDHAVELABEL)) { 383 bp->b_error = EIO; 384 goto bad; 385 } 386 /* 387 * do bounds checking, adjust transfer. if error, process. 388 * if end of partition, just return 389 */ 390 if (bounds_check_with_label(bp, &sd->sc_dk.dk_label, 391 sd->wlabel) <= 0) 392 goto done; 393 /* otherwise, process transfer request */ 394 } 395 opri = splbio(); 396 dp = &sd->buf_queue; 397 398 /* 399 * Place it in the queue of disk activities for this disk 400 */ 401 disksort(dp, bp); 402 403 /* 404 * Tell the device to get going on the transfer if it's 405 * not doing anything, otherwise just wait for completion 406 */ 407 sdstart(unit); 408 409 splx(opri); 410 return; 411 412 bad: 413 bp->b_flags |= B_ERROR; 414 done: 415 416 /* 417 * Correctly set the buf to indicate a completed xfer 418 */ 419 bp->b_resid = bp->b_bcount; 420 biodone(bp); 421 } 422 423 /* 424 * sdstart looks to see if there is a buf waiting for the device 425 * and that the device is not already busy. If both are true, 426 * It dequeues the buf and creates a scsi command to perform the 427 * transfer in the buf. The transfer request will call scsi_done 428 * on completion, which will in turn call this routine again 429 * so that the next queued transfer is performed. 430 * The bufs are queued by the strategy routine (sdstrategy) 431 * 432 * This routine is also called after other non-queued requests 433 * have been made of the scsi driver, to ensure that the queue 434 * continues to be drained. 435 * 436 * must be called at the correct (highish) spl level 437 * sdstart() is called at splbio from sdstrategy and scsi_done 438 */ 439 void 440 sdstart(unit) 441 int unit; 442 { 443 register struct sd_data *sd = sdcd.cd_devs[unit]; 444 register struct scsi_link *sc_link = sd->sc_link; 445 struct buf *bp = 0; 446 struct buf *dp; 447 struct scsi_rw_big cmd; 448 int blkno, nblks; 449 struct partition *p; 450 451 SC_DEBUG(sc_link, SDEV_DB2, ("sdstart ")); 452 /* 453 * Check if the device has room for another command 454 */ 455 while (sc_link->opennings) { 456 /* 457 * there is excess capacity, but a special waits 458 * It'll need the adapter as soon as we clear out of the 459 * way and let it run (user level wait). 460 */ 461 if (sc_link->flags & SDEV_WAITING) { 462 sc_link->flags &= ~SDEV_WAITING; 463 wakeup((caddr_t)sc_link); 464 return; 465 } 466 467 /* 468 * See if there is a buf with work for us to do.. 469 */ 470 dp = &sd->buf_queue; 471 if ((bp = dp->b_actf) == NULL) /* yes, an assign */ 472 return; 473 dp->b_actf = bp->b_actf; 474 475 /* 476 * If the device has become invalid, abort all the 477 * reads and writes until all files have been closed and 478 * re-openned 479 */ 480 if (!(sc_link->flags & SDEV_MEDIA_LOADED)) { 481 sd->flags &= ~SDHAVELABEL; 482 goto bad; 483 } 484 485 /* 486 * We have a buf, now we know we are going to go through 487 * With this thing.. 488 * 489 * First, translate the block to absolute 490 */ 491 blkno = bp->b_blkno / (sd->params.blksize / DEV_BSIZE); 492 if (SDPART(bp->b_dev) != RAW_PART) { 493 p = &sd->sc_dk.dk_label.d_partitions[SDPART(bp->b_dev)]; 494 blkno += p->p_offset; 495 } 496 nblks = (bp->b_bcount + (sd->params.blksize - 1)) / 497 sd->params.blksize; 498 499 /* 500 * Fill out the scsi command 501 */ 502 bzero(&cmd, sizeof(cmd)); 503 cmd.op_code = (bp->b_flags & B_READ) ? READ_BIG : WRITE_BIG; 504 cmd.addr_3 = (blkno & 0xff000000) >> 24; 505 cmd.addr_2 = (blkno & 0xff0000) >> 16; 506 cmd.addr_1 = (blkno & 0xff00) >> 8; 507 cmd.addr_0 = blkno & 0xff; 508 cmd.length2 = (nblks & 0xff00) >> 8; 509 cmd.length1 = (nblks & 0xff); 510 511 /* 512 * Call the routine that chats with the adapter. 513 * Note: we cannot sleep as we may be an interrupt 514 */ 515 if (scsi_scsi_cmd(sc_link, (struct scsi_generic *) &cmd, 516 sizeof(cmd), (u_char *) bp->b_un.b_addr, bp->b_bcount, 517 SDRETRIES, 10000, bp, SCSI_NOSLEEP | 518 ((bp->b_flags & B_READ) ? SCSI_DATA_IN : SCSI_DATA_OUT)) 519 != SUCCESSFULLY_QUEUED) { 520 bad: 521 printf("%s: not queued", sd->sc_dev.dv_xname); 522 bp->b_error = EIO; 523 bp->b_flags |= B_ERROR; 524 biodone(bp); 525 } 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(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