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