1 /* 2 * Copyright (c) 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This software was developed by the Computer Systems Engineering group 6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 7 * contributed to Berkeley. 8 * 9 * %sccs.include.redist.c% 10 * 11 * @(#)scsi_subr.c 5.1 (Berkeley) 07/10/92 12 * 13 * from: $Header: scsi_subr.c,v 1.7 92/06/11 17:55:48 torek Exp $ (LBL) 14 */ 15 16 /* 17 * Generic SCSI host adapter driver. 18 * Does almost nothing (most work is relegated to per-hba drivers). 19 */ 20 21 #include "sys/param.h" 22 #include "sys/buf.h" 23 #include "sys/device.h" 24 #include "scsi/scsi.h" 25 #include "scsi/scsivar.h" 26 27 /* 28 * General subroutines, and scsi data. 29 */ 30 31 /* table of lengths of scsi commands */ 32 const char scsicmdlen[8] = { 6, 10, 0, 0, 0, 12, 0, 0 }; 33 34 /* table of lengths of scsi messages */ 35 const signed char scsimsglen[0x24] = { 36 SMLEN_DONE, /* MSG_CMD_COMPLETE */ 37 SMLEN_EXTENDED, /* MSG_EXT_MESSAGE */ 38 1, /* MSG_SAVE_DATA_PTR */ 39 1, /* MSG_RESTORE_PTR */ 40 1, /* MSG_DISCONNECT */ 41 1, /* MSG_INIT_DETECT_ERROR */ 42 1, /* MSG_ABORT */ 43 1, /* MSG_REJECT */ 44 1, /* MSG_NOOP */ 45 1, /* MSG_PARITY_ERROR */ 46 1, /* MSG_LCC */ 47 1, /* MSG_LCCF */ 48 1, /* MSG_BUS_DEVICE_RESET */ 49 1, /* MSG_ABORT_TAG */ 50 1, /* MSG_CLEAR_QUEUE */ 51 1, /* MSG_INITIATE_RECOVERY */ 52 1, /* MSG_RELEASE_RECOVERY */ 53 1, /* MSG_TERMINATE_PROCESS */ 54 SMLEN_UNDEF, /* 0x12 */ 55 SMLEN_UNDEF, /* 0x13 */ 56 SMLEN_UNDEF, /* 0x14 */ 57 SMLEN_UNDEF, /* 0x15 */ 58 SMLEN_UNDEF, /* 0x16 */ 59 SMLEN_UNDEF, /* 0x17 */ 60 SMLEN_UNDEF, /* 0x18 */ 61 SMLEN_UNDEF, /* 0x19 */ 62 SMLEN_UNDEF, /* 0x1a */ 63 SMLEN_UNDEF, /* 0x1b */ 64 SMLEN_UNDEF, /* 0x1c */ 65 SMLEN_UNDEF, /* 0x1d */ 66 SMLEN_UNDEF, /* 0x1e */ 67 SMLEN_UNDEF, /* 0x1f */ 68 2, /* MSG_SIMPLE_QTAG */ 69 2, /* MSG_HEAD_QTAG */ 70 2, /* MSG_ORDERED_QTAG */ 71 2, /* MSG_IGNORE_WIDE_RESID */ 72 }; 73 74 /* definition of `tg' target driver for autoconfig */ 75 static int scsi_targmatch __P((struct device *, struct cfdata *, void *)); 76 static void scsi_targattach __P((struct device *, struct device *, void *)); 77 struct cfdriver tgcd = 78 { NULL, "tg", scsi_targmatch, scsi_targattach, 79 DV_DULL, sizeof(struct targ) }; 80 81 void scsi_targstart __P((struct device *, struct sq *, struct buf *, 82 scdgo_fn, struct device *)); 83 int scsi_targgo __P((struct device *, int targ, 84 scintr_fn, struct device *, struct buf *, int)); 85 void scsi_targintr __P((struct device *, int, int)); 86 void scsi_targrel __P((struct device *)); 87 88 #define NOBUF ((caddr_t)0) 89 90 /* 91 * Perform a TEST UNIT READY immediate (polled) command 92 * on the given <target,unit> pair. Return the status byte 93 * returned, or -1 for none. 94 */ 95 int 96 scsi_test_unit_ready(hba, targ, unit) 97 struct hba_softc *hba; 98 int targ, unit; 99 { 100 struct scsi_cdb cdb; 101 102 CDB6(&cdb)->cdb_cmd = CMD_TEST_UNIT_READY; 103 CDB6(&cdb)->cdb_lun_lbah = unit << 5; 104 *(short *)&CDB6(&cdb)->cdb_lbam = 0; 105 *(short *)&CDB6(&cdb)->cdb_len = 0; 106 return (hba->hba_driver->hd_icmd(hba, targ, &cdb, NOBUF, 0, 0)); 107 } 108 109 /* 110 * Request sense. The sense is to be written into the given buffer. 111 * The given length must be < 256. 112 */ 113 int 114 scsi_request_sense(hba, targ, unit, buf, len) 115 struct hba_softc *hba; 116 int targ, unit; 117 caddr_t buf; 118 int len; 119 { 120 struct scsi_cdb cdb; 121 122 CDB6(&cdb)->cdb_cmd = CMD_REQUEST_SENSE; 123 CDB6(&cdb)->cdb_lun_lbah = unit << 5; 124 *(short *)&CDB6(&cdb)->cdb_lbam = 0; 125 CDB6(&cdb)->cdb_len = len; 126 CDB6(&cdb)->cdb_ctrl = 0; 127 return (hba->hba_driver->hd_icmd(hba, targ, &cdb, buf, len, B_READ)); 128 } 129 130 /* 131 * Called (indirectly, via config_found) from scsi_hbaattach. 132 * Print target number, and if no device was configured there, 133 * the hba as well. 134 */ 135 int 136 scsi_targprint(aux, hba) 137 void *aux; 138 char *hba; 139 { 140 141 if (hba) { 142 printf("target %d on %s", *(int *)aux, hba); 143 return (UNCONF); 144 } 145 printf(" target %d", *(int *)aux); 146 return (QUIET); 147 } 148 149 /* 150 * Print information about a unit found on some target. 151 * If the unit was not configured, `targ' is the name of the target 152 * on which the unit was found. If it was, targ is NULL and we 153 * let the unit's attach routine print the INQUIRE result if 154 * appropriate. 155 */ 156 static int 157 scsi_unitprint(aux, targ) 158 void *aux; 159 char *targ; 160 { 161 register struct scsi_attach_args *sa = aux; 162 163 if (targ) { 164 printf("unit %d at %s", sa->sa_unit, targ); 165 if ((sa->sa_inq_status & STS_MASK) == STS_GOOD) { 166 printf(" ("); 167 scsi_printinq(&sa->sa_si); 168 printf(")"); 169 } 170 return (UNCONF); 171 } 172 printf(" unit %d", sa->sa_unit); 173 return (QUIET); 174 } 175 176 /* 177 * Generic target-match. 178 */ 179 static int 180 scsi_targmatch(parent, cf, aux) 181 struct device *parent; 182 register struct cfdata *cf; 183 void *aux; 184 { 185 int targ = *(int *)aux; 186 187 return (cf->cf_loc[0] == targ || cf->cf_loc[0] == -1); 188 } 189 190 /* 191 * And now, a generic `target attach' routine. 192 * We assume that INQUIRY works. 193 */ 194 static void 195 scsi_targattach(parent, self, aux) 196 struct device *parent, *self; 197 void *aux; 198 { 199 register struct targ *t = (struct targ *)self; 200 register struct hba_softc *hba; 201 register struct hbadriver *hd; 202 register int targ, unit; 203 struct scsi_attach_args sa; 204 struct scsi_cdb si; 205 206 printf("\n"); 207 t->t_targ = targ = *(int *)aux; 208 hba = (struct hba_softc *)parent; 209 hba->hba_targets[targ] = t; 210 211 /* 212 * Probe each of the 8 units using the sequence 213 * TEST UNIT READY 214 * REQUEST SENSE 215 * INQUIRY 216 * The first should not be necessary, but some SCSI devices 217 * refuse to speak until it is done. The second is only necessary 218 * if the first returns a CHECK CONDITION status, but we do it 219 * anyway. 220 */ 221 hd = hba->hba_driver; 222 sa.sa_targ = targ; 223 CDB6(&si)->cdb_cmd = CMD_INQUIRY; 224 *(short *)&CDB6(&si)->cdb_lbam = 0; 225 CDB6(&si)->cdb_len = sizeof sa.sa_si; 226 CDB6(&si)->cdb_ctrl = 0; 227 for (unit = 0; unit < 8; unit++) { 228 if (scsi_test_unit_ready(hba, targ, unit) == -1) 229 continue; 230 sa.sa_unit = unit; 231 sa.sa_req_status = scsi_request_sense(hba, targ, unit, 232 (caddr_t)&sa.sa_sn, sizeof sa.sa_sn); 233 CDB6(&si)->cdb_lun_lbah = unit << 5; 234 sa.sa_inq_status = (*hd->hd_icmd)(hba, targ, &si, 235 (caddr_t)&sa.sa_si, sizeof sa.sa_si, B_READ); 236 if ((sa.sa_inq_status & STS_MASK) == STS_GOOD && 237 #ifdef notdef /* XXX don't know if this is a reasonable test */ 238 (sa.sa_si.si_type & TYPE_QUAL_MASK) == TYPE_QUAL_NOTCONN && 239 #endif 240 (sa.sa_si.si_type & TYPE_TYPE_MASK) == TYPE_NP) { 241 continue; 242 } 243 config_found(&t->t_dev, (void *)&sa, scsi_unitprint); 244 } 245 } 246 247 /* 248 * Each unit calls scsi_establish to tell the hba and target of 249 * its existence. 250 */ 251 void 252 scsi_establish(u, dev, unit) 253 register struct unit *u; 254 struct device *dev; 255 register int unit; 256 { 257 register struct targ *t; 258 register struct hba_softc *hba; 259 register struct hbadriver *hbd; 260 261 u->u_dev = dev; 262 t = (struct targ *)dev->dv_parent; 263 hba = (struct hba_softc *)t->t_dev.dv_parent; 264 hbd = hba->hba_driver; 265 t->t_units[unit] = u; 266 if (t->t_nunits == 0) { 267 /* 268 * This is the first unit on the target. We can 269 * probably just call the hba start code, avoiding 270 * one level of calls and queueing. If we attach 271 * another target we will fix this in the code below. 272 */ 273 u->u_start = hbd->hd_start; 274 u->u_go = hbd->hd_go; 275 u->u_rel = hbd->hd_rel; 276 u->u_updev = &hba->hba_dev; 277 t->t_firstunit = unit; 278 } else { 279 /* 280 * This is not the only unit on the target, so we 281 * must call the target start code rather than the 282 * hba start code. Fix the linkage on the first 283 * target too (possibly for the 2nd, 3rd, ..., time). 284 */ 285 t->t_units[t->t_firstunit]->u_start = scsi_targstart; 286 t->t_units[t->t_firstunit]->u_updev = &t->t_dev; 287 u->u_start = scsi_targstart; 288 u->u_go = scsi_targgo; 289 u->u_rel = scsi_targrel; 290 u->u_updev = &t->t_dev; 291 } 292 t->t_nunits++; /* another unit is alive */ 293 u->u_unit = unit; 294 u->u_targ = t->t_targ; /* record target number, */ 295 u->u_hba = hba; /* hba ... */ 296 u->u_hbd = hbd; /* and driver */ 297 } 298 299 /* NO DOUBT SOME OF THE STUFF PRINTED HERE IS USELESS */ 300 void 301 scsi_printinq(inq) 302 register struct scsi_inquiry *inq; 303 { 304 register int iso, ecma, ansi, t; 305 static char *types[] = { "disk", "tape", "printer", "processor", 306 "WORM", "ROM disk", "scanner", "magneto-optical", 307 "jukebox", "lan" }; 308 309 if ((t = (inq->si_type & TYPE_QUAL_MASK)) != 0) 310 printf("type-qual=0x%x ", t); 311 t = inq->si_type & TYPE_TYPE_MASK; 312 if (t < sizeof types / sizeof *types) 313 printf("%s", types[t]); 314 else 315 printf("<type %d>", t); 316 if (inq->si_qual & QUAL_RMB) 317 printf(" (removable)"); 318 printf(" qual=0x%x", inq->si_qual & QUAL_MASK); 319 iso = (inq->si_qual >> VER_ISO_SHIFT) & VER_ISO_MASK; 320 ecma = (inq->si_qual >> VER_ECMA_SHIFT) & VER_ECMA_MASK; 321 ansi = (inq->si_qual >> VER_ANSI_SHIFT) & VER_ANSI_MASK; 322 printf(" version=<iso %d, ecma %d, ansi %d>", iso, ecma, ansi); 323 if (ansi == 1 || ansi == 2) { 324 char v[9], p[17], r[5]; 325 326 scsi_inq_ansi((struct scsi_inq_ansi *)inq, v, p, r); 327 printf(" vendor %s, product %s, rev %s", v, p, r); 328 } 329 } 330 331 /* copy a counted string but trim trailing blanks; make the dest a C string */ 332 static void 333 scsi_str(src, dst, len) 334 register char *src, *dst; 335 register int len; 336 { 337 338 while (src[len - 1] == ' ') { 339 if (--len == 0) { 340 *dst = 0; 341 return; 342 } 343 } 344 bcopy(src, dst, len); 345 dst[len] = 0; 346 } 347 348 void 349 scsi_inq_ansi(si, vendor, product, rev) 350 register struct scsi_inq_ansi *si; 351 char *vendor, *product, *rev; 352 { 353 register int i, len; 354 355 /* if too short, extend with blanks */ 356 len = si->si_len + 5; /* 5 fixed; len is `additional' */ 357 if (len < sizeof(*si)) 358 for (i = len; i < sizeof *si; i++) 359 ((char *)si)[i] = ' '; 360 scsi_str(si->si_vendor, vendor, sizeof si->si_vendor); 361 scsi_str(si->si_product, product, sizeof si->si_product); 362 scsi_str(si->si_rev, rev, sizeof si->si_rev); 363 } 364 365 /* 366 * Tell all the devices on the given hba that it has been reset. 367 * SHOULD PROBABLY DO MORE HERE 368 */ 369 void 370 scsi_reset_units(hba) 371 register struct hba_softc *hba; 372 { 373 register int targ, unit; 374 register struct targ *t; 375 register struct unit *u; 376 377 for (targ = 0; targ < 8; targ++) { 378 if ((t = hba->hba_targets[targ]) == NULL) 379 continue; 380 for (unit = 0; unit < 8; unit++) 381 if ((u = t->t_units[unit]) != NULL) 382 (*u->u_driver->ud_reset)(u); 383 } 384 } 385 386 /* 387 * Start a unit on a target. 388 * If the target is busy, just enqueue the unit; 389 * once the target becomes free, we will call the hba start routine. 390 * Otherwise, call the hba start routine now, and then when the hba 391 * becomes free it will call the unit's dgo routine. 392 */ 393 void 394 scsi_targstart(self, sq, bp, dgo, dev) 395 struct device *self; 396 register struct sq *sq; 397 struct buf *bp; 398 scdgo_fn dgo; 399 struct device *dev; 400 { 401 register struct targ *t = (struct targ *)self; 402 register struct hba_softc *hba; 403 404 sq->sq_forw = NULL; 405 if (t->t_head == NULL) 406 t->t_head = sq; 407 else 408 t->t_tail->sq_forw = sq; 409 t->t_tail = sq; 410 if (t->t_busy == 0) { 411 t->t_busy = 1; 412 hba = (struct hba_softc *)t->t_dev.dv_parent; 413 (*hba->hba_driver->hd_start)(&hba->hba_dev, &t->t_forw, bp, 414 dgo, dev); 415 } else { 416 sq->sq_bp = bp; 417 sq->sq_dgo = dgo; 418 sq->sq_dev = dev; 419 } 420 } 421 422 /* 423 * The unit got the bus, and wants the hba to go. 424 * Remember its interrupt handler; substitute ours instead. 425 */ 426 int 427 scsi_targgo(self, targ, intr, dev, bp, pad) 428 struct device *self; 429 int targ; 430 scintr_fn intr; 431 struct device *dev; 432 struct buf *bp; 433 int pad; 434 { 435 register struct targ *t = (struct targ *)self; 436 register struct hba_softc *hba; 437 438 t->t_intr = intr; 439 t->t_intrdev = dev; 440 hba = (struct hba_softc *)t->t_dev.dv_parent; 441 return ((*hba->hba_driver->hd_go)(&hba->hba_dev, targ, 442 scsi_targintr, &t->t_dev, bp, pad)); 443 } 444 445 /* 446 * The hba got an interrupt. Dequeue the unit from the target 447 * (the target is already off the hba queue) and then call the 448 * underlying interrupt handler. 449 */ 450 void 451 scsi_targintr(self, stat, resid) 452 struct device *self; 453 int stat, resid; 454 { 455 register struct targ *t = (struct targ *)self; 456 register struct hba_softc *hba; 457 register struct sq *sq; 458 459 sq = t->t_head; 460 if (sq == NULL) panic("scsi_targintr"); 461 t->t_head = sq = sq->sq_forw; 462 (*t->t_intr)(t->t_intrdev, stat, resid); 463 if (sq != NULL) { 464 hba = (struct hba_softc *)t->t_dev.dv_parent; 465 (*hba->hba_driver->hd_start)(&hba->hba_dev, &t->t_forw, 466 sq->sq_bp, sq->sq_dgo, sq->sq_dev); 467 } else 468 t->t_busy = 0; 469 } 470 471 /* 472 * The unit decided that it needed to `give up' its hold on the bus early. 473 */ 474 void 475 scsi_targrel(self) 476 struct device *self; 477 { 478 register struct targ *t = (struct targ *)self; 479 register struct hba_softc *hba; 480 register struct sq *sq; 481 482 hba = (struct hba_softc *)t->t_dev.dv_parent; 483 sq = t->t_head; 484 if (sq == NULL) panic("scsi_targrel"); 485 /* 486 * This target is at the head of the hba queue. 487 * Remove it by calling hba bus release. Then, if the 488 * target queue is not empty, put it back on the hba queue. 489 * (This produces round robin service.) 490 */ 491 (*hba->hba_driver->hd_rel)(&hba->hba_dev); 492 sq = sq->sq_forw; 493 if ((t->t_head = sq) != NULL) 494 (*hba->hba_driver->hd_start)(&hba->hba_dev, &t->t_forw, 495 sq->sq_bp, sq->sq_dgo, sq->sq_dev); 496 else 497 t->t_busy = 0; 498 } 499