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.18 (Berkeley) 02/18/93 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_ncylinders = 1; 315 lp->d_secpercyl = 32*20; 316 lp->d_npartitions = 3; 317 lp->d_partitions[2].p_offset = 0; 318 /* XXX we can open a device even without SDF_ALIVE */ 319 if (sc->sc_blksize == 0) 320 sc->sc_blksize = DEV_BSIZE; 321 /* XXX ensure size is at least one device block */ 322 lp->d_partitions[2].p_size = 323 roundup(LABELSECTOR+1, btodb(sc->sc_blksize)); 324 325 /* 326 * Now try to read the disklabel 327 */ 328 msg = readdisklabel(sdlabdev(dev), sdstrategy, lp); 329 if (msg == NULL) 330 return(0); 331 if (bcmp(msg, "I/O", 3) == 0) /* XXX */ 332 return(EIO); 333 334 pi = lp->d_partitions; 335 printf("sd%d: WARNING: %s, ", unit, msg); 336 #ifdef COMPAT_NOLABEL 337 printf("using old default partitioning\n"); 338 sdmakedisklabel(unit, lp); 339 #else 340 printf("defining `c' partition as entire disk\n"); 341 pi[2].p_size = sc->sc_blks; 342 #endif 343 return(0); 344 } 345 346 int 347 sdopen(dev, flags, mode, p) 348 dev_t dev; 349 int flags, mode; 350 struct proc *p; 351 { 352 register int unit = sdunit(dev); 353 register struct sd_softc *sc = &sd_softc[unit]; 354 int mask, error; 355 356 if (unit >= NSD) 357 return(ENXIO); 358 if ((sc->sc_flags & SDF_ALIVE) == 0 && suser(p->p_ucred, &p->p_acflag)) 359 return(ENXIO); 360 if (sc->sc_flags & SDF_ERROR) 361 return(EIO); 362 363 /* 364 * Wait for any pending opens/closes to complete 365 */ 366 while (sc->sc_flags & (SDF_OPENING|SDF_CLOSING)) 367 sleep((caddr_t)sc, PRIBIO); 368 /* 369 * On first open, get label and partition info. 370 * We may block reading the label, so be careful 371 * to stop any other opens. 372 */ 373 if (sc->sc_info.si_open == 0) { 374 sc->sc_flags |= SDF_OPENING; 375 error = sdgetinfo(dev); 376 sc->sc_flags &= ~SDF_OPENING; 377 wakeup((caddr_t)sc); 378 if (error) 379 return(error); 380 } 381 if (sc->sc_hd->hp_dk >= 0) 382 dk_wpms[sc->sc_hd->hp_dk] = sc->sc_wpms; 383 384 mask = 1 << sdpart(dev); 385 if (mode == S_IFCHR) 386 sc->sc_info.si_copen |= mask; 387 else 388 sc->sc_info.si_bopen |= mask; 389 sc->sc_info.si_open |= mask; 390 return(0); 391 } 392 393 int 394 sdclose(dev, flag, mode, p) 395 dev_t dev; 396 int flag, mode; 397 struct proc *p; 398 { 399 int unit = sdunit(dev); 400 register struct sd_softc *sc = &sd_softc[unit]; 401 register struct sdinfo *si = &sc->sc_info; 402 int mask, s; 403 404 mask = 1 << sdpart(dev); 405 if (mode == S_IFCHR) 406 si->si_copen &= ~mask; 407 else 408 si->si_bopen &= ~mask; 409 si->si_open = si->si_bopen | si->si_copen; 410 /* 411 * On last close, we wait for all activity to cease since 412 * the label/parition info will become invalid. Since we 413 * might sleep, we must block any opens while we are here. 414 * Note we don't have to about other closes since we know 415 * we are the last one. 416 */ 417 if (si->si_open == 0) { 418 sc->sc_flags |= SDF_CLOSING; 419 s = splbio(); 420 while (sdtab[unit].b_active) { 421 sc->sc_flags |= SDF_WANTED; 422 sleep((caddr_t)&sdtab[unit], PRIBIO); 423 } 424 splx(s); 425 sc->sc_flags &= ~(SDF_CLOSING|SDF_WLABEL|SDF_ERROR); 426 wakeup((caddr_t)sc); 427 } 428 sc->sc_format_pid = 0; 429 return(0); 430 } 431 432 /* 433 * This routine is called for partial block transfers and non-aligned 434 * transfers (the latter only being possible on devices with a block size 435 * larger than DEV_BSIZE). The operation is performed in three steps 436 * using a locally allocated buffer: 437 * 1. transfer any initial partial block 438 * 2. transfer full blocks 439 * 3. transfer any final partial block 440 */ 441 static void 442 sdlblkstrat(bp, bsize) 443 register struct buf *bp; 444 register int bsize; 445 { 446 register struct buf *cbp = (struct buf *)malloc(sizeof(struct buf), 447 M_DEVBUF, M_WAITOK); 448 caddr_t cbuf = (caddr_t)malloc(bsize, M_DEVBUF, M_WAITOK); 449 register int bn, resid; 450 register caddr_t addr; 451 452 bzero((caddr_t)cbp, sizeof(*cbp)); 453 cbp->b_proc = curproc; /* XXX */ 454 cbp->b_dev = bp->b_dev; 455 bn = bp->b_blkno; 456 resid = bp->b_bcount; 457 addr = bp->b_un.b_addr; 458 #ifdef DEBUG 459 if (sddebug & SDB_PARTIAL) 460 printf("sdlblkstrat: bp %x flags %x bn %x resid %x addr %x\n", 461 bp, bp->b_flags, bn, resid, addr); 462 #endif 463 464 while (resid > 0) { 465 register int boff = dbtob(bn) & (bsize - 1); 466 register int count; 467 468 if (boff || resid < bsize) { 469 sdstats[sdunit(bp->b_dev)].sdpartials++; 470 count = min(resid, bsize - boff); 471 cbp->b_flags = B_BUSY | B_PHYS | B_READ; 472 cbp->b_blkno = bn - btodb(boff); 473 cbp->b_un.b_addr = cbuf; 474 cbp->b_bcount = bsize; 475 #ifdef DEBUG 476 if (sddebug & SDB_PARTIAL) 477 printf(" readahead: bn %x cnt %x off %x addr %x\n", 478 cbp->b_blkno, count, boff, addr); 479 #endif 480 sdstrategy(cbp); 481 biowait(cbp); 482 if (cbp->b_flags & B_ERROR) { 483 bp->b_flags |= B_ERROR; 484 bp->b_error = cbp->b_error; 485 break; 486 } 487 if (bp->b_flags & B_READ) { 488 bcopy(&cbuf[boff], addr, count); 489 goto done; 490 } 491 bcopy(addr, &cbuf[boff], count); 492 #ifdef DEBUG 493 if (sddebug & SDB_PARTIAL) 494 printf(" writeback: bn %x cnt %x off %x addr %x\n", 495 cbp->b_blkno, count, boff, addr); 496 #endif 497 } else { 498 count = resid & ~(bsize - 1); 499 cbp->b_blkno = bn; 500 cbp->b_un.b_addr = addr; 501 cbp->b_bcount = count; 502 #ifdef DEBUG 503 if (sddebug & SDB_PARTIAL) 504 printf(" fulltrans: bn %x cnt %x addr %x\n", 505 cbp->b_blkno, count, addr); 506 #endif 507 } 508 cbp->b_flags = B_BUSY | B_PHYS | (bp->b_flags & B_READ); 509 sdstrategy(cbp); 510 biowait(cbp); 511 if (cbp->b_flags & B_ERROR) { 512 bp->b_flags |= B_ERROR; 513 bp->b_error = cbp->b_error; 514 break; 515 } 516 done: 517 bn += btodb(count); 518 resid -= count; 519 addr += count; 520 #ifdef DEBUG 521 if (sddebug & SDB_PARTIAL) 522 printf(" done: bn %x resid %x addr %x\n", 523 bn, resid, addr); 524 #endif 525 } 526 free(cbuf, M_DEVBUF); 527 free(cbp, M_DEVBUF); 528 } 529 530 void 531 sdstrategy(bp) 532 register struct buf *bp; 533 { 534 int unit = sdunit(bp->b_dev); 535 register struct sd_softc *sc = &sd_softc[unit]; 536 register struct buf *dp = &sdtab[unit]; 537 register struct partition *pinfo; 538 register daddr_t bn; 539 register int sz, s; 540 541 if (sc->sc_flags & SDF_ERROR) { 542 bp->b_error = EIO; 543 goto bad; 544 } 545 if (sc->sc_format_pid) { 546 if (sc->sc_format_pid != curproc->p_pid) { /* XXX */ 547 bp->b_error = EPERM; 548 goto bad; 549 } 550 bp->b_cylin = 0; 551 } else { 552 bn = bp->b_blkno; 553 sz = howmany(bp->b_bcount, DEV_BSIZE); 554 pinfo = &sc->sc_info.si_label.d_partitions[sdpart(bp->b_dev)]; 555 if (bn < 0 || bn + sz > pinfo->p_size) { 556 sz = pinfo->p_size - bn; 557 if (sz == 0) { 558 bp->b_resid = bp->b_bcount; 559 goto done; 560 } 561 if (sz < 0) { 562 bp->b_error = EINVAL; 563 goto bad; 564 } 565 bp->b_bcount = dbtob(sz); 566 } 567 /* 568 * Check for write to write protected label 569 */ 570 if (bn + pinfo->p_offset <= LABELSECTOR && 571 #if LABELSECTOR != 0 572 bn + pinfo->p_offset + sz > LABELSECTOR && 573 #endif 574 !(bp->b_flags & B_READ) && !(sc->sc_flags & SDF_WLABEL)) { 575 bp->b_error = EROFS; 576 goto bad; 577 } 578 /* 579 * Non-aligned or partial-block transfers handled specially. 580 */ 581 s = sc->sc_blksize - 1; 582 if ((dbtob(bn) & s) || (bp->b_bcount & s)) { 583 sdlblkstrat(bp, sc->sc_blksize); 584 goto done; 585 } 586 bp->b_cylin = (bn + pinfo->p_offset) >> sc->sc_bshift; 587 } 588 s = splbio(); 589 disksort(dp, bp); 590 if (dp->b_active == 0) { 591 dp->b_active = 1; 592 sdustart(unit); 593 } 594 splx(s); 595 return; 596 bad: 597 bp->b_flags |= B_ERROR; 598 done: 599 biodone(bp); 600 } 601 602 void 603 sdustart(unit) 604 register int unit; 605 { 606 if (scsireq(&sd_softc[unit].sc_dq)) 607 sdstart(unit); 608 } 609 610 /* 611 * Return: 612 * 0 if not really an error 613 * <0 if we should do a retry 614 * >0 if a fatal error 615 */ 616 static int 617 sderror(unit, sc, hp, stat) 618 int unit, stat; 619 register struct sd_softc *sc; 620 register struct hp_device *hp; 621 { 622 int cond = 1; 623 624 sdsense[unit].status = stat; 625 if (stat & STS_CHECKCOND) { 626 struct scsi_xsense *sp; 627 628 scsi_request_sense(hp->hp_ctlr, hp->hp_slave, 629 sc->sc_punit, sdsense[unit].sense, 630 sizeof(sdsense[unit].sense)); 631 sp = (struct scsi_xsense *)sdsense[unit].sense; 632 printf("sd%d: scsi sense class %d, code %d", unit, 633 sp->class, sp->code); 634 if (sp->class == 7) { 635 printf(", key %d", sp->key); 636 if (sp->valid) 637 printf(", blk %d", *(int *)&sp->info1); 638 switch (sp->key) { 639 /* no sense, try again */ 640 case 0: 641 cond = -1; 642 break; 643 /* recovered error, not a problem */ 644 case 1: 645 cond = 0; 646 break; 647 /* possible media change */ 648 case 6: 649 /* 650 * For removable media, if we are doing the 651 * first open (i.e. reading the label) go 652 * ahead and retry, otherwise someone has 653 * changed the media out from under us and 654 * we should abort any further operations 655 * until a close is done. 656 */ 657 if (sc->sc_flags & SDF_RMEDIA) { 658 if (sc->sc_flags & SDF_OPENING) 659 cond = -1; 660 else 661 sc->sc_flags |= SDF_ERROR; 662 } 663 break; 664 } 665 } 666 printf("\n"); 667 } 668 return(cond); 669 } 670 671 static void 672 sdfinish(unit, sc, bp) 673 int unit; 674 register struct sd_softc *sc; 675 register struct buf *bp; 676 { 677 register struct buf *dp = &sdtab[unit]; 678 679 dp->b_errcnt = 0; 680 dp->b_actf = bp->b_actf; 681 bp->b_resid = 0; 682 biodone(bp); 683 scsifree(&sc->sc_dq); 684 if (dp->b_actf) 685 sdustart(unit); 686 else { 687 dp->b_active = 0; 688 if (sc->sc_flags & SDF_WANTED) { 689 sc->sc_flags &= ~SDF_WANTED; 690 wakeup((caddr_t)dp); 691 } 692 } 693 } 694 695 void 696 sdstart(unit) 697 register int unit; 698 { 699 register struct sd_softc *sc = &sd_softc[unit]; 700 register struct hp_device *hp = sc->sc_hd; 701 702 /* 703 * we have the SCSI bus -- in format mode, we may or may not need dma 704 * so check now. 705 */ 706 if (sc->sc_format_pid && legal_cmds[sdcmd[unit].cdb[0]] > 0) { 707 register struct buf *bp = sdtab[unit].b_actf; 708 register int sts; 709 710 sts = scsi_immed_command(hp->hp_ctlr, hp->hp_slave, 711 sc->sc_punit, &sdcmd[unit], 712 bp->b_un.b_addr, bp->b_bcount, 713 bp->b_flags & B_READ); 714 sdsense[unit].status = sts; 715 if (sts & 0xfe) { 716 (void) sderror(unit, sc, hp, sts); 717 bp->b_flags |= B_ERROR; 718 bp->b_error = EIO; 719 } 720 sdfinish(unit, sc, bp); 721 722 } else if (scsiustart(hp->hp_ctlr)) 723 sdgo(unit); 724 } 725 726 void 727 sdgo(unit) 728 register int unit; 729 { 730 register struct sd_softc *sc = &sd_softc[unit]; 731 register struct hp_device *hp = sc->sc_hd; 732 register struct buf *bp = sdtab[unit].b_actf; 733 register int pad; 734 register struct scsi_fmt_cdb *cmd; 735 736 /* 737 * Drive is in an error state, abort all operations 738 */ 739 if (sc->sc_flags & SDF_ERROR) { 740 bp->b_flags |= B_ERROR; 741 bp->b_error = EIO; 742 sdfinish(unit, sc, bp); 743 return; 744 } 745 if (sc->sc_format_pid) { 746 cmd = &sdcmd[unit]; 747 pad = 0; 748 } else { 749 cmd = bp->b_flags & B_READ? &sd_read_cmd : &sd_write_cmd; 750 *(int *)(&cmd->cdb[2]) = bp->b_cylin; 751 pad = howmany(bp->b_bcount, sc->sc_blksize); 752 *(u_short *)(&cmd->cdb[7]) = pad; 753 pad = (bp->b_bcount & (sc->sc_blksize - 1)) != 0; 754 #ifdef DEBUG 755 if (pad) 756 printf("sd%d: partial block xfer -- %x bytes\n", 757 unit, bp->b_bcount); 758 #endif 759 sdstats[unit].sdtransfers++; 760 } 761 #ifdef USELEDS 762 if (inledcontrol == 0) 763 ledcontrol(0, 0, LED_DISK); 764 #endif 765 if (scsigo(hp->hp_ctlr, hp->hp_slave, sc->sc_punit, bp, cmd, pad) == 0) { 766 if (hp->hp_dk >= 0) { 767 dk_busy |= 1 << hp->hp_dk; 768 ++dk_seek[hp->hp_dk]; 769 ++dk_xfer[hp->hp_dk]; 770 dk_wds[hp->hp_dk] += bp->b_bcount >> 6; 771 } 772 return; 773 } 774 #ifdef DEBUG 775 if (sddebug & SDB_ERROR) 776 printf("sd%d: sdstart: %s adr %d blk %d len %d ecnt %d\n", 777 unit, bp->b_flags & B_READ? "read" : "write", 778 bp->b_un.b_addr, bp->b_cylin, bp->b_bcount, 779 sdtab[unit].b_errcnt); 780 #endif 781 bp->b_flags |= B_ERROR; 782 bp->b_error = EIO; 783 sdfinish(unit, sc, bp); 784 } 785 786 void 787 sdintr(unit, stat) 788 register int unit; 789 int stat; 790 { 791 register struct sd_softc *sc = &sd_softc[unit]; 792 register struct buf *bp = sdtab[unit].b_actf; 793 register struct hp_device *hp = sc->sc_hd; 794 int cond; 795 796 if (bp == NULL) { 797 printf("sd%d: bp == NULL\n", unit); 798 return; 799 } 800 if (hp->hp_dk >= 0) 801 dk_busy &=~ (1 << hp->hp_dk); 802 if (stat) { 803 #ifdef DEBUG 804 if (sddebug & SDB_ERROR) 805 printf("sd%d: sdintr: bad scsi status 0x%x\n", 806 unit, stat); 807 #endif 808 cond = sderror(unit, sc, hp, stat); 809 if (cond) { 810 if (cond < 0 && sdtab[unit].b_errcnt++ < SDRETRY) { 811 #ifdef DEBUG 812 if (sddebug & SDB_ERROR) 813 printf("sd%d: retry #%d\n", 814 unit, sdtab[unit].b_errcnt); 815 #endif 816 sdstart(unit); 817 return; 818 } 819 bp->b_flags |= B_ERROR; 820 bp->b_error = EIO; 821 } 822 } 823 sdfinish(unit, sc, bp); 824 } 825 826 int 827 sdread(dev, uio, flags) 828 dev_t dev; 829 struct uio *uio; 830 int flags; 831 { 832 register int unit = sdunit(dev); 833 register int pid; 834 835 if ((pid = sd_softc[unit].sc_format_pid) && 836 pid != uio->uio_procp->p_pid) 837 return (EPERM); 838 839 return (physio(sdstrategy, NULL, dev, B_READ, minphys, uio)); 840 } 841 842 int 843 sdwrite(dev, uio, flags) 844 dev_t dev; 845 struct uio *uio; 846 int flags; 847 { 848 register int unit = sdunit(dev); 849 register int pid; 850 851 if ((pid = sd_softc[unit].sc_format_pid) && 852 pid != uio->uio_procp->p_pid) 853 return (EPERM); 854 855 return (physio(sdstrategy, NULL, dev, B_WRITE, minphys, uio)); 856 } 857 858 int 859 sdioctl(dev, cmd, data, flag, p) 860 dev_t dev; 861 int cmd; 862 caddr_t data; 863 int flag; 864 struct proc *p; 865 { 866 int unit = sdunit(dev); 867 register struct sd_softc *sc = &sd_softc[unit]; 868 register struct disklabel *lp = &sc->sc_info.si_label; 869 int error, flags; 870 871 switch (cmd) { 872 default: 873 return (EINVAL); 874 875 case DIOCGDINFO: 876 *(struct disklabel *)data = *lp; 877 return (0); 878 879 case DIOCGPART: 880 ((struct partinfo *)data)->disklab = lp; 881 ((struct partinfo *)data)->part = 882 &lp->d_partitions[sdpart(dev)]; 883 return (0); 884 885 case DIOCWLABEL: 886 if ((flag & FWRITE) == 0) 887 return (EBADF); 888 if (*(int *)data) 889 sc->sc_flags |= SDF_WLABEL; 890 else 891 sc->sc_flags &= ~SDF_WLABEL; 892 return (0); 893 894 case DIOCSDINFO: 895 if ((flag & FWRITE) == 0) 896 return (EBADF); 897 error = setdisklabel(lp, (struct disklabel *)data, 898 (sc->sc_flags & SDF_WLABEL) ? 0 899 : sc->sc_info.si_open); 900 return (error); 901 902 case DIOCWDINFO: 903 if ((flag & FWRITE) == 0) 904 return (EBADF); 905 error = setdisklabel(lp, (struct disklabel *)data, 906 (sc->sc_flags & SDF_WLABEL) ? 0 907 : sc->sc_info.si_open); 908 if (error) 909 return (error); 910 flags = sc->sc_flags; 911 sc->sc_flags = SDF_ALIVE | SDF_WLABEL; 912 error = writedisklabel(sdlabdev(dev), sdstrategy, lp); 913 sc->sc_flags = flags; 914 return (error); 915 916 case SDIOCSFORMAT: 917 /* take this device into or out of "format" mode */ 918 if (suser(p->p_ucred, &p->p_acflag)) 919 return(EPERM); 920 921 if (*(int *)data) { 922 if (sc->sc_format_pid) 923 return (EPERM); 924 sc->sc_format_pid = p->p_pid; 925 } else 926 sc->sc_format_pid = 0; 927 return (0); 928 929 case SDIOCGFORMAT: 930 /* find out who has the device in format mode */ 931 *(int *)data = sc->sc_format_pid; 932 return (0); 933 934 case SDIOCSCSICOMMAND: 935 /* 936 * Save what user gave us as SCSI cdb to use with next 937 * read or write to the char device. 938 */ 939 if (sc->sc_format_pid != p->p_pid) 940 return (EPERM); 941 if (legal_cmds[((struct scsi_fmt_cdb *)data)->cdb[0]] == 0) 942 return (EINVAL); 943 bcopy(data, (caddr_t)&sdcmd[unit], sizeof(sdcmd[0])); 944 return (0); 945 946 case SDIOCSENSE: 947 /* 948 * return the SCSI sense data saved after the last 949 * operation that completed with "check condition" status. 950 */ 951 bcopy((caddr_t)&sdsense[unit], data, sizeof(sdsense[0])); 952 return (0); 953 954 } 955 /*NOTREACHED*/ 956 } 957 958 int 959 sdsize(dev) 960 dev_t dev; 961 { 962 register int unit = sdunit(dev); 963 register struct sd_softc *sc = &sd_softc[unit]; 964 int psize, didopen = 0; 965 966 if (unit >= NSD || (sc->sc_flags & SDF_ALIVE) == 0) 967 return(-1); 968 969 /* 970 * We get called very early on (via swapconf) 971 * without the device being open so we may need 972 * to handle it here. 973 */ 974 if (sc->sc_info.si_open == 0) { 975 if (sdopen(dev, FREAD|FWRITE, S_IFBLK, NULL)) 976 return(-1); 977 didopen = 1; 978 } 979 psize = sc->sc_info.si_label.d_partitions[sdpart(dev)].p_size; 980 if (didopen) 981 (void) sdclose(dev, FREAD|FWRITE, S_IFBLK, NULL); 982 return (psize); 983 } 984 985 /* 986 * Non-interrupt driven, non-dma dump routine. 987 */ 988 int 989 sddump(dev) 990 dev_t dev; 991 { 992 int part = sdpart(dev); 993 int unit = sdunit(dev); 994 register struct sd_softc *sc = &sd_softc[unit]; 995 register struct hp_device *hp = sc->sc_hd; 996 register struct partition *pinfo; 997 register daddr_t baddr; 998 register int maddr; 999 register int pages, i; 1000 int stat; 1001 extern int lowram; 1002 1003 /* is drive ok? */ 1004 if (unit >= NSD || (sc->sc_flags & SDF_ALIVE) == 0) 1005 return (ENXIO); 1006 pinfo = &sc->sc_info.si_label.d_partitions[part]; 1007 /* dump parameters in range? */ 1008 if (dumplo < 0 || dumplo >= pinfo->p_size || 1009 pinfo->p_fstype != FS_SWAP) 1010 return (EINVAL); 1011 pages = physmem; 1012 if (dumplo + ctod(pages) > pinfo->p_size) 1013 pages = dtoc(pinfo->p_size - dumplo); 1014 maddr = lowram; 1015 baddr = dumplo + pinfo->p_offset; 1016 /* scsi bus idle? */ 1017 if (!scsireq(&sc->sc_dq)) { 1018 scsireset(hp->hp_ctlr); 1019 sdreset(sc, sc->sc_hd); 1020 printf("[ drive %d reset ] ", unit); 1021 } 1022 for (i = 0; i < pages; i++) { 1023 #define NPGMB (1024*1024/NBPG) 1024 /* print out how many Mbs we have dumped */ 1025 if (i && (i % NPGMB) == 0) 1026 printf("%d ", i / NPGMB); 1027 #undef NPBMG 1028 pmap_enter(kernel_pmap, (vm_offset_t)vmmap, maddr, 1029 VM_PROT_READ, TRUE); 1030 stat = scsi_tt_write(hp->hp_ctlr, hp->hp_slave, sc->sc_punit, 1031 vmmap, NBPG, baddr, sc->sc_bshift); 1032 if (stat) { 1033 printf("sddump: scsi write error 0x%x\n", stat); 1034 return (EIO); 1035 } 1036 maddr += NBPG; 1037 baddr += ctod(1); 1038 } 1039 return (0); 1040 } 1041 #endif 1042