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.1 (Berkeley) 05/08/90 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: sd.c,v 1.5 90/01/10 16:06:12 mike Locked $"; 21 #endif 22 23 #include "param.h" 24 #include "systm.h" 25 #include "buf.h" 26 #include "errno.h" 27 #include "dkstat.h" 28 #include "disklabel.h" 29 #include "device.h" 30 #include "malloc.h" 31 #include "scsireg.h" 32 33 #include "user.h" 34 #include "proc.h" 35 #include "uio.h" 36 37 extern int scsi_test_unit_rdy(); 38 extern int scsi_request_sense(); 39 extern int scsi_inquiry(); 40 extern int scsi_read_capacity(); 41 extern int scsi_tt_write(); 42 extern int scsireq(); 43 extern int scsiustart(); 44 extern int scsigo(); 45 extern void scsifree(); 46 extern void scsireset(); 47 48 extern void printf(); 49 extern void bcopy(); 50 extern void disksort(); 51 extern int splbio(); 52 extern void splx(); 53 extern void biodone(); 54 extern int physio(); 55 extern void TBIS(); 56 57 int sdinit(); 58 void sdstrategy(), sdstart(), sdustart(), sdgo(), sdintr(); 59 60 struct driver sddriver = { 61 sdinit, "sd", (int (*)())sdstart, (int (*)())sdgo, (int (*)())sdintr, 62 }; 63 64 struct size { 65 u_long strtblk; 66 u_long endblk; 67 int nblocks; 68 }; 69 70 struct sdinfo { 71 struct size part[8]; 72 }; 73 74 /* 75 * since the SCSI standard tends to hide the disk structure, we define 76 * partitions in terms of DEV_BSIZE blocks. The default partition table 77 * (for an unlabeled disk) reserves 512K for a boot area, has an 8 meg 78 * root and 32 meg of swap. The rest of the space on the drive goes in 79 * the G partition. As usual, the C partition covers the entire disk 80 * (including the boot area). 81 */ 82 struct sdinfo sddefaultpart = { 83 1024, 17408, 16384 , /* A */ 84 17408, 82944, 65536 , /* B */ 85 0, 0, 0 , /* C */ 86 17408, 115712, 98304 , /* D */ 87 115712, 218112, 102400 , /* E */ 88 218112, 0, 0 , /* F */ 89 82944, 0, 0 , /* G */ 90 115712, 0, 0 , /* H */ 91 }; 92 93 struct sd_softc { 94 struct hp_device *sc_hd; 95 struct devqueue sc_dq; 96 int sc_format_pid; /* process using "format" mode */ 97 short sc_flags; 98 short sc_type; /* drive type */ 99 short sc_punit; /* physical unit (scsi lun) */ 100 u_short sc_bshift; /* convert device blocks to DEV_BSIZE blks */ 101 u_int sc_blks; /* number of blocks on device */ 102 int sc_blksize; /* device block size in bytes */ 103 u_int sc_wpms; /* average xfer rate in 16 bit wds/sec. */ 104 struct sdinfo sc_info; /* drive partition table & label info */ 105 } sd_softc[NSD]; 106 107 /* sc_flags values */ 108 #define SDF_ALIVE 0x1 109 110 #ifdef DEBUG 111 int sddebug = 1; 112 #define SDB_ERROR 0x01 113 #define SDB_PARTIAL 0x02 114 #endif 115 116 struct sdstats { 117 long sdresets; 118 long sdtransfers; 119 long sdpartials; 120 } sdstats[NSD]; 121 122 struct buf sdtab[NSD]; 123 struct buf sdbuf[NSD]; 124 struct scsi_fmt_cdb sdcmd[NSD]; 125 struct scsi_fmt_sense sdsense[NSD]; 126 127 static struct scsi_fmt_cdb sd_read_cmd = { 10, CMD_READ_EXT }; 128 static struct scsi_fmt_cdb sd_write_cmd = { 10, CMD_WRITE_EXT }; 129 130 #define sdunit(x) ((minor(x) >> 3) & 0x7) 131 #define sdpart(x) (minor(x) & 0x7) 132 #define sdpunit(x) ((x) & 7) 133 #define b_cylin b_resid 134 #define SDRETRY 2 135 136 /* 137 * Table of scsi commands users are allowed to access via "format" 138 * mode. 0 means not legal. 1 means "immediate" (doesn't need dma). 139 * -1 means needs dma and/or wait for intr. 140 */ 141 static char legal_cmds[256] = { 142 /***** 0 1 2 3 4 5 6 7 8 9 A B C D E F */ 143 /*00*/ 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144 /*10*/ 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 145 /*20*/ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146 /*30*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147 /*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148 /*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149 /*60*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150 /*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151 /*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 152 /*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153 /*a0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154 /*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155 /*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156 /*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157 /*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 158 /*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 159 }; 160 161 static struct scsi_inquiry inqbuf; 162 static struct scsi_fmt_cdb inq = { 163 6, 164 CMD_INQUIRY, 0, 0, 0, sizeof(inqbuf), 0 165 }; 166 167 static u_char capbuf[8]; 168 struct scsi_fmt_cdb cap = { 169 10, 170 CMD_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0 171 }; 172 173 static int 174 sdident(sc, hd) 175 struct sd_softc *sc; 176 struct hp_device *hd; 177 { 178 int unit; 179 register int ctlr, slave; 180 register int i; 181 register int tries = 10; 182 183 ctlr = hd->hp_ctlr; 184 slave = hd->hp_slave; 185 unit = sc->sc_punit; 186 187 /* 188 * See if unit exists and is a disk then read block size & nblocks. 189 */ 190 while ((i = scsi_test_unit_rdy(ctlr, slave, unit)) != 0) { 191 if (i == -1 || --tries < 0) 192 /* doesn't exist or not a CCS device */ 193 return (-1); 194 if (i == STS_CHECKCOND) { 195 u_char sensebuf[128]; 196 struct scsi_xsense *sp = (struct scsi_xsense *)sensebuf; 197 198 scsi_request_sense(ctlr, slave, unit, sensebuf, 199 sizeof(sensebuf)); 200 if (sp->class == 7 && sp->key == 6) 201 /* drive doing an RTZ -- give it a while */ 202 DELAY(1000000); 203 } 204 DELAY(1000); 205 } 206 if (scsi_immed_command(ctlr, slave, unit, &inq, (u_char *)&inqbuf, 207 sizeof(inqbuf), B_READ) || 208 scsi_immed_command(ctlr, slave, unit, &cap, (u_char *)&capbuf, 209 sizeof(capbuf), B_READ)) 210 /* doesn't exist or not a CCS device */ 211 return (-1); 212 213 switch (inqbuf.type) { 214 case 0: /* disk */ 215 case 4: /* WORM */ 216 case 5: /* CD-ROM */ 217 case 7: /* Magneto-optical */ 218 break; 219 default: /* not a disk */ 220 return (-1); 221 } 222 sc->sc_blks = *(u_int *)&capbuf[0]; 223 sc->sc_blksize = *(int *)&capbuf[4]; 224 225 if (inqbuf.version != 1) 226 printf("sd%d: type 0x%x, qual 0x%x, ver %d", hd->hp_unit, 227 inqbuf.type, inqbuf.qual, inqbuf.version); 228 else { 229 char idstr[32]; 230 231 bcopy((caddr_t)&inqbuf.vendor_id, (caddr_t)idstr, 28); 232 for (i = 27; i > 23; --i) 233 if (idstr[i] != ' ') 234 break; 235 idstr[i+1] = 0; 236 for (i = 23; i > 7; --i) 237 if (idstr[i] != ' ') 238 break; 239 idstr[i+1] = 0; 240 for (i = 7; i >= 0; --i) 241 if (idstr[i] != ' ') 242 break; 243 idstr[i+1] = 0; 244 printf("sd%d: %s %s rev %s", hd->hp_unit, idstr, &idstr[8], 245 &idstr[24]); 246 } 247 printf(", %d %d byte blocks\n", sc->sc_blks, sc->sc_blksize); 248 if (sc->sc_blksize != DEV_BSIZE) { 249 if (sc->sc_blksize < DEV_BSIZE) { 250 printf("sd%d: need %d byte blocks - drive ignored\n", 251 unit, DEV_BSIZE); 252 return (-1); 253 } 254 for (i = sc->sc_blksize; i > DEV_BSIZE; i >>= 1) 255 ++sc->sc_bshift; 256 sc->sc_blks <<= sc->sc_bshift; 257 } 258 sc->sc_wpms = 32 * (60 * DEV_BSIZE / 2); /* XXX */ 259 return(inqbuf.type); 260 } 261 262 int 263 sdinit(hd) 264 register struct hp_device *hd; 265 { 266 register struct sd_softc *sc = &sd_softc[hd->hp_unit]; 267 268 sc->sc_hd = hd; 269 sc->sc_punit = sdpunit(hd->hp_flags); 270 sc->sc_type = sdident(sc, hd); 271 if (sc->sc_type < 0) 272 return(0); 273 sc->sc_dq.dq_ctlr = hd->hp_ctlr; 274 sc->sc_dq.dq_unit = hd->hp_unit; 275 sc->sc_dq.dq_slave = hd->hp_slave; 276 sc->sc_dq.dq_driver = &sddriver; 277 278 /* 279 * If we don't have a disk label, build a default partition 280 * table with 'standard' size root & swap and everything else 281 * in the G partition. 282 */ 283 sc->sc_info = sddefaultpart; 284 /* C gets everything */ 285 sc->sc_info.part[2].nblocks = sc->sc_blks; 286 sc->sc_info.part[2].endblk = sc->sc_blks; 287 /* G gets from end of B to end of disk */ 288 sc->sc_info.part[6].nblocks = sc->sc_blks - sc->sc_info.part[1].endblk; 289 sc->sc_info.part[6].endblk = sc->sc_blks; 290 /* 291 * We also define the D, E and F paritions as an alternative to 292 * B and G. D is 48Mb, starts after A and is intended for swapping. 293 * E is 50Mb, starts after D and is intended for /usr. F starts 294 * after E and is what ever is left. 295 */ 296 if (sc->sc_blks >= sc->sc_info.part[4].endblk) { 297 sc->sc_info.part[5].nblocks = 298 sc->sc_blks - sc->sc_info.part[4].endblk; 299 sc->sc_info.part[5].endblk = sc->sc_blks; 300 } else { 301 sc->sc_info.part[5].strtblk = 0; 302 sc->sc_info.part[3] = sc->sc_info.part[5]; 303 sc->sc_info.part[4] = sc->sc_info.part[5]; 304 } 305 /* 306 * H is a single partition alternative to E and F. 307 */ 308 if (sc->sc_blks >= sc->sc_info.part[3].endblk) { 309 sc->sc_info.part[7].nblocks = 310 sc->sc_blks - sc->sc_info.part[3].endblk; 311 sc->sc_info.part[7].endblk = sc->sc_blks; 312 } else { 313 sc->sc_info.part[7].strtblk = 0; 314 } 315 316 sc->sc_flags = SDF_ALIVE; 317 return(1); 318 } 319 320 void 321 sdreset(sc, hd) 322 register struct sd_softc *sc; 323 register struct hp_device *hd; 324 { 325 sdstats[hd->hp_unit].sdresets++; 326 } 327 328 int 329 sdopen(dev, flags) 330 dev_t dev; 331 int flags; 332 { 333 register int unit = sdunit(dev); 334 register struct sd_softc *sc = &sd_softc[unit]; 335 336 if (unit >= NSD) 337 return(ENXIO); 338 if ((sc->sc_flags & SDF_ALIVE) == 0 && suser(u.u_cred, &u.u_acflag)) 339 return(ENXIO); 340 341 if (sc->sc_hd->hp_dk >= 0) 342 dk_wpms[sc->sc_hd->hp_dk] = sc->sc_wpms; 343 return(0); 344 } 345 346 /* 347 * This routine is called for partial block transfers and non-aligned 348 * transfers (the latter only being possible on devices with a block size 349 * larger than DEV_BSIZE). The operation is performed in three steps 350 * using a locally allocated buffer: 351 * 1. transfer any initial partial block 352 * 2. transfer full blocks 353 * 3. transfer any final partial block 354 */ 355 static void 356 sdlblkstrat(bp, bsize) 357 register struct buf *bp; 358 register int bsize; 359 { 360 register struct buf *cbp = (struct buf *)malloc(sizeof(struct buf), 361 M_DEVBUF, M_WAITOK); 362 caddr_t cbuf = (caddr_t)malloc(bsize, M_DEVBUF, M_WAITOK); 363 register int bn, resid; 364 register caddr_t addr; 365 366 bzero((caddr_t)cbp, sizeof(*cbp)); 367 cbp->b_proc = u.u_procp; 368 cbp->b_dev = bp->b_dev; 369 bn = bp->b_blkno; 370 resid = bp->b_bcount; 371 addr = bp->b_un.b_addr; 372 #ifdef DEBUG 373 if (sddebug & SDB_PARTIAL) 374 printf("sdlblkstrat: bp %x flags %x bn %x resid %x addr %x\n", 375 bp, bp->b_flags, bn, resid, addr); 376 #endif 377 378 while (resid > 0) { 379 register int boff = dbtob(bn) & (bsize - 1); 380 register int count; 381 382 if (boff || resid < bsize) { 383 sdstats[sdunit(bp->b_dev)].sdpartials++; 384 count = MIN(resid, bsize - boff); 385 cbp->b_flags = B_BUSY | B_PHYS | B_READ; 386 cbp->b_blkno = bn - btodb(boff); 387 cbp->b_un.b_addr = cbuf; 388 cbp->b_bcount = bsize; 389 #ifdef DEBUG 390 if (sddebug & SDB_PARTIAL) 391 printf(" readahead: bn %x cnt %x off %x addr %x\n", 392 cbp->b_blkno, count, boff, addr); 393 #endif 394 sdstrategy(cbp); 395 biowait(cbp); 396 if (cbp->b_flags & B_ERROR) { 397 bp->b_flags |= B_ERROR; 398 bp->b_error = cbp->b_error; 399 break; 400 } 401 if (bp->b_flags & B_READ) { 402 bcopy(&cbuf[boff], addr, count); 403 goto done; 404 } 405 bcopy(addr, &cbuf[boff], count); 406 #ifdef DEBUG 407 if (sddebug & SDB_PARTIAL) 408 printf(" writeback: bn %x cnt %x off %x addr %x\n", 409 cbp->b_blkno, count, boff, addr); 410 #endif 411 } else { 412 count = resid & ~(bsize - 1); 413 cbp->b_blkno = bn; 414 cbp->b_un.b_addr = addr; 415 cbp->b_bcount = count; 416 #ifdef DEBUG 417 if (sddebug & SDB_PARTIAL) 418 printf(" fulltrans: bn %x cnt %x addr %x\n", 419 cbp->b_blkno, count, addr); 420 #endif 421 } 422 cbp->b_flags = B_BUSY | B_PHYS | (bp->b_flags & B_READ); 423 sdstrategy(cbp); 424 biowait(cbp); 425 if (cbp->b_flags & B_ERROR) { 426 bp->b_flags |= B_ERROR; 427 bp->b_error = cbp->b_error; 428 break; 429 } 430 done: 431 bn += btodb(count); 432 resid -= count; 433 addr += count; 434 #ifdef DEBUG 435 if (sddebug & SDB_PARTIAL) 436 printf(" done: bn %x resid %x addr %x\n", 437 bn, resid, addr); 438 #endif 439 } 440 free(cbuf, M_DEVBUF); 441 free(cbp, M_DEVBUF); 442 } 443 444 void 445 sdstrategy(bp) 446 register struct buf *bp; 447 { 448 register int part = sdpart(bp->b_dev); 449 register int unit = sdunit(bp->b_dev); 450 register int bn, sz; 451 register struct sd_softc *sc = &sd_softc[unit]; 452 register struct buf *dp = &sdtab[unit]; 453 register int s; 454 455 if (sc->sc_format_pid) { 456 if (sc->sc_format_pid != u.u_procp->p_pid) { 457 bp->b_error = EPERM; 458 goto bad; 459 } 460 bp->b_cylin = 0; 461 } else { 462 bn = bp->b_blkno; 463 sz = (bp->b_bcount + (DEV_BSIZE - 1)) >> DEV_BSHIFT; 464 if (bn < 0 || bn + sz > sc->sc_info.part[part].nblocks) { 465 if (bn == sc->sc_info.part[part].nblocks) { 466 bp->b_resid = bp->b_bcount; 467 goto done; 468 } 469 bp->b_error = EINVAL; 470 goto bad; 471 } 472 /* 473 * Non-aligned or partial-block transfers handled specially. 474 */ 475 s = sc->sc_blksize - 1; 476 if ((dbtob(bn) & s) || (bp->b_bcount & s)) { 477 sdlblkstrat(bp, sc->sc_blksize); 478 goto done; 479 } 480 bp->b_cylin = (bn + sc->sc_info.part[part].strtblk) >> 481 sc->sc_bshift; 482 } 483 s = splbio(); 484 disksort(dp, bp); 485 if (dp->b_active == 0) { 486 dp->b_active = 1; 487 sdustart(unit); 488 } 489 splx(s); 490 return; 491 bad: 492 bp->b_flags |= B_ERROR; 493 done: 494 iodone(bp); 495 } 496 497 void 498 sdustart(unit) 499 register int unit; 500 { 501 if (scsireq(&sd_softc[unit].sc_dq)) 502 sdstart(unit); 503 } 504 505 static void 506 sderror(unit, sc, hp, stat) 507 int unit, stat; 508 register struct sd_softc *sc; 509 register struct hp_device *hp; 510 { 511 sdsense[unit].status = stat; 512 if (stat & STS_CHECKCOND) { 513 struct scsi_xsense *sp; 514 515 scsi_request_sense(hp->hp_ctlr, hp->hp_slave, 516 sc->sc_punit, sdsense[unit].sense, 517 sizeof(sdsense[unit].sense)); 518 sp = (struct scsi_xsense *)sdsense[unit].sense; 519 printf("sd%d: scsi sense class %d, code %d", unit, 520 sp->class, sp->code); 521 if (sp->class == 7) { 522 printf(", key %d", sp->key); 523 if (sp->valid) 524 printf(", blk %d", *(int *)&sp->info1); 525 } 526 printf("\n"); 527 } 528 } 529 530 static void 531 sdfinish(unit, sc, bp) 532 int unit; 533 register struct sd_softc *sc; 534 register struct buf *bp; 535 { 536 sdtab[unit].b_errcnt = 0; 537 sdtab[unit].b_actf = bp->b_actf; 538 bp->b_resid = 0; 539 iodone(bp); 540 scsifree(&sc->sc_dq); 541 if (sdtab[unit].b_actf) 542 sdustart(unit); 543 else 544 sdtab[unit].b_active = 0; 545 } 546 547 void 548 sdstart(unit) 549 register int unit; 550 { 551 register struct sd_softc *sc = &sd_softc[unit]; 552 register struct hp_device *hp = sc->sc_hd; 553 554 /* 555 * we have the SCSI bus -- in format mode, we may or may not need dma 556 * so check now. 557 */ 558 if (sc->sc_format_pid && legal_cmds[sdcmd[unit].cdb[0]] > 0) { 559 register struct buf *bp = sdtab[unit].b_actf; 560 register int sts; 561 562 sts = scsi_immed_command(hp->hp_ctlr, hp->hp_slave, 563 sc->sc_punit, &sdcmd[unit], 564 bp->b_un.b_addr, bp->b_bcount, 565 bp->b_flags & B_READ); 566 sdsense[unit].status = sts; 567 if (sts & 0xfe) { 568 sderror(unit, sc, hp, sts); 569 bp->b_flags |= B_ERROR; 570 bp->b_error = EIO; 571 } 572 sdfinish(unit, sc, bp); 573 574 } else if (scsiustart(hp->hp_ctlr)) 575 sdgo(unit); 576 } 577 578 void 579 sdgo(unit) 580 register int unit; 581 { 582 register struct sd_softc *sc = &sd_softc[unit]; 583 register struct hp_device *hp = sc->sc_hd; 584 register struct buf *bp = sdtab[unit].b_actf; 585 register int pad; 586 register struct scsi_fmt_cdb *cmd; 587 588 if (sc->sc_format_pid) { 589 cmd = &sdcmd[unit]; 590 pad = 0; 591 } else { 592 cmd = bp->b_flags & B_READ? &sd_read_cmd : &sd_write_cmd; 593 *(int *)(&cmd->cdb[2]) = bp->b_cylin; 594 pad = howmany(bp->b_bcount, sc->sc_blksize); 595 *(u_short *)(&cmd->cdb[7]) = pad; 596 pad = (bp->b_bcount & (sc->sc_blksize - 1)) != 0; 597 #ifdef DEBUG 598 if (pad) 599 printf("sd%d: partial block xfer -- %x bytes\n", 600 unit, bp->b_bcount); 601 #endif 602 sdstats[unit].sdtransfers++; 603 } 604 if (scsigo(hp->hp_ctlr, hp->hp_slave, sc->sc_punit, bp, cmd, pad) == 0) { 605 if (hp->hp_dk >= 0) { 606 dk_busy |= 1 << hp->hp_dk; 607 ++dk_seek[hp->hp_dk]; 608 ++dk_xfer[hp->hp_dk]; 609 dk_wds[hp->hp_dk] += bp->b_bcount >> 6; 610 } 611 return; 612 } 613 #ifdef DEBUG 614 if (sddebug & SDB_ERROR) 615 printf("sd%d: sdstart: %s adr %d blk %d len %d ecnt %d\n", 616 unit, bp->b_flags & B_READ? "read" : "write", 617 bp->b_un.b_addr, bp->b_cylin, bp->b_bcount, 618 sdtab[unit].b_errcnt); 619 #endif 620 bp->b_flags |= B_ERROR; 621 bp->b_error = EIO; 622 sdfinish(unit, sc, bp); 623 } 624 625 void 626 sdintr(unit, stat) 627 register int unit; 628 int stat; 629 { 630 register struct sd_softc *sc = &sd_softc[unit]; 631 register struct buf *bp = sdtab[unit].b_actf; 632 register struct hp_device *hp = sc->sc_hd; 633 634 if (bp == NULL) { 635 printf("sd%d: bp == NULL\n", unit); 636 return; 637 } 638 if (hp->hp_dk >= 0) 639 dk_busy &=~ (1 << hp->hp_dk); 640 if (stat) { 641 #ifdef DEBUG 642 if (sddebug & SDB_ERROR) 643 printf("sd%d: sdintr: bad scsi status 0x%x\n", 644 unit, stat); 645 #endif 646 sderror(unit, sc, hp, stat); 647 bp->b_flags |= B_ERROR; 648 bp->b_error = EIO; 649 } 650 sdfinish(unit, sc, bp); 651 } 652 653 int 654 sdread(dev, uio) 655 dev_t dev; 656 struct uio *uio; 657 { 658 register int unit = sdunit(dev); 659 register int pid; 660 661 if ((pid = sd_softc[unit].sc_format_pid) && pid != u.u_procp->p_pid) 662 return (EPERM); 663 664 return(physio(sdstrategy, &sdbuf[unit], dev, B_READ, minphys, uio)); 665 } 666 667 int 668 sdwrite(dev, uio) 669 dev_t dev; 670 struct uio *uio; 671 { 672 register int unit = sdunit(dev); 673 register int pid; 674 675 if ((pid = sd_softc[unit].sc_format_pid) && pid != u.u_procp->p_pid) 676 return (EPERM); 677 678 return(physio(sdstrategy, &sdbuf[unit], dev, B_WRITE, minphys, uio)); 679 } 680 681 int 682 sdioctl(dev, cmd, data, flag) 683 dev_t dev; 684 int cmd; 685 caddr_t data; 686 int flag; 687 { 688 register int unit = sdunit(dev); 689 register struct sd_softc *sc = &sd_softc[unit]; 690 691 switch (cmd) { 692 default: 693 return (EINVAL); 694 695 case SDIOCSFORMAT: 696 /* take this device into or out of "format" mode */ 697 if (suser(u.u_cred, &u.u_acflag)) 698 return(EPERM); 699 700 if (*(int *)data) { 701 if (sc->sc_format_pid) 702 return (EPERM); 703 sc->sc_format_pid = u.u_procp->p_pid; 704 } else 705 sc->sc_format_pid = 0; 706 return (0); 707 708 case SDIOCGFORMAT: 709 /* find out who has the device in format mode */ 710 *(int *)data = sc->sc_format_pid; 711 return (0); 712 713 case SDIOCSCSICOMMAND: 714 /* 715 * Save what user gave us as SCSI cdb to use with next 716 * read or write to the char device. 717 */ 718 if (sc->sc_format_pid != u.u_procp->p_pid) 719 return (EPERM); 720 if (legal_cmds[((struct scsi_fmt_cdb *)data)->cdb[0]] == 0) 721 return (EINVAL); 722 bcopy(data, (caddr_t)&sdcmd[unit], sizeof(sdcmd[0])); 723 return (0); 724 725 case SDIOCSENSE: 726 /* 727 * return the SCSI sense data saved after the last 728 * operation that completed with "check condition" status. 729 */ 730 bcopy((caddr_t)&sdsense[unit], data, sizeof(sdsense[0])); 731 return (0); 732 733 } 734 /*NOTREACHED*/ 735 } 736 737 int 738 sdsize(dev) 739 dev_t dev; 740 { 741 register int unit = sdunit(dev); 742 register struct sd_softc *sc = &sd_softc[unit]; 743 744 if (unit >= NSD || (sc->sc_flags & SDF_ALIVE) == 0) 745 return(-1); 746 747 return(sc->sc_info.part[sdpart(dev)].nblocks); 748 } 749 750 #include "machine/pte.h" 751 #include "machine/vmparam.h" 752 #include "../h/vmmac.h" 753 754 /* 755 * Non-interrupt driven, non-dma dump routine. 756 */ 757 int 758 sddump(dev) 759 dev_t dev; 760 { 761 int part = sdpart(dev); 762 int unit = sdunit(dev); 763 register struct sd_softc *sc = &sd_softc[unit]; 764 register struct hp_device *hp = sc->sc_hd; 765 register daddr_t baddr; 766 register int maddr; 767 register int pages, i; 768 int stat; 769 extern int lowram; 770 771 /* 772 * Hmm... all vax drivers dump maxfree pages which is physmem minus 773 * the message buffer. Is there a reason for not dumping the 774 * message buffer? Savecore expects to read 'dumpsize' pages of 775 * dump, where dumpsys() sets dumpsize to physmem! 776 */ 777 pages = physmem; 778 779 /* is drive ok? */ 780 if (unit >= NSD || (sc->sc_flags & SDF_ALIVE) == 0) 781 return (ENXIO); 782 /* dump parameters in range? */ 783 if (dumplo < 0 || dumplo >= sc->sc_info.part[part].nblocks) 784 return (EINVAL); 785 if (dumplo + ctod(pages) > sc->sc_info.part[part].nblocks) 786 pages = dtoc(sc->sc_info.part[part].nblocks - dumplo); 787 maddr = lowram; 788 baddr = dumplo + sc->sc_info.part[part].strtblk; 789 /* scsi bus idle? */ 790 if (!scsireq(&sc->sc_dq)) { 791 scsireset(hp->hp_ctlr); 792 sdreset(sc, sc->sc_hd); 793 printf("[ drive %d reset ] ", unit); 794 } 795 for (i = 0; i < pages; i++) { 796 #define NPGMB (1024*1024/NBPG) 797 /* print out how many Mbs we have dumped */ 798 if (i && (i % NPGMB) == 0) 799 printf("%d ", i / NPGMB); 800 #undef NPBMG 801 mapin(mmap, (u_int)vmmap, btop(maddr), PG_URKR|PG_CI|PG_V); 802 stat = scsi_tt_write(hp->hp_ctlr, hp->hp_slave, sc->sc_punit, 803 vmmap, NBPG, baddr, sc->sc_bshift); 804 if (stat) { 805 printf("sddump: scsi write error 0x%x\n", stat); 806 return (EIO); 807 } 808 maddr += NBPG; 809 baddr += ctod(1); 810 } 811 return (0); 812 } 813 #endif 814