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