1 /* 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Van Jacobson of Lawrence Berkeley Laboratory. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)sd.c 7.17 (Berkeley) 12/27/92 11 */ 12 13 /* 14 * SCSI CCS (Command Command Set) disk driver. 15 */ 16 #include "sd.h" 17 #if NSD > 0 18 19 #ifndef lint 20 static char rcsid[] = "$Header: /usr/src/sys/hp300/dev/RCS/sd.c,v 1.4 92/12/26 13:26:40 mike Exp $"; 21 #endif 22 23 #include <sys/param.h> 24 #include <sys/systm.h> 25 #include <sys/buf.h> 26 #include <sys/stat.h> 27 #include <sys/dkstat.h> 28 #include <sys/disklabel.h> 29 #include <sys/malloc.h> 30 #include <sys/proc.h> 31 #include <sys/ioctl.h> 32 #include <sys/fcntl.h> 33 34 #include <hp/dev/device.h> 35 #include <hp300/dev/scsireg.h> 36 #include <hp300/dev/sdvar.h> 37 #ifdef USELEDS 38 #include <hp300/hp300/led.h> 39 #endif 40 41 #include <vm/vm_param.h> 42 #include <vm/lock.h> 43 #include <vm/vm_prot.h> 44 #include <vm/pmap.h> 45 46 extern int scsi_test_unit_rdy(); 47 extern int scsi_request_sense(); 48 extern int scsi_inquiry(); 49 extern int scsi_read_capacity(); 50 extern int scsi_tt_write(); 51 extern int scsireq(); 52 extern int scsiustart(); 53 extern int scsigo(); 54 extern void scsifree(); 55 extern void scsireset(); 56 extern void scsi_delay(); 57 58 extern void disksort(); 59 extern void biodone(); 60 extern int physio(); 61 extern void TBIS(); 62 63 int sdinit(); 64 void sdstrategy(), sdstart(), sdustart(), sdgo(), sdintr(); 65 66 struct driver sddriver = { 67 sdinit, "sd", (int (*)())sdstart, (int (*)())sdgo, (int (*)())sdintr, 68 }; 69 70 #ifdef DEBUG 71 int sddebug = 1; 72 #define SDB_ERROR 0x01 73 #define SDB_PARTIAL 0x02 74 #endif 75 76 struct sd_softc sd_softc[NSD]; 77 struct sdstats sdstats[NSD]; 78 struct buf sdtab[NSD]; 79 struct scsi_fmt_cdb sdcmd[NSD]; 80 struct scsi_fmt_sense sdsense[NSD]; 81 82 static struct scsi_fmt_cdb sd_read_cmd = { 10, CMD_READ_EXT }; 83 static struct scsi_fmt_cdb sd_write_cmd = { 10, CMD_WRITE_EXT }; 84 85 /* 86 * Table of scsi commands users are allowed to access via "format" 87 * mode. 0 means not legal. 1 means "immediate" (doesn't need dma). 88 * -1 means needs dma and/or wait for intr. 89 */ 90 static char legal_cmds[256] = { 91 /***** 0 1 2 3 4 5 6 7 8 9 A B C D E F */ 92 /*00*/ 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93 /*10*/ 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 94 /*20*/ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95 /*30*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96 /*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97 /*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98 /*60*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99 /*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100 /*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101 /*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102 /*a0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103 /*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104 /*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105 /*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106 /*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107 /*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108 }; 109 110 static struct scsi_inquiry inqbuf; 111 static struct scsi_fmt_cdb inq = { 112 6, 113 CMD_INQUIRY, 0, 0, 0, sizeof(inqbuf), 0 114 }; 115 116 static u_char capbuf[8]; 117 struct scsi_fmt_cdb cap = { 118 10, 119 CMD_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0 120 }; 121 122 static int 123 sdident(sc, hd) 124 struct sd_softc *sc; 125 struct hp_device *hd; 126 { 127 int unit; 128 register int ctlr, slave; 129 register int i; 130 register int tries = 10; 131 char idstr[32]; 132 int ismo = 0; 133 134 ctlr = hd->hp_ctlr; 135 slave = hd->hp_slave; 136 unit = sc->sc_punit; 137 scsi_delay(-1); 138 139 /* 140 * See if unit exists and is a disk then read block size & nblocks. 141 */ 142 while ((i = scsi_test_unit_rdy(ctlr, slave, unit)) != 0) { 143 if (i == -1 || --tries < 0) { 144 if (ismo) 145 break; 146 /* doesn't exist or not a CCS device */ 147 goto failed; 148 } 149 if (i == STS_CHECKCOND) { 150 u_char sensebuf[128]; 151 struct scsi_xsense *sp = (struct scsi_xsense *)sensebuf; 152 153 scsi_request_sense(ctlr, slave, unit, sensebuf, 154 sizeof(sensebuf)); 155 if (sp->class == 7) 156 switch (sp->key) { 157 /* not ready -- might be MO with no media */ 158 case 2: 159 if (sp->len == 12 && 160 sensebuf[12] == 10) /* XXX */ 161 ismo = 1; 162 break; 163 /* drive doing an RTZ -- give it a while */ 164 case 6: 165 DELAY(1000000); 166 break; 167 default: 168 break; 169 } 170 } 171 DELAY(1000); 172 } 173 /* 174 * Find out about device 175 */ 176 if (scsi_immed_command(ctlr, slave, unit, &inq, 177 (u_char *)&inqbuf, sizeof(inqbuf), B_READ)) 178 goto failed; 179 switch (inqbuf.type) { 180 case 0: /* disk */ 181 case 4: /* WORM */ 182 case 5: /* CD-ROM */ 183 case 7: /* Magneto-optical */ 184 break; 185 default: /* not a disk */ 186 goto failed; 187 } 188 /* 189 * Get a usable id string 190 */ 191 switch (inqbuf.version) { 192 case 1: 193 case 2: 194 bcopy((caddr_t)&inqbuf.vendor_id, (caddr_t)idstr, 28); 195 for (i = 27; i > 23; --i) 196 if (idstr[i] != ' ') 197 break; 198 idstr[i+1] = 0; 199 for (i = 23; i > 7; --i) 200 if (idstr[i] != ' ') 201 break; 202 idstr[i+1] = 0; 203 for (i = 7; i >= 0; --i) 204 if (idstr[i] != ' ') 205 break; 206 idstr[i+1] = 0; 207 break; 208 default: 209 bcopy("UNKNOWN", &idstr[0], 8); 210 bcopy("DRIVE TYPE", &idstr[8], 11); 211 } 212 i = scsi_immed_command(ctlr, slave, unit, &cap, 213 (u_char *)&capbuf, sizeof(capbuf), B_READ); 214 if (i) { 215 if (i != STS_CHECKCOND || 216 bcmp(&idstr[0], "HP", 3) || 217 bcmp(&idstr[8], "S6300.650A", 11)) 218 goto failed; 219 /* XXX unformatted or non-existant MO media; fake it */ 220 sc->sc_blks = 318664; 221 sc->sc_blksize = 1024; 222 } else { 223 sc->sc_blks = *(u_int *)&capbuf[0]; 224 sc->sc_blksize = *(int *)&capbuf[4]; 225 } 226 /* return value of read capacity is last valid block number */ 227 sc->sc_blks++; 228 229 switch (inqbuf.version) { 230 case 1: 231 case 2: 232 printf("sd%d: %s %s rev %s", hd->hp_unit, idstr, &idstr[8], 233 &idstr[24]); 234 if (inqbuf.version == 2) 235 printf(" (SCSI-2)"); 236 break; 237 default: 238 printf("sd%d: type 0x%x, qual 0x%x, ver %d", hd->hp_unit, 239 inqbuf.type, inqbuf.qual, inqbuf.version); 240 break; 241 } 242 printf(", %d %d byte blocks\n", sc->sc_blks, sc->sc_blksize); 243 if (inqbuf.qual & 0x80) 244 sc->sc_flags |= SDF_RMEDIA; 245 if (sc->sc_blksize != DEV_BSIZE) { 246 if (sc->sc_blksize < DEV_BSIZE) { 247 printf("sd%d: need %d byte blocks - drive ignored\n", 248 unit, DEV_BSIZE); 249 goto failed; 250 } 251 for (i = sc->sc_blksize; i > DEV_BSIZE; i >>= 1) 252 ++sc->sc_bshift; 253 sc->sc_blks <<= sc->sc_bshift; 254 } 255 sc->sc_wpms = 32 * (60 * DEV_BSIZE / 2); /* XXX */ 256 scsi_delay(0); 257 return(inqbuf.type); 258 failed: 259 scsi_delay(0); 260 return(-1); 261 } 262 263 int 264 sdinit(hd) 265 register struct hp_device *hd; 266 { 267 register struct sd_softc *sc = &sd_softc[hd->hp_unit]; 268 269 sc->sc_hd = hd; 270 sc->sc_flags = 0; 271 sc->sc_punit = sdpunit(hd->hp_flags); 272 sc->sc_type = sdident(sc, hd); 273 if (sc->sc_type < 0) 274 return(0); 275 sc->sc_dq.dq_ctlr = hd->hp_ctlr; 276 sc->sc_dq.dq_unit = hd->hp_unit; 277 sc->sc_dq.dq_slave = hd->hp_slave; 278 sc->sc_dq.dq_driver = &sddriver; 279 280 sc->sc_flags |= SDF_ALIVE; 281 return(1); 282 } 283 284 void 285 sdreset(sc, hd) 286 register struct sd_softc *sc; 287 register struct hp_device *hd; 288 { 289 sdstats[hd->hp_unit].sdresets++; 290 } 291 292 /* 293 * Read or constuct a disklabel 294 */ 295 int 296 sdgetinfo(dev) 297 dev_t dev; 298 { 299 int unit = sdunit(dev); 300 register struct sd_softc *sc = &sd_softc[unit]; 301 register struct disklabel *lp = &sc->sc_info.si_label; 302 register struct partition *pi; 303 char *msg, *readdisklabel(); 304 305 /* 306 * Set some default values to use while reading the label 307 * or to use if there isn't a label. 308 */ 309 bzero((caddr_t)lp, sizeof *lp); 310 lp->d_type = DTYPE_SCSI; 311 lp->d_secsize = DEV_BSIZE; 312 lp->d_nsectors = 32; 313 lp->d_ntracks = 20; 314 lp->d_secpercyl = 32*20; 315 lp->d_npartitions = 3; 316 lp->d_partitions[2].p_offset = 0; 317 /* XXX ensure size is at least one device block */ 318 lp->d_partitions[2].p_size = 319 roundup(LABELSECTOR+1, btodb(sc->sc_blksize)); 320 321 /* 322 * Now try to read the disklabel 323 */ 324 msg = readdisklabel(sdlabdev(dev), sdstrategy, lp); 325 if (msg == NULL) 326 return(0); 327 if (bcmp(msg, "I/O", 3) == 0) /* XXX */ 328 return(EIO); 329 330 pi = lp->d_partitions; 331 printf("sd%d: WARNING: %s, ", unit, msg); 332 #ifdef COMPAT_NOLABEL 333 printf("using old default partitioning\n"); 334 sdmakedisklabel(unit, lp); 335 #else 336 printf("defining `c' partition as entire disk\n"); 337 pi[2].p_size = sc->sc_blks; 338 #endif 339 return(0); 340 } 341 342 int 343 sdopen(dev, flags, mode, p) 344 dev_t dev; 345 int flags, mode; 346 struct proc *p; 347 { 348 register int unit = sdunit(dev); 349 register struct sd_softc *sc = &sd_softc[unit]; 350 int mask, error; 351 352 if (unit >= NSD) 353 return(ENXIO); 354 if ((sc->sc_flags & SDF_ALIVE) == 0 && suser(p->p_ucred, &p->p_acflag)) 355 return(ENXIO); 356 if (sc->sc_flags & SDF_ERROR) 357 return(EIO); 358 359 /* 360 * Wait for any pending opens/closes to complete 361 */ 362 while (sc->sc_flags & (SDF_OPENING|SDF_CLOSING)) 363 sleep((caddr_t)sc, PRIBIO); 364 /* 365 * On first open, get label and partition info. 366 * We may block reading the label, so be careful 367 * to stop any other opens. 368 */ 369 if (sc->sc_info.si_open == 0) { 370 sc->sc_flags |= SDF_OPENING; 371 error = sdgetinfo(dev); 372 sc->sc_flags &= ~SDF_OPENING; 373 wakeup((caddr_t)sc); 374 if (error) 375 return(error); 376 } 377 if (sc->sc_hd->hp_dk >= 0) 378 dk_wpms[sc->sc_hd->hp_dk] = sc->sc_wpms; 379 380 mask = 1 << sdpart(dev); 381 if (mode == S_IFCHR) 382 sc->sc_info.si_copen |= mask; 383 else 384 sc->sc_info.si_bopen |= mask; 385 sc->sc_info.si_open |= mask; 386 return(0); 387 } 388 389 int 390 sdclose(dev, flag, mode, p) 391 dev_t dev; 392 int flag, mode; 393 struct proc *p; 394 { 395 int unit = sdunit(dev); 396 register struct sd_softc *sc = &sd_softc[unit]; 397 register struct sdinfo *si = &sc->sc_info; 398 int mask, s; 399 400 mask = 1 << sdpart(dev); 401 if (mode == S_IFCHR) 402 si->si_copen &= ~mask; 403 else 404 si->si_bopen &= ~mask; 405 si->si_open = si->si_bopen | si->si_copen; 406 /* 407 * On last close, we wait for all activity to cease since 408 * the label/parition info will become invalid. Since we 409 * might sleep, we must block any opens while we are here. 410 * Note we don't have to about other closes since we know 411 * we are the last one. 412 */ 413 if (si->si_open == 0) { 414 sc->sc_flags |= SDF_CLOSING; 415 s = splbio(); 416 while (sdtab[unit].b_active) { 417 sc->sc_flags |= SDF_WANTED; 418 sleep((caddr_t)&sdtab[unit], PRIBIO); 419 } 420 splx(s); 421 sc->sc_flags &= ~(SDF_CLOSING|SDF_WLABEL|SDF_ERROR); 422 wakeup((caddr_t)sc); 423 } 424 sc->sc_format_pid = 0; 425 return(0); 426 } 427 428 /* 429 * This routine is called for partial block transfers and non-aligned 430 * transfers (the latter only being possible on devices with a block size 431 * larger than DEV_BSIZE). The operation is performed in three steps 432 * using a locally allocated buffer: 433 * 1. transfer any initial partial block 434 * 2. transfer full blocks 435 * 3. transfer any final partial block 436 */ 437 static void 438 sdlblkstrat(bp, bsize) 439 register struct buf *bp; 440 register int bsize; 441 { 442 register struct buf *cbp = (struct buf *)malloc(sizeof(struct buf), 443 M_DEVBUF, M_WAITOK); 444 caddr_t cbuf = (caddr_t)malloc(bsize, M_DEVBUF, M_WAITOK); 445 register int bn, resid; 446 register caddr_t addr; 447 448 bzero((caddr_t)cbp, sizeof(*cbp)); 449 cbp->b_proc = curproc; /* XXX */ 450 cbp->b_dev = bp->b_dev; 451 bn = bp->b_blkno; 452 resid = bp->b_bcount; 453 addr = bp->b_un.b_addr; 454 #ifdef DEBUG 455 if (sddebug & SDB_PARTIAL) 456 printf("sdlblkstrat: bp %x flags %x bn %x resid %x addr %x\n", 457 bp, bp->b_flags, bn, resid, addr); 458 #endif 459 460 while (resid > 0) { 461 register int boff = dbtob(bn) & (bsize - 1); 462 register int count; 463 464 if (boff || resid < bsize) { 465 sdstats[sdunit(bp->b_dev)].sdpartials++; 466 count = min(resid, bsize - boff); 467 cbp->b_flags = B_BUSY | B_PHYS | B_READ; 468 cbp->b_blkno = bn - btodb(boff); 469 cbp->b_un.b_addr = cbuf; 470 cbp->b_bcount = bsize; 471 #ifdef DEBUG 472 if (sddebug & SDB_PARTIAL) 473 printf(" readahead: bn %x cnt %x off %x addr %x\n", 474 cbp->b_blkno, count, boff, addr); 475 #endif 476 sdstrategy(cbp); 477 biowait(cbp); 478 if (cbp->b_flags & B_ERROR) { 479 bp->b_flags |= B_ERROR; 480 bp->b_error = cbp->b_error; 481 break; 482 } 483 if (bp->b_flags & B_READ) { 484 bcopy(&cbuf[boff], addr, count); 485 goto done; 486 } 487 bcopy(addr, &cbuf[boff], count); 488 #ifdef DEBUG 489 if (sddebug & SDB_PARTIAL) 490 printf(" writeback: bn %x cnt %x off %x addr %x\n", 491 cbp->b_blkno, count, boff, addr); 492 #endif 493 } else { 494 count = resid & ~(bsize - 1); 495 cbp->b_blkno = bn; 496 cbp->b_un.b_addr = addr; 497 cbp->b_bcount = count; 498 #ifdef DEBUG 499 if (sddebug & SDB_PARTIAL) 500 printf(" fulltrans: bn %x cnt %x addr %x\n", 501 cbp->b_blkno, count, addr); 502 #endif 503 } 504 cbp->b_flags = B_BUSY | B_PHYS | (bp->b_flags & B_READ); 505 sdstrategy(cbp); 506 biowait(cbp); 507 if (cbp->b_flags & B_ERROR) { 508 bp->b_flags |= B_ERROR; 509 bp->b_error = cbp->b_error; 510 break; 511 } 512 done: 513 bn += btodb(count); 514 resid -= count; 515 addr += count; 516 #ifdef DEBUG 517 if (sddebug & SDB_PARTIAL) 518 printf(" done: bn %x resid %x addr %x\n", 519 bn, resid, addr); 520 #endif 521 } 522 free(cbuf, M_DEVBUF); 523 free(cbp, M_DEVBUF); 524 } 525 526 void 527 sdstrategy(bp) 528 register struct buf *bp; 529 { 530 int unit = sdunit(bp->b_dev); 531 register struct sd_softc *sc = &sd_softc[unit]; 532 register struct buf *dp = &sdtab[unit]; 533 register struct partition *pinfo; 534 register daddr_t bn; 535 register int sz, s; 536 537 if (sc->sc_flags & SDF_ERROR) { 538 bp->b_error = EIO; 539 goto bad; 540 } 541 if (sc->sc_format_pid) { 542 if (sc->sc_format_pid != curproc->p_pid) { /* XXX */ 543 bp->b_error = EPERM; 544 goto bad; 545 } 546 bp->b_cylin = 0; 547 } else { 548 bn = bp->b_blkno; 549 sz = howmany(bp->b_bcount, DEV_BSIZE); 550 pinfo = &sc->sc_info.si_label.d_partitions[sdpart(bp->b_dev)]; 551 if (bn < 0 || bn + sz > pinfo->p_size) { 552 sz = pinfo->p_size - bn; 553 if (sz == 0) { 554 bp->b_resid = bp->b_bcount; 555 goto done; 556 } 557 if (sz < 0) { 558 bp->b_error = EINVAL; 559 goto bad; 560 } 561 bp->b_bcount = dbtob(sz); 562 } 563 /* 564 * Check for write to write protected label 565 */ 566 if (bn + pinfo->p_offset <= LABELSECTOR && 567 #if LABELSECTOR != 0 568 bn + pinfo->p_offset + sz > LABELSECTOR && 569 #endif 570 !(bp->b_flags & B_READ) && !(sc->sc_flags & SDF_WLABEL)) { 571 bp->b_error = EROFS; 572 goto bad; 573 } 574 /* 575 * Non-aligned or partial-block transfers handled specially. 576 */ 577 s = sc->sc_blksize - 1; 578 if ((dbtob(bn) & s) || (bp->b_bcount & s)) { 579 sdlblkstrat(bp, sc->sc_blksize); 580 goto done; 581 } 582 bp->b_cylin = (bn + pinfo->p_offset) >> sc->sc_bshift; 583 } 584 s = splbio(); 585 disksort(dp, bp); 586 if (dp->b_active == 0) { 587 dp->b_active = 1; 588 sdustart(unit); 589 } 590 splx(s); 591 return; 592 bad: 593 bp->b_flags |= B_ERROR; 594 done: 595 biodone(bp); 596 } 597 598 void 599 sdustart(unit) 600 register int unit; 601 { 602 if (scsireq(&sd_softc[unit].sc_dq)) 603 sdstart(unit); 604 } 605 606 /* 607 * Return: 608 * 0 if not really an error 609 * <0 if we should do a retry 610 * >0 if a fatal error 611 */ 612 static int 613 sderror(unit, sc, hp, stat) 614 int unit, stat; 615 register struct sd_softc *sc; 616 register struct hp_device *hp; 617 { 618 int cond = 1; 619 620 sdsense[unit].status = stat; 621 if (stat & STS_CHECKCOND) { 622 struct scsi_xsense *sp; 623 624 scsi_request_sense(hp->hp_ctlr, hp->hp_slave, 625 sc->sc_punit, sdsense[unit].sense, 626 sizeof(sdsense[unit].sense)); 627 sp = (struct scsi_xsense *)sdsense[unit].sense; 628 printf("sd%d: scsi sense class %d, code %d", unit, 629 sp->class, sp->code); 630 if (sp->class == 7) { 631 printf(", key %d", sp->key); 632 if (sp->valid) 633 printf(", blk %d", *(int *)&sp->info1); 634 switch (sp->key) { 635 /* no sense, try again */ 636 case 0: 637 cond = -1; 638 break; 639 /* recovered error, not a problem */ 640 case 1: 641 cond = 0; 642 break; 643 /* possible media change */ 644 case 6: 645 /* 646 * For removable media, if we are doing the 647 * first open (i.e. reading the label) go 648 * ahead and retry, otherwise someone has 649 * changed the media out from under us and 650 * we should abort any further operations 651 * until a close is done. 652 */ 653 if (sc->sc_flags & SDF_RMEDIA) { 654 if (sc->sc_flags & SDF_OPENING) 655 cond = -1; 656 else 657 sc->sc_flags |= SDF_ERROR; 658 } 659 break; 660 } 661 } 662 printf("\n"); 663 } 664 return(cond); 665 } 666 667 static void 668 sdfinish(unit, sc, bp) 669 int unit; 670 register struct sd_softc *sc; 671 register struct buf *bp; 672 { 673 register struct buf *dp = &sdtab[unit]; 674 675 dp->b_errcnt = 0; 676 dp->b_actf = bp->b_actf; 677 bp->b_resid = 0; 678 biodone(bp); 679 scsifree(&sc->sc_dq); 680 if (dp->b_actf) 681 sdustart(unit); 682 else { 683 dp->b_active = 0; 684 if (sc->sc_flags & SDF_WANTED) { 685 sc->sc_flags &= ~SDF_WANTED; 686 wakeup((caddr_t)dp); 687 } 688 } 689 } 690 691 void 692 sdstart(unit) 693 register int unit; 694 { 695 register struct sd_softc *sc = &sd_softc[unit]; 696 register struct hp_device *hp = sc->sc_hd; 697 698 /* 699 * we have the SCSI bus -- in format mode, we may or may not need dma 700 * so check now. 701 */ 702 if (sc->sc_format_pid && legal_cmds[sdcmd[unit].cdb[0]] > 0) { 703 register struct buf *bp = sdtab[unit].b_actf; 704 register int sts; 705 706 sts = scsi_immed_command(hp->hp_ctlr, hp->hp_slave, 707 sc->sc_punit, &sdcmd[unit], 708 bp->b_un.b_addr, bp->b_bcount, 709 bp->b_flags & B_READ); 710 sdsense[unit].status = sts; 711 if (sts & 0xfe) { 712 (void) sderror(unit, sc, hp, sts); 713 bp->b_flags |= B_ERROR; 714 bp->b_error = EIO; 715 } 716 sdfinish(unit, sc, bp); 717 718 } else if (scsiustart(hp->hp_ctlr)) 719 sdgo(unit); 720 } 721 722 void 723 sdgo(unit) 724 register int unit; 725 { 726 register struct sd_softc *sc = &sd_softc[unit]; 727 register struct hp_device *hp = sc->sc_hd; 728 register struct buf *bp = sdtab[unit].b_actf; 729 register int pad; 730 register struct scsi_fmt_cdb *cmd; 731 732 /* 733 * Drive is in an error state, abort all operations 734 */ 735 if (sc->sc_flags & SDF_ERROR) { 736 bp->b_flags |= B_ERROR; 737 bp->b_error = EIO; 738 sdfinish(unit, sc, bp); 739 return; 740 } 741 if (sc->sc_format_pid) { 742 cmd = &sdcmd[unit]; 743 pad = 0; 744 } else { 745 cmd = bp->b_flags & B_READ? &sd_read_cmd : &sd_write_cmd; 746 *(int *)(&cmd->cdb[2]) = bp->b_cylin; 747 pad = howmany(bp->b_bcount, sc->sc_blksize); 748 *(u_short *)(&cmd->cdb[7]) = pad; 749 pad = (bp->b_bcount & (sc->sc_blksize - 1)) != 0; 750 #ifdef DEBUG 751 if (pad) 752 printf("sd%d: partial block xfer -- %x bytes\n", 753 unit, bp->b_bcount); 754 #endif 755 sdstats[unit].sdtransfers++; 756 } 757 #ifdef USELEDS 758 if (inledcontrol == 0) 759 ledcontrol(0, 0, LED_DISK); 760 #endif 761 if (scsigo(hp->hp_ctlr, hp->hp_slave, sc->sc_punit, bp, cmd, pad) == 0) { 762 if (hp->hp_dk >= 0) { 763 dk_busy |= 1 << hp->hp_dk; 764 ++dk_seek[hp->hp_dk]; 765 ++dk_xfer[hp->hp_dk]; 766 dk_wds[hp->hp_dk] += bp->b_bcount >> 6; 767 } 768 return; 769 } 770 #ifdef DEBUG 771 if (sddebug & SDB_ERROR) 772 printf("sd%d: sdstart: %s adr %d blk %d len %d ecnt %d\n", 773 unit, bp->b_flags & B_READ? "read" : "write", 774 bp->b_un.b_addr, bp->b_cylin, bp->b_bcount, 775 sdtab[unit].b_errcnt); 776 #endif 777 bp->b_flags |= B_ERROR; 778 bp->b_error = EIO; 779 sdfinish(unit, sc, bp); 780 } 781 782 void 783 sdintr(unit, stat) 784 register int unit; 785 int stat; 786 { 787 register struct sd_softc *sc = &sd_softc[unit]; 788 register struct buf *bp = sdtab[unit].b_actf; 789 register struct hp_device *hp = sc->sc_hd; 790 int cond; 791 792 if (bp == NULL) { 793 printf("sd%d: bp == NULL\n", unit); 794 return; 795 } 796 if (hp->hp_dk >= 0) 797 dk_busy &=~ (1 << hp->hp_dk); 798 if (stat) { 799 #ifdef DEBUG 800 if (sddebug & SDB_ERROR) 801 printf("sd%d: sdintr: bad scsi status 0x%x\n", 802 unit, stat); 803 #endif 804 cond = sderror(unit, sc, hp, stat); 805 if (cond) { 806 if (cond < 0 && sdtab[unit].b_errcnt++ < SDRETRY) { 807 #ifdef DEBUG 808 if (sddebug & SDB_ERROR) 809 printf("sd%d: retry #%d\n", 810 unit, sdtab[unit].b_errcnt); 811 #endif 812 sdstart(unit); 813 return; 814 } 815 bp->b_flags |= B_ERROR; 816 bp->b_error = EIO; 817 } 818 } 819 sdfinish(unit, sc, bp); 820 } 821 822 int 823 sdread(dev, uio, flags) 824 dev_t dev; 825 struct uio *uio; 826 int flags; 827 { 828 register int unit = sdunit(dev); 829 register int pid; 830 831 if ((pid = sd_softc[unit].sc_format_pid) && 832 pid != uio->uio_procp->p_pid) 833 return (EPERM); 834 835 return (physio(sdstrategy, NULL, dev, B_READ, minphys, uio)); 836 } 837 838 int 839 sdwrite(dev, uio, flags) 840 dev_t dev; 841 struct uio *uio; 842 int flags; 843 { 844 register int unit = sdunit(dev); 845 register int pid; 846 847 if ((pid = sd_softc[unit].sc_format_pid) && 848 pid != uio->uio_procp->p_pid) 849 return (EPERM); 850 851 return (physio(sdstrategy, NULL, dev, B_WRITE, minphys, uio)); 852 } 853 854 int 855 sdioctl(dev, cmd, data, flag, p) 856 dev_t dev; 857 int cmd; 858 caddr_t data; 859 int flag; 860 struct proc *p; 861 { 862 int unit = sdunit(dev); 863 register struct sd_softc *sc = &sd_softc[unit]; 864 register struct disklabel *lp = &sc->sc_info.si_label; 865 int error, flags; 866 867 switch (cmd) { 868 default: 869 return (EINVAL); 870 871 case DIOCGDINFO: 872 *(struct disklabel *)data = *lp; 873 return (0); 874 875 case DIOCGPART: 876 ((struct partinfo *)data)->disklab = lp; 877 ((struct partinfo *)data)->part = 878 &lp->d_partitions[sdpart(dev)]; 879 return (0); 880 881 case DIOCWLABEL: 882 if ((flag & FWRITE) == 0) 883 return (EBADF); 884 if (*(int *)data) 885 sc->sc_flags |= SDF_WLABEL; 886 else 887 sc->sc_flags &= ~SDF_WLABEL; 888 return (0); 889 890 case DIOCSDINFO: 891 if ((flag & FWRITE) == 0) 892 return (EBADF); 893 error = setdisklabel(lp, (struct disklabel *)data, 894 (sc->sc_flags & SDF_WLABEL) ? 0 895 : sc->sc_info.si_open); 896 return (error); 897 898 case DIOCWDINFO: 899 if ((flag & FWRITE) == 0) 900 return (EBADF); 901 error = setdisklabel(lp, (struct disklabel *)data, 902 (sc->sc_flags & SDF_WLABEL) ? 0 903 : sc->sc_info.si_open); 904 if (error) 905 return (error); 906 flags = sc->sc_flags; 907 sc->sc_flags = SDF_ALIVE | SDF_WLABEL; 908 error = writedisklabel(sdlabdev(dev), sdstrategy, lp); 909 sc->sc_flags = flags; 910 return (error); 911 912 case SDIOCSFORMAT: 913 /* take this device into or out of "format" mode */ 914 if (suser(p->p_ucred, &p->p_acflag)) 915 return(EPERM); 916 917 if (*(int *)data) { 918 if (sc->sc_format_pid) 919 return (EPERM); 920 sc->sc_format_pid = p->p_pid; 921 } else 922 sc->sc_format_pid = 0; 923 return (0); 924 925 case SDIOCGFORMAT: 926 /* find out who has the device in format mode */ 927 *(int *)data = sc->sc_format_pid; 928 return (0); 929 930 case SDIOCSCSICOMMAND: 931 /* 932 * Save what user gave us as SCSI cdb to use with next 933 * read or write to the char device. 934 */ 935 if (sc->sc_format_pid != p->p_pid) 936 return (EPERM); 937 if (legal_cmds[((struct scsi_fmt_cdb *)data)->cdb[0]] == 0) 938 return (EINVAL); 939 bcopy(data, (caddr_t)&sdcmd[unit], sizeof(sdcmd[0])); 940 return (0); 941 942 case SDIOCSENSE: 943 /* 944 * return the SCSI sense data saved after the last 945 * operation that completed with "check condition" status. 946 */ 947 bcopy((caddr_t)&sdsense[unit], data, sizeof(sdsense[0])); 948 return (0); 949 950 } 951 /*NOTREACHED*/ 952 } 953 954 int 955 sdsize(dev) 956 dev_t dev; 957 { 958 register int unit = sdunit(dev); 959 register struct sd_softc *sc = &sd_softc[unit]; 960 int psize, didopen = 0; 961 962 if (unit >= NSD || (sc->sc_flags & SDF_ALIVE) == 0) 963 return(-1); 964 965 /* 966 * We get called very early on (via swapconf) 967 * without the device being open so we may need 968 * to handle it here. 969 */ 970 if (sc->sc_info.si_open == 0) { 971 if (sdopen(dev, FREAD|FWRITE, S_IFBLK, NULL)) 972 return(-1); 973 didopen = 1; 974 } 975 psize = sc->sc_info.si_label.d_partitions[sdpart(dev)].p_size; 976 if (didopen) 977 (void) sdclose(dev, FREAD|FWRITE, S_IFBLK, NULL); 978 return (psize); 979 } 980 981 /* 982 * Non-interrupt driven, non-dma dump routine. 983 */ 984 int 985 sddump(dev) 986 dev_t dev; 987 { 988 int part = sdpart(dev); 989 int unit = sdunit(dev); 990 register struct sd_softc *sc = &sd_softc[unit]; 991 register struct hp_device *hp = sc->sc_hd; 992 register struct partition *pinfo; 993 register daddr_t baddr; 994 register int maddr; 995 register int pages, i; 996 int stat; 997 extern int lowram; 998 999 /* is drive ok? */ 1000 if (unit >= NSD || (sc->sc_flags & SDF_ALIVE) == 0) 1001 return (ENXIO); 1002 pinfo = &sc->sc_info.si_label.d_partitions[part]; 1003 /* dump parameters in range? */ 1004 if (dumplo < 0 || dumplo >= pinfo->p_size || 1005 pinfo->p_fstype != FS_SWAP) 1006 return (EINVAL); 1007 pages = physmem; 1008 if (dumplo + ctod(pages) > pinfo->p_size) 1009 pages = dtoc(pinfo->p_size - dumplo); 1010 maddr = lowram; 1011 baddr = dumplo + pinfo->p_offset; 1012 /* scsi bus idle? */ 1013 if (!scsireq(&sc->sc_dq)) { 1014 scsireset(hp->hp_ctlr); 1015 sdreset(sc, sc->sc_hd); 1016 printf("[ drive %d reset ] ", unit); 1017 } 1018 for (i = 0; i < pages; i++) { 1019 #define NPGMB (1024*1024/NBPG) 1020 /* print out how many Mbs we have dumped */ 1021 if (i && (i % NPGMB) == 0) 1022 printf("%d ", i / NPGMB); 1023 #undef NPBMG 1024 pmap_enter(kernel_pmap, (vm_offset_t)vmmap, maddr, 1025 VM_PROT_READ, TRUE); 1026 stat = scsi_tt_write(hp->hp_ctlr, hp->hp_slave, sc->sc_punit, 1027 vmmap, NBPG, baddr, sc->sc_bshift); 1028 if (stat) { 1029 printf("sddump: scsi write error 0x%x\n", stat); 1030 return (EIO); 1031 } 1032 maddr += NBPG; 1033 baddr += ctod(1); 1034 } 1035 return (0); 1036 } 1037 #endif 1038