1 /* 2 * Copyright (c) 1992 OMRON Corporation. 3 * Copyright (c) 1992, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * OMRON Corporation. 8 * 9 * %sccs.include.redist.c% 10 * 11 * @(#)sd.c 8.3 (Berkeley) 12/07/93 12 */ 13 14 /* 15 * sd.c -- SCSI Disk Device Driver 16 * remaked by A.Fujita, MAR-22-1992 17 */ 18 19 /* 20 * SCSI CCS (Command Command Set) disk driver. 21 */ 22 #include "sd.h" 23 #if NSD > 0 24 25 #include <sys/param.h> 26 #include <sys/systm.h> 27 #include <sys/buf.h> 28 #include <sys/dkstat.h> 29 #include <sys/proc.h> 30 #include <sys/disklabel.h> 31 32 #include <luna68k/dev/device.h> 33 #include <luna68k/dev/screg.h> 34 #include <luna68k/dev/scvar.h> 35 36 int sdinit(), sdstrategy(), sdstart(), sdintr(); 37 38 struct driver sddriver = { 39 sdinit, "sd", sdstart, (int (*)()) 0, sdintr, (int (*)()) 0 40 }; 41 42 struct disklabel sdlabel[NSD]; 43 44 struct sd_softc { 45 struct hp_device *sc_hd; 46 struct scsi_queue sc_dq; 47 short sc_flags; 48 short sc_type; /* drive type */ 49 short sc_punit; /* physical unit (scsi lun) */ 50 u_int sc_blks; /* number of blocks on device */ 51 int sc_blksize; /* device block size in bytes */ 52 u_int sc_wpms; /* average xfer rate in 16 bit wds/sec. */ 53 } sd_softc[NSD]; 54 55 /* sc_flags values */ 56 #define SDF_ALIVE 0x1 57 58 struct buf sdtab[NSD]; 59 struct scsi_fmt_sense sdsense[NSD]; 60 61 static struct scsi_fmt_cdb sd_read_cmd = { 10, CMD_READ_EXT }; 62 static struct scsi_fmt_cdb sd_write_cmd = { 10, CMD_WRITE_EXT }; 63 64 #define sdunit(x) ((minor(x) >> 3) & 0x7) 65 #define sdpart(x) (minor(x) & 0x7) 66 #define sdpunit(x) ((x) & 7) 67 #define sdminor(unit, part) (((unit) << 3) | (part)) 68 69 #define b_lba b_resid 70 71 #define SDRETRY 3 /* IO retry count */ 72 73 struct sd_iostat { 74 int imax; 75 int imin; 76 int omax; 77 int omin; 78 }; 79 80 struct sd_iostat sd_iostat[NSD] = { 81 { 14000, -1, 100, -1 }, 82 }; 83 84 /* 85 * Initialize 86 */ 87 88 int 89 sdinit(hd) 90 register struct hp_device *hd; 91 { 92 register struct sd_softc *sc = &sd_softc[hd->hp_unit]; 93 register struct disklabel *lp; 94 char *msg, *sdreadlabel(); 95 96 sc->sc_hd = hd; 97 sc->sc_punit = sdpunit(hd->hp_flags); 98 sc->sc_type = sdident(sc, hd); 99 if (sc->sc_type < 0) 100 return(0); 101 sc->sc_dq.dq_ctlr = hd->hp_ctlr; 102 sc->sc_dq.dq_unit = hd->hp_unit; 103 sc->sc_dq.dq_slave = hd->hp_slave; 104 sc->sc_dq.dq_driver = &sddriver; 105 106 /* 107 * Use the default sizes until we've read the label, 108 * or longer if there isn't one there. 109 */ 110 lp = &sdlabel[hd->hp_unit]; 111 112 if (lp->d_secpercyl == 0) { 113 lp->d_secsize = DEV_BSIZE; 114 lp->d_nsectors = 32; 115 lp->d_ntracks = 20; 116 lp->d_secpercyl = 32*20; 117 lp->d_npartitions = 1; 118 lp->d_partitions[0].p_offset = 0; 119 lp->d_partitions[0].p_size = LABELSECTOR + 1; 120 } 121 122 /* 123 * read disklabel 124 */ 125 if (msg = sdreadlabel(makedev(4, (hd->hp_unit<<3)), sdstrategy, lp)) { 126 if (msg != NULL) { 127 printf("sd%d: %s\n", hd->hp_unit, msg); 128 return(0); 129 } 130 } 131 132 sc->sc_flags = SDF_ALIVE; 133 return(1); 134 } 135 136 static struct scsi_inquiry inqbuf; 137 static struct scsi_fmt_cdb inq = { 138 6, 139 CMD_INQUIRY, 0, 0, 0, sizeof(inqbuf), 0 140 }; 141 142 static u_long capbuf[2]; 143 struct scsi_fmt_cdb cap = { 144 10, 145 CMD_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0 146 }; 147 148 int 149 sdident(sc, hd) 150 struct sd_softc *sc; 151 struct hp_device *hd; 152 { 153 char idstr[32]; 154 int unit; 155 register int ctlr, slave; 156 register int i; 157 register int tries = 10; 158 159 ctlr = hd->hp_ctlr; 160 slave = hd->hp_slave; 161 unit = sc->sc_punit; 162 163 /* 164 * See if unit exists and is a disk then read block size & nblocks. 165 */ 166 while ((i = sc_test_unit_rdy(ctlr, slave, unit)) != 0) { 167 if (i < 0 || --tries < 0) 168 return (-1); 169 if (i == STS_CHECKCOND) { 170 u_char sensebuf[8]; 171 struct scsi_xsense *sp = (struct scsi_xsense *)sensebuf; 172 173 sc_request_sense(ctlr, slave, unit, sensebuf, 8); 174 if (sp->class == 7 && sp->key == 6) 175 /* drive doing an RTZ -- give it a while */ 176 DELAY(1000000); 177 } 178 DELAY(1000); 179 } 180 if (scsi_immed_command(ctlr, slave, unit, &inq, (u_char *)&inqbuf, 181 sizeof(inqbuf)) || 182 scsi_immed_command(ctlr, slave, unit, &cap, (u_char *)&capbuf, 183 sizeof(capbuf))) 184 /* doesn't exist or not a CCS device */ 185 return (-1); 186 187 switch (inqbuf.type) { 188 case 0: /* disk */ 189 case 4: /* WORM */ 190 case 5: /* CD-ROM */ 191 case 7: /* Magneto-optical */ 192 break; 193 default: /* not a disk */ 194 return (-1); 195 } 196 sc->sc_blks = capbuf[0]; 197 sc->sc_blksize = capbuf[1]; 198 199 bcopy((caddr_t)&inqbuf.vendor_id, (caddr_t)idstr, 28); 200 for (i = 27; i > 23; --i) 201 if (idstr[i] != ' ') 202 break; 203 idstr[i+1] = 0; 204 for (i = 23; i > 7; --i) 205 if (idstr[i] != ' ') 206 break; 207 idstr[i+1] = 0; 208 for (i = 7; i >= 0; --i) 209 if (idstr[i] != ' ') 210 break; 211 idstr[i+1] = 0; 212 printf("sd%d: %s %s rev %s", hd->hp_unit, idstr, &idstr[8], 213 &idstr[24]); 214 215 printf(", %d %d byte blocks\n", sc->sc_blks, sc->sc_blksize); 216 if (sc->sc_blksize != DEV_BSIZE) { 217 printf("sd%d: need %d byte blocks - drive ignored\n", unit, DEV_BSIZE); 218 return(1); 219 } 220 221 sc->sc_wpms = 32 * (60 * DEV_BSIZE / 2); /* XXX */ 222 return(inqbuf.type); 223 } 224 225 226 /* 227 * Open 228 */ 229 230 int 231 sdopen(dev, flags, mode, p) 232 dev_t dev; 233 int flags, mode; 234 struct proc *p; 235 { 236 register int unit = sdunit(dev); 237 register struct sd_softc *sc = &sd_softc[unit]; 238 239 if (unit >= NSD) 240 return(ENXIO); 241 if ((sc->sc_flags & SDF_ALIVE) == 0 && suser(p->p_ucred, &p->p_acflag)) 242 return(ENXIO); 243 244 if (sc->sc_hd->hp_dk >= 0) 245 dk_wpms[sc->sc_hd->hp_dk] = sc->sc_wpms; 246 return(0); 247 } 248 249 250 /* 251 * Close 252 */ 253 254 int 255 sdclose(dev, flag, mode, p) 256 dev_t dev; 257 int flag, mode; 258 struct proc *p; 259 { 260 return(0); 261 } 262 263 /* 264 * Strategy 265 */ 266 267 int 268 sdstrategy(bp) 269 register struct buf *bp; 270 { 271 register int unit = sdunit(bp->b_dev); 272 register int part = sdpart(bp->b_dev); 273 register struct sd_softc *sc = &sd_softc[unit]; 274 register struct disklabel *lp = &sdlabel[unit]; 275 register struct partition *pp = &(lp->d_partitions[part]); 276 register struct buf *dp = &sdtab[unit]; 277 register daddr_t bn; 278 register int sz, s; 279 280 bn = bp->b_blkno; 281 sz = howmany(bp->b_bcount, DEV_BSIZE); 282 283 /* check that tracsfer is within a drive's partition */ 284 285 if (bn < 0 || (bn + sz) > pp->p_size) { 286 sz = pp->p_size - bn; 287 if (sz == 0) { 288 bp->b_resid = bp->b_bcount; 289 goto done; 290 } 291 if (sz < 0) { 292 bp->b_error = EINVAL; 293 bp->b_flags |= B_ERROR; 294 goto done; 295 } 296 bp->b_bcount = dbtob(sz); 297 } 298 299 /* calculate LBA for transfer */ 300 301 bp->b_lba = bn + pp->p_offset; 302 303 /* raise priority to block sdintr */ 304 305 s = splbio(); 306 307 /* call disksort to sort request into drive queue */ 308 309 disksort(dp, bp); 310 311 if (dp->b_active == 0) { /* */ 312 dp->b_active = 1; 313 sdustart(unit); 314 } 315 316 /* lower priority */ 317 318 splx(s); 319 320 return; 321 322 done: 323 biodone(bp); 324 } 325 326 int 327 sdustart(unit) 328 register int unit; 329 { 330 register struct sd_softc *sc = &sd_softc[unit]; 331 register struct hp_device *hp = sc->sc_hd; 332 register struct scsi_queue *dq = &sc->sc_dq; 333 register struct buf *bp = sdtab[unit].b_actf; 334 register struct scsi_fmt_cdb *cmd; 335 336 cmd = bp->b_flags & B_READ? &sd_read_cmd : &sd_write_cmd; 337 *(int *)(&cmd->cdb[2]) = bp->b_lba; 338 *(u_short *)(&cmd->cdb[7]) = howmany(bp->b_bcount, DEV_BSIZE); 339 340 dq->dq_cdb = cmd; 341 dq->dq_bp = bp; 342 dq->dq_flags = DQ_DISCONNECT; /* SCSI Disconnect */ 343 344 if (screq(dq)) 345 sdstart(unit); 346 } 347 348 int 349 sdstart(unit) 350 register int unit; 351 { 352 register struct sd_softc *sc = &sd_softc[unit]; 353 register struct hp_device *hp = sc->sc_hd; 354 355 if (hp->hp_dk >= 0) { 356 dk_busy |= 1 << hp->hp_dk; 357 } 358 359 scstart(hp->hp_ctlr); 360 } 361 362 363 /* 364 * Return: 365 * 0 if not really an error 366 * <0 if we should do a retry 367 * >0 if a fatal error 368 */ 369 static int 370 sderror(unit, sc, hp, stat) 371 int unit, stat; 372 register struct sd_softc *sc; 373 register struct hp_device *hp; 374 { 375 int cond = 1; 376 377 sdsense[unit].status = stat; 378 if (stat & STS_CHECKCOND) { 379 struct scsi_xsense *sp; 380 381 sc_request_sense(hp->hp_ctlr, hp->hp_slave, 382 sc->sc_punit, sdsense[unit].sense, 383 sizeof(sdsense[unit].sense)); 384 sp = (struct scsi_xsense *)sdsense[unit].sense; 385 printf("sd%d: scsi sense class %d, code %d", unit, 386 sp->class, sp->code); 387 if (sp->class == 7) { 388 printf(", key %d", sp->key); 389 if (sp->valid) 390 printf(", blk %d", *(int *)&sp->info1); 391 switch (sp->key) { 392 /* no sense, try again */ 393 case 0: 394 cond = -1; 395 break; 396 /* recovered error, not a problem */ 397 case 1: 398 cond = 0; 399 break; 400 } 401 } 402 printf("\n"); 403 } 404 return(cond); 405 } 406 407 /* 408 * Interrupt 409 */ 410 411 int 412 sdintr(unit, stat) 413 register int unit; 414 int stat; 415 { 416 register struct sd_softc *sc = &sd_softc[unit]; 417 register struct hp_device *hp = sc->sc_hd; 418 register struct scsi_queue *dq = &sc->sc_dq; 419 register struct buf *bp = dq->dq_bp; 420 int cond; 421 422 if (stat == SC_IO_TIMEOUT) { 423 printf("sdintr: sd%d timeout error\n", unit, stat); 424 } 425 426 if (hp->hp_dk >= 0) { 427 dk_busy &=~ (1 << hp->hp_dk); 428 if (stat == 0) { 429 ++dk_seek[hp->hp_dk]; 430 ++dk_xfer[hp->hp_dk]; 431 dk_wds[hp->hp_dk] += bp->b_bcount >> 6; 432 } 433 } 434 435 if (bp->b_flags & B_READ) { 436 sd_iostat[unit].imin = min(dq->dq_imin, sd_iostat[unit].imin); 437 if (dq->dq_imax > sd_iostat[unit].imax) { 438 sd_iostat[unit].imax = dq->dq_imax; 439 #ifdef SD_IOSTAT 440 printf("sdintr: sd%d INPUT MAX = %d, MIN = %d\n", 441 unit, sd_iostat[unit].imax, sd_iostat[unit].imin); 442 #endif 443 } 444 } else { 445 sd_iostat[unit].omin = min(dq->dq_omin, sd_iostat[unit].omin); 446 if (dq->dq_omax > sd_iostat[unit].omax) { 447 sd_iostat[unit].omax = dq->dq_omax; 448 #ifdef SD_IOSTAT 449 printf("sdintr: sd%d OUTPUT MAX = %d, MIN = %d\n", 450 unit, sd_iostat[unit].omax, sd_iostat[unit].omin); 451 #endif 452 } 453 } 454 455 if (stat != 0) { 456 if (stat > 0) { 457 #ifdef DEBUGPRINT 458 dbgprintall(); 459 printf("\n"); 460 #endif 461 cond = sderror(unit, sc, hp, stat); 462 if (cond) { 463 if (cond < 0 && sdtab[unit].b_errcnt++ < SDRETRY) { 464 sdstart(unit); 465 return; 466 } 467 } 468 } else { 469 if (sdtab[unit].b_errcnt++ < SDRETRY) { 470 printf("sdintr: sd%d restart IO request\n", unit); 471 sdstart(unit); 472 return; 473 } 474 } 475 bp->b_flags |= B_ERROR; 476 bp->b_error = EIO; 477 } 478 479 sdtab[unit].b_errcnt = 0; 480 sdtab[unit].b_actf = bp->b_actf; 481 482 bp->b_resid = 0; 483 484 biodone(bp); 485 486 scfree(dq); 487 488 if (sdtab[unit].b_actf) { 489 sdustart(unit); 490 } else { 491 sdtab[unit].b_active = 0; 492 } 493 } 494 495 496 /* 497 * RAW Device Routines 498 */ 499 500 int 501 sdread(dev, uio, flags) 502 dev_t dev; 503 struct uio *uio; 504 int flags; 505 { 506 register int unit = sdunit(dev); 507 508 return (physio(sdstrategy, NULL, dev, B_READ, minphys, uio)); 509 } 510 511 int 512 sdwrite(dev, uio, flags) 513 dev_t dev; 514 struct uio *uio; 515 int flags; 516 { 517 register int unit = sdunit(dev); 518 519 return (physio(sdstrategy, NULL, dev, B_WRITE, minphys, uio)); 520 } 521 522 int 523 sdioctl(dev, cmd, data, flag, p) 524 dev_t dev; 525 int cmd; 526 caddr_t data; 527 int flag; 528 struct proc *p; 529 { 530 int unit = sdunit(dev); 531 register struct sd_softc *sc = &sd_softc[unit]; 532 register struct disklabel *lp = &sdlabel[unit]; 533 int error = 0; 534 535 switch (cmd) { 536 537 case DIOCGDINFO: 538 *(struct disklabel *)data = *lp; 539 break; 540 541 case DIOCGPART: 542 ((struct partinfo *)data)->disklab = lp; 543 ((struct partinfo *)data)->part = 544 &lp->d_partitions[sdpart(dev)]; 545 break; 546 547 case DIOCWLABEL: 548 case DIOCSDINFO: 549 case DIOCWDINFO: 550 break; 551 552 default: 553 error = ENOTTY; 554 break; 555 } 556 return (error); 557 } 558 559 560 /* 561 * Size 562 */ 563 564 int 565 sdsize(dev) 566 dev_t dev; 567 { 568 register int unit = sdunit(dev); 569 register struct sd_softc *sc = &sd_softc[unit]; 570 571 if (unit >= NSD || (sc->sc_flags & SDF_ALIVE) == 0) 572 return(-1); 573 574 return(sdlabel[unit].d_partitions[sdpart(dev)].p_size); 575 } 576 577 578 /* 579 * Dump 580 */ 581 582 int 583 sddump(dev) 584 dev_t dev; 585 { 586 } 587 588 /* 589 * Disk Subs 590 */ 591 592 /* 593 * Attempt to read a disk label from a device 594 * using the indicated stategy routine. 595 * The label must be partly set up before this: 596 * secpercyl and anything required in the strategy routine 597 * (e.g., sector size) must be filled in before calling us. 598 * Returns null on success and an error string on failure. 599 */ 600 char * 601 sdreadlabel(dev, strat, lp) 602 dev_t dev; 603 int (*strat)(); 604 register struct disklabel *lp; 605 { 606 register struct buf *bp; 607 struct disklabel *dlp; 608 char *msg = NULL; 609 610 if (lp->d_secperunit == 0) 611 lp->d_secperunit = 0x1fffffff; 612 lp->d_npartitions = 1; 613 if (lp->d_partitions[0].p_size == 0) 614 lp->d_partitions[0].p_size = 0x1fffffff; 615 lp->d_partitions[0].p_offset = 0; 616 617 bp = geteblk((int)lp->d_secsize); 618 bp->b_dev = dev; 619 bp->b_blkno = LABELSECTOR; 620 bp->b_bcount = lp->d_secsize; 621 bp->b_flags = B_BUSY | B_READ; 622 (*strat)(bp); 623 if (biowait(bp)) { 624 msg = "I/O error"; 625 } else { 626 for (dlp = (struct disklabel *)bp->b_un.b_addr; 627 dlp <= (struct disklabel *)(bp->b_un.b_addr+DEV_BSIZE-sizeof(*dlp)); 628 dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { 629 if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) { 630 if (msg == NULL) 631 msg = "no disk label"; 632 } else if (dlp->d_npartitions > MAXPARTITIONS || 633 dkcksum(dlp) != 0) 634 msg = "disk label corrupted"; 635 else { 636 *lp = *dlp; 637 msg = NULL; 638 break; 639 } 640 } 641 } 642 bp->b_flags = B_INVAL | B_AGE; 643 brelse(bp); 644 return (msg); 645 } 646 647 #ifdef notyet 648 649 /* 650 * Checksum routine for OMRON native disklabel 651 */ 652 653 #define OMRON_LBLSIZE 512 654 655 u_short 656 omcksum(omp) 657 register char *omp; 658 { 659 register u_short *start, *end; 660 register u_short sum = 0; 661 662 start = (u_short *) omp; 663 end = (u_short *) &start[(OMRON_LBLSIZE/sizeof(u_short) - 1)]; 664 while (start < end) 665 sum ^= *start++; 666 667 printf("omcksum: saved ... 0x%s\n", hexstr(*end, 4)); 668 printf("omcksum: calced ... 0x%s\n", hexstr(sum, 4)); 669 670 return (sum); 671 } 672 673 /* 674 * Write disk label back to device after modification. 675 */ 676 sdwritelabel(dev, strat, lp) 677 dev_t dev; 678 int (*strat)(); 679 register struct disklabel *lp; 680 { 681 struct buf *bp; 682 struct disklabel *dlp; 683 int labelpart; 684 int error = 0; 685 686 labelpart = sdpart(dev); 687 if (lp->d_partitions[labelpart].p_offset != 0) { 688 if (lp->d_partitions[0].p_offset != 0) 689 return (EXDEV); /* not quite right */ 690 labelpart = 0; 691 } 692 693 bp = geteblk((int)lp->d_secsize); 694 bp->b_dev = makedev(major(dev), sdminor(sdunit(dev), labelpart)); 695 bp->b_blkno = LABELSECTOR; 696 bp->b_bcount = lp->d_secsize; 697 bp->b_flags = B_READ; 698 (*strat)(bp); 699 if (error = biowait(bp)) 700 goto done; 701 702 for (dlp = (struct disklabel *)bp->b_un.b_addr; 703 dlp <= (struct disklabel *) 704 (bp->b_un.b_addr + lp->d_secsize - sizeof(*dlp)); 705 dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { 706 if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC && 707 dkcksum(dlp) == 0) { 708 omcksum(bp->b_un.b_addr); 709 /* 710 *dlp = *lp; 711 bp->b_flags = B_WRITE; 712 (*strat)(bp); 713 error = biowait(bp); 714 goto done; 715 */ 716 } 717 } 718 error = ESRCH; 719 done: 720 brelse(bp); 721 return (error); 722 } 723 #endif 724 725 #endif 726