scsiconf.c revision 1.1 1 1.1 cgd /*
2 1.1 cgd * Written by Julian Elischer (julian (at) tfs.com)
3 1.1 cgd * for TRW Financial Systems for use under the MACH(2.5) operating system.
4 1.1 cgd *
5 1.1 cgd * TRW Financial Systems, in accordance with their agreement with Carnegie
6 1.1 cgd * Mellon University, makes this software available to CMU to distribute
7 1.1 cgd * or use in any manner that they see fit as long as this message is kept with
8 1.1 cgd * the software. For this reason TFS also grants any other persons or
9 1.1 cgd * organisations permission to use or modify this software.
10 1.1 cgd *
11 1.1 cgd * TFS supplies this software to be publicly redistributed
12 1.1 cgd * on the understanding that TFS is not responsible for the correct
13 1.1 cgd * functioning of this software in any circumstances.
14 1.1 cgd *
15 1.1 cgd *
16 1.1 cgd * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
17 1.1 cgd * -------------------- ----- ----------------------
18 1.1 cgd * CURRENT PATCH LEVEL: 1 00098
19 1.1 cgd * -------------------- ----- ----------------------
20 1.1 cgd *
21 1.1 cgd * 16 Feb 93 Julian Elischer ADDED for SCSI system
22 1.1 cgd */
23 1.1 cgd
24 1.1 cgd /*
25 1.1 cgd * Ported to run under 386BSD by Julian Elischer (julian (at) tfs.com) Sept 1992
26 1.1 cgd */
27 1.1 cgd
28 1.1 cgd /*
29 1.1 cgd $Log:
30 1.1 cgd *
31 1.1 cgd */
32 1.1 cgd #include <sys/types.h>
33 1.1 cgd #include "st.h"
34 1.1 cgd #include "sd.h"
35 1.1 cgd #include "ch.h"
36 1.1 cgd #include "cd.h"
37 1.1 cgd
38 1.1 cgd #ifdef MACH
39 1.1 cgd #include <i386/machparam.h>
40 1.1 cgd #endif MACH
41 1.1 cgd #include <scsi/scsi_all.h>
42 1.1 cgd #include <scsi/scsiconf.h>
43 1.1 cgd
44 1.1 cgd #if !defined(OSF) && !defined(__386BSD__)
45 1.1 cgd #include "bll.h"
46 1.1 cgd #include "cals.h"
47 1.1 cgd #include "kil.h"
48 1.1 cgd #else
49 1.1 cgd #define NBLL 0
50 1.1 cgd #define NCALS 0
51 1.1 cgd #define NKIL 0
52 1.1 cgd #endif /* !defined(OSF) && !defined(__386BSD__) */
53 1.1 cgd
54 1.1 cgd #if NSD > 0
55 1.1 cgd extern sdattach();
56 1.1 cgd #endif NSD
57 1.1 cgd #if NST > 0
58 1.1 cgd extern stattach();
59 1.1 cgd #endif NST
60 1.1 cgd #if NCH > 0
61 1.1 cgd extern chattach();
62 1.1 cgd #endif NCH
63 1.1 cgd #if NCD > 0
64 1.1 cgd extern cdattach();
65 1.1 cgd #endif NCD
66 1.1 cgd #if NBLL > 0
67 1.1 cgd extern bllattach();
68 1.1 cgd #endif NBLL
69 1.1 cgd #if NCALS > 0
70 1.1 cgd extern calsattach();
71 1.1 cgd #endif NCALS
72 1.1 cgd #if NKIL > 0
73 1.1 cgd extern kil_attach();
74 1.1 cgd #endif NKIL
75 1.1 cgd
76 1.1 cgd /***************************************************************\
77 1.1 cgd * The structure of pre-configured devices that might be turned *
78 1.1 cgd * off and therefore may not show up *
79 1.1 cgd \***************************************************************/
80 1.1 cgd struct predefined
81 1.1 cgd {
82 1.1 cgd u_char scsibus;
83 1.1 cgd u_char dev;
84 1.1 cgd u_char lu;
85 1.1 cgd int (*attach_rtn)();
86 1.1 cgd char *devname;
87 1.1 cgd char flags;
88 1.1 cgd }
89 1.1 cgd pd[] =
90 1.1 cgd {
91 1.1 cgd #ifdef EXAMPLE_PREDEFINE
92 1.1 cgd #if NSD > 0
93 1.1 cgd {0,0,0,sdattach,"sd",0},/* define a disk at scsibus=0 dev=0 lu=0 */
94 1.1 cgd #endif NSD
95 1.1 cgd #endif EXAMPLE_PREDEFINE
96 1.1 cgd {0,9,9} /*illegal dummy end entry */
97 1.1 cgd };
98 1.1 cgd
99 1.1 cgd
100 1.1 cgd /***************************************************************\
101 1.1 cgd * The structure of known drivers for autoconfiguration *
102 1.1 cgd \***************************************************************/
103 1.1 cgd static struct scsidevs
104 1.1 cgd {
105 1.1 cgd int type;
106 1.1 cgd int removable;
107 1.1 cgd char *manufacturer;
108 1.1 cgd char *model;
109 1.1 cgd char *version;
110 1.1 cgd int (*attach_rtn)();
111 1.1 cgd char *devname;
112 1.1 cgd char flags; /* 1 show my comparisons during boot(debug) */
113 1.1 cgd }
114 1.1 cgd #define SC_SHOWME 0x01
115 1.1 cgd #define SC_ONE_LU 0x00
116 1.1 cgd #define SC_MORE_LUS 0x02
117 1.1 cgd knowndevs[] = {
118 1.1 cgd #if NSD > 0
119 1.1 cgd { T_DIRECT,T_FIXED,"standard","any"
120 1.1 cgd ,"any",sdattach,"sd",SC_ONE_LU },
121 1.1 cgd { T_DIRECT,T_FIXED,"MAXTOR ","XT-4170S "
122 1.1 cgd ,"B5A ",sdattach,"mx1",SC_ONE_LU },
123 1.1 cgd #endif NSD
124 1.1 cgd #if NST > 0
125 1.1 cgd { T_SEQUENTIAL,T_REMOV,"standard","any"
126 1.1 cgd ,"any",stattach,"st",SC_ONE_LU },
127 1.1 cgd #endif NST
128 1.1 cgd #if NCALS > 0
129 1.1 cgd { T_PROCESSOR,T_FIXED,"standard","any"
130 1.1 cgd ,"any",calsattach,"cals",SC_MORE_LUS },
131 1.1 cgd #endif NCALS
132 1.1 cgd #if NCH > 0
133 1.1 cgd { T_CHANGER,T_REMOV,"standard","any"
134 1.1 cgd ,"any",chattach,"ch",SC_ONE_LU },
135 1.1 cgd #endif NCH
136 1.1 cgd #if NCD > 0
137 1.1 cgd { T_READONLY,T_REMOV,"SONY ","CD-ROM CDU-8012 "
138 1.1 cgd ,"3.1a",cdattach,"cd",SC_ONE_LU },
139 1.1 cgd #endif NCD
140 1.1 cgd #if NBLL > 0
141 1.1 cgd { T_PROCESSOR,T_FIXED,"AEG ","READER "
142 1.1 cgd ,"V1.0",bllattach,"bll",SC_MORE_LUS },
143 1.1 cgd #endif NBLL
144 1.1 cgd #if NKIL > 0
145 1.1 cgd { T_SCANNER,T_FIXED,"KODAK ","IL Scanner 900 "
146 1.1 cgd ,"any",kil_attach,"kil",SC_ONE_LU },
147 1.1 cgd #endif NKIL
148 1.1 cgd
149 1.1 cgd {0}
150 1.1 cgd };
151 1.1 cgd /***************************************************************\
152 1.1 cgd * Declarations *
153 1.1 cgd \***************************************************************/
154 1.1 cgd struct predefined *scsi_get_predef();
155 1.1 cgd struct scsidevs *scsi_probedev();
156 1.1 cgd struct scsidevs *selectdev();
157 1.1 cgd
158 1.1 cgd /* controls debug level within the scsi subsystem */
159 1.1 cgd /* see scsiconf.h for values */
160 1.1 cgd int scsi_debug = 0x0;
161 1.1 cgd int scsibus = 0x0; /* This is the Nth scsibus */
162 1.1 cgd
163 1.1 cgd /***************************************************************\
164 1.1 cgd * The routine called by the adapter boards to get all their *
165 1.1 cgd * devices configured in. *
166 1.1 cgd \***************************************************************/
167 1.1 cgd scsi_attachdevs( unit, scsi_addr, scsi_switch)
168 1.1 cgd int unit,scsi_addr;
169 1.1 cgd struct scsi_switch *scsi_switch;
170 1.1 cgd {
171 1.1 cgd int targ,lun;
172 1.1 cgd struct scsidevs *bestmatch = (struct scsidevs *)0;
173 1.1 cgd struct predefined *predef;
174 1.1 cgd int maybe_more;
175 1.1 cgd
176 1.1 cgd #ifdef SCSI_DELAY
177 1.1 cgd #if SCSI_DELAY > 2
178 1.1 cgd printf("waiting for scsi devices to settle\n");
179 1.1 cgd #else SCSI_DELAY > 2
180 1.1 cgd #define SCSI_DELAY 15
181 1.1 cgd #endif SCSI_DELAY > 2
182 1.1 cgd #else
183 1.1 cgd #define SCSI_DELAY 2
184 1.1 cgd #endif SCSI_DELAY
185 1.1 cgd spinwait(1000 * SCSI_DELAY);
186 1.1 cgd targ = 0;
187 1.1 cgd while(targ < 8)
188 1.1 cgd {
189 1.1 cgd maybe_more = 0; /* by default only check 1 lun */
190 1.1 cgd if (targ == scsi_addr)
191 1.1 cgd {
192 1.1 cgd targ++;
193 1.1 cgd continue;
194 1.1 cgd }
195 1.1 cgd lun = 0;
196 1.1 cgd while(lun < 8)
197 1.1 cgd {
198 1.1 cgd predef = scsi_get_predef(scsibus
199 1.1 cgd ,targ
200 1.1 cgd ,lun
201 1.1 cgd ,&maybe_more);
202 1.1 cgd bestmatch = scsi_probedev(unit
203 1.1 cgd ,targ
204 1.1 cgd ,lun
205 1.1 cgd ,scsi_switch
206 1.1 cgd ,&maybe_more);
207 1.1 cgd if((bestmatch) && (predef)) /* both exist */
208 1.1 cgd {
209 1.1 cgd if(bestmatch->attach_rtn
210 1.1 cgd != predef->attach_rtn)
211 1.1 cgd {
212 1.1 cgd printf("Clash in found/expected devices\n");
213 1.1 cgd printf("will link in FOUND\n");
214 1.1 cgd }
215 1.1 cgd (*(bestmatch->attach_rtn))(unit,
216 1.1 cgd targ,
217 1.1 cgd lun,
218 1.1 cgd scsi_switch);
219 1.1 cgd }
220 1.1 cgd if((bestmatch) && (!predef)) /* just FOUND */
221 1.1 cgd {
222 1.1 cgd (*(bestmatch->attach_rtn))(unit,
223 1.1 cgd targ,
224 1.1 cgd lun,
225 1.1 cgd scsi_switch);
226 1.1 cgd }
227 1.1 cgd if((!bestmatch) && (predef)) /* just predef */
228 1.1 cgd {
229 1.1 cgd (*(predef->attach_rtn))(unit,
230 1.1 cgd targ,
231 1.1 cgd lun,
232 1.1 cgd scsi_switch);
233 1.1 cgd }
234 1.1 cgd if(!(maybe_more)) /* nothing suggests we'll find more */
235 1.1 cgd {
236 1.1 cgd break; /* nothing here, skip to next targ */
237 1.1 cgd }
238 1.1 cgd /* otherwise something says we should look further*/
239 1.1 cgd lun++;
240 1.1 cgd }
241 1.1 cgd targ++;
242 1.1 cgd }
243 1.1 cgd #if NGENSCSI > 0
244 1.1 cgd /***************************************************************\
245 1.1 cgd * If available hook up the generic scsi driver, letting it *
246 1.1 cgd * know which target is US. (i.e. illegal or at least special) *
247 1.1 cgd \***************************************************************/
248 1.1 cgd genscsi_attach(unit,scsi_addr,0,scsi_switch);
249 1.1 cgd #endif
250 1.1 cgd scsibus++; /* next time we are on the NEXT scsi bus */
251 1.1 cgd }
252 1.1 cgd
253 1.1 cgd /***********************************************\
254 1.1 cgd * given a target and lu, check if there is a *
255 1.1 cgd * predefined device for that address *
256 1.1 cgd \***********************************************/
257 1.1 cgd struct predefined *scsi_get_predef(unit,target,lu,maybe_more)
258 1.1 cgd int unit,target,lu,*maybe_more;
259 1.1 cgd {
260 1.1 cgd int upto,numents;
261 1.1 cgd
262 1.1 cgd numents = (sizeof(pd)/sizeof(struct predefined)) - 1;
263 1.1 cgd
264 1.1 cgd for(upto = 0;upto < numents;upto++)
265 1.1 cgd {
266 1.1 cgd if(pd[upto].scsibus != unit)
267 1.1 cgd continue;
268 1.1 cgd if(pd[upto].dev != target)
269 1.1 cgd continue;
270 1.1 cgd if(pd[upto].lu != lu)
271 1.1 cgd continue;
272 1.1 cgd
273 1.1 cgd printf(" dev%d,lu%d: %s - PRECONFIGURED -\n"
274 1.1 cgd ,target
275 1.1 cgd ,lu
276 1.1 cgd ,pd[upto].devname);
277 1.1 cgd *maybe_more = pd[upto].flags & SC_MORE_LUS;
278 1.1 cgd return(&(pd[upto]));
279 1.1 cgd }
280 1.1 cgd return((struct predefined *)0);
281 1.1 cgd }
282 1.1 cgd
283 1.1 cgd /***********************************************\
284 1.1 cgd * given a target and lu, ask the device what *
285 1.1 cgd * it is, and find the correct driver table *
286 1.1 cgd * entry. *
287 1.1 cgd \***********************************************/
288 1.1 cgd struct scsidevs *scsi_probedev(unit,target,lu,scsi_switch, maybe_more)
289 1.1 cgd
290 1.1 cgd struct scsi_switch *scsi_switch;
291 1.1 cgd int unit,target,lu;
292 1.1 cgd int *maybe_more;
293 1.1 cgd {
294 1.1 cgd struct scsidevs *bestmatch = (struct scsidevs *)0;
295 1.1 cgd char *dtype=(char *)0,*desc;
296 1.1 cgd char *qtype;
297 1.1 cgd static struct scsi_inquiry_data inqbuf;
298 1.1 cgd int len,qualifier,type,remov;
299 1.1 cgd char manu[32];
300 1.1 cgd char model[32];
301 1.1 cgd char version[32];
302 1.1 cgd
303 1.1 cgd
304 1.1 cgd bzero(&inqbuf,sizeof(inqbuf));
305 1.1 cgd /***********************************************\
306 1.1 cgd * Ask the device what it is *
307 1.1 cgd \***********************************************/
308 1.1 cgd #ifdef DEBUG
309 1.1 cgd if((target == 0) && (lu == 0))
310 1.1 cgd scsi_debug = 0xfff;
311 1.1 cgd else
312 1.1 cgd scsi_debug = 0;
313 1.1 cgd #endif DEBUG
314 1.1 cgd if(scsi_ready( unit,
315 1.1 cgd target,
316 1.1 cgd lu,
317 1.1 cgd scsi_switch,
318 1.1 cgd SCSI_NOSLEEP | SCSI_NOMASK) != COMPLETE)
319 1.1 cgd {
320 1.1 cgd return(struct scsidevs *)0;
321 1.1 cgd }
322 1.1 cgd if(scsi_inquire(unit,
323 1.1 cgd target,
324 1.1 cgd lu,
325 1.1 cgd scsi_switch,
326 1.1 cgd &inqbuf,
327 1.1 cgd SCSI_NOSLEEP | SCSI_NOMASK) != COMPLETE)
328 1.1 cgd {
329 1.1 cgd return(struct scsidevs *)0;
330 1.1 cgd }
331 1.1 cgd
332 1.1 cgd /***********************************************\
333 1.1 cgd * note what BASIC type of device it is *
334 1.1 cgd \***********************************************/
335 1.1 cgd if(scsi_debug & SHOWINQUIRY)
336 1.1 cgd {
337 1.1 cgd desc=(char *)&inqbuf;
338 1.1 cgd printf("inq: %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
339 1.1 cgd desc[0], desc[1], desc[2], desc[3],
340 1.1 cgd desc[4], desc[5], desc[6], desc[7],
341 1.1 cgd desc[8], desc[9], desc[10], desc[11],
342 1.1 cgd desc[12]);
343 1.1 cgd }
344 1.1 cgd
345 1.1 cgd type = inqbuf.device_type;
346 1.1 cgd qualifier = inqbuf.device_qualifier;
347 1.1 cgd remov = inqbuf.removable;
348 1.1 cgd
349 1.1 cgd /* Check for a non-existent unit. If the device is returning
350 1.1 cgd * this much, then we must set the flag that has
351 1.1 cgd * the searcher keep looking on other luns.
352 1.1 cgd */
353 1.1 cgd if (qualifier == 3 && type == T_NODEVICE)
354 1.1 cgd {
355 1.1 cgd *maybe_more = 1;
356 1.1 cgd return (struct scsidevs *)0;
357 1.1 cgd }
358 1.1 cgd
359 1.1 cgd /* Any device qualifier that has
360 1.1 cgd * the top bit set (qualifier&4 != 0) is vendor specific and
361 1.1 cgd * won't match in this switch.
362 1.1 cgd */
363 1.1 cgd
364 1.1 cgd switch(qualifier)
365 1.1 cgd {
366 1.1 cgd case 0:
367 1.1 cgd qtype="";
368 1.1 cgd break;
369 1.1 cgd case 1:
370 1.1 cgd qtype=", Unit not Connected!";
371 1.1 cgd break;
372 1.1 cgd case 2:
373 1.1 cgd qtype=", Reserved Peripheral Qualifier!";
374 1.1 cgd break;
375 1.1 cgd case 3:
376 1.1 cgd qtype=", The Target can't support this Unit!";
377 1.1 cgd break;
378 1.1 cgd
379 1.1 cgd default:
380 1.1 cgd dtype="vendor specific";
381 1.1 cgd qtype="";
382 1.1 cgd *maybe_more = 1;
383 1.1 cgd break;
384 1.1 cgd }
385 1.1 cgd
386 1.1 cgd if (dtype == 0)
387 1.1 cgd switch(type)
388 1.1 cgd {
389 1.1 cgd case T_DIRECT:
390 1.1 cgd dtype="direct";
391 1.1 cgd break;
392 1.1 cgd case T_SEQUENTIAL:
393 1.1 cgd dtype="sequential";
394 1.1 cgd break;
395 1.1 cgd case T_PRINTER:
396 1.1 cgd dtype="printer";
397 1.1 cgd break;
398 1.1 cgd case T_PROCESSOR:
399 1.1 cgd dtype="processor";
400 1.1 cgd break;
401 1.1 cgd case T_READONLY:
402 1.1 cgd dtype="readonly";
403 1.1 cgd break;
404 1.1 cgd case T_WORM:
405 1.1 cgd dtype="worm";
406 1.1 cgd break;
407 1.1 cgd case T_SCANNER:
408 1.1 cgd dtype="scanner";
409 1.1 cgd break;
410 1.1 cgd case T_OPTICAL:
411 1.1 cgd dtype="optical";
412 1.1 cgd break;
413 1.1 cgd case T_CHANGER:
414 1.1 cgd dtype="changer";
415 1.1 cgd break;
416 1.1 cgd case T_COMM:
417 1.1 cgd dtype="communication";
418 1.1 cgd break;
419 1.1 cgd default:
420 1.1 cgd dtype="unknown";
421 1.1 cgd break;
422 1.1 cgd }
423 1.1 cgd
424 1.1 cgd /***********************************************\
425 1.1 cgd * Then if it's advanced enough, more detailed *
426 1.1 cgd * information *
427 1.1 cgd \***********************************************/
428 1.1 cgd if(inqbuf.ansii_version > 0)
429 1.1 cgd {
430 1.1 cgd if ((len = inqbuf.additional_length
431 1.1 cgd + ( (char *)inqbuf.unused
432 1.1 cgd - (char *)&inqbuf))
433 1.1 cgd > (sizeof(struct scsi_inquiry_data) - 1))
434 1.1 cgd len = sizeof(struct scsi_inquiry_data) - 1;
435 1.1 cgd desc=inqbuf.vendor;
436 1.1 cgd desc[len-(desc - (char *)&inqbuf)] = 0;
437 1.1 cgd strncpy(manu,inqbuf.vendor,8);manu[8]=0;
438 1.1 cgd strncpy(model,inqbuf.product,16);model[16]=0;
439 1.1 cgd strncpy(version,inqbuf.revision,4);version[4]=0;
440 1.1 cgd }
441 1.1 cgd else
442 1.1 cgd /***********************************************\
443 1.1 cgd * If not advanced enough, use default values *
444 1.1 cgd \***********************************************/
445 1.1 cgd {
446 1.1 cgd desc="early protocol device";
447 1.1 cgd strncpy(manu,"unknown",8);
448 1.1 cgd strncpy(model,"unknown",16);
449 1.1 cgd strncpy(version,"????",4);
450 1.1 cgd }
451 1.1 cgd printf(" dev%d,lu%d: type %d:%d(%s%s),%s '%s%s%s' scsi%d\n"
452 1.1 cgd ,target
453 1.1 cgd ,lu
454 1.1 cgd ,qualifier,type
455 1.1 cgd ,dtype,qtype
456 1.1 cgd ,remov?"removable":"fixed"
457 1.1 cgd ,manu
458 1.1 cgd ,model
459 1.1 cgd ,version
460 1.1 cgd ,inqbuf.ansii_version
461 1.1 cgd );
462 1.1 cgd /***********************************************\
463 1.1 cgd * Try make as good a match as possible with *
464 1.1 cgd * available sub drivers *
465 1.1 cgd \***********************************************/
466 1.1 cgd bestmatch = (selectdev(unit,target,lu,&scsi_switch,
467 1.1 cgd qualifier,type,remov,manu,model,version));
468 1.1 cgd if((bestmatch) && (bestmatch->flags & SC_MORE_LUS))
469 1.1 cgd {
470 1.1 cgd *maybe_more = 1;
471 1.1 cgd }
472 1.1 cgd return(bestmatch);
473 1.1 cgd }
474 1.1 cgd
475 1.1 cgd /***********************************************\
476 1.1 cgd * Try make as good a match as possible with *
477 1.1 cgd * available sub drivers *
478 1.1 cgd \***********************************************/
479 1.1 cgd struct scsidevs
480 1.1 cgd *selectdev(unit,target,lu,dvr_switch,qualifier,type,remov,manu,model,rev)
481 1.1 cgd int unit,target,lu;
482 1.1 cgd struct scsi_switch *dvr_switch;
483 1.1 cgd int qualifier,type,remov;
484 1.1 cgd char *manu,*model,*rev;
485 1.1 cgd {
486 1.1 cgd int numents = (sizeof(knowndevs)/sizeof(struct scsidevs)) - 1;
487 1.1 cgd int count = 0;
488 1.1 cgd int bestmatches = 0;
489 1.1 cgd struct scsidevs *bestmatch = (struct scsidevs *)0;
490 1.1 cgd struct scsidevs *thisentry = knowndevs;
491 1.1 cgd
492 1.1 cgd type |= (qualifier << 5);
493 1.1 cgd
494 1.1 cgd thisentry--;
495 1.1 cgd while( count++ < numents)
496 1.1 cgd {
497 1.1 cgd thisentry++;
498 1.1 cgd if(type != thisentry->type)
499 1.1 cgd {
500 1.1 cgd continue;
501 1.1 cgd }
502 1.1 cgd if(bestmatches < 1)
503 1.1 cgd {
504 1.1 cgd bestmatches = 1;
505 1.1 cgd bestmatch = thisentry;
506 1.1 cgd }
507 1.1 cgd if(remov != thisentry->removable)
508 1.1 cgd {
509 1.1 cgd continue;
510 1.1 cgd }
511 1.1 cgd if(bestmatches < 2)
512 1.1 cgd {
513 1.1 cgd bestmatches = 2;
514 1.1 cgd bestmatch = thisentry;
515 1.1 cgd }
516 1.1 cgd if(thisentry->flags & SC_SHOWME)
517 1.1 cgd printf("\n%s-\n%s-",thisentry->manufacturer, manu);
518 1.1 cgd if(strcmp(thisentry->manufacturer, manu))
519 1.1 cgd {
520 1.1 cgd continue;
521 1.1 cgd }
522 1.1 cgd if(bestmatches < 3)
523 1.1 cgd {
524 1.1 cgd bestmatches = 3;
525 1.1 cgd bestmatch = thisentry;
526 1.1 cgd }
527 1.1 cgd if(thisentry->flags & SC_SHOWME)
528 1.1 cgd printf("\n%s-\n%s-",thisentry->model, model);
529 1.1 cgd if(strcmp(thisentry->model, model))
530 1.1 cgd {
531 1.1 cgd continue;
532 1.1 cgd }
533 1.1 cgd if(bestmatches < 4)
534 1.1 cgd {
535 1.1 cgd bestmatches = 4;
536 1.1 cgd bestmatch = thisentry;
537 1.1 cgd }
538 1.1 cgd if(thisentry->flags & SC_SHOWME)
539 1.1 cgd printf("\n%s-\n%s-",thisentry->version, rev);
540 1.1 cgd if(strcmp(thisentry->version, rev))
541 1.1 cgd {
542 1.1 cgd continue;
543 1.1 cgd }
544 1.1 cgd if(bestmatches < 5)
545 1.1 cgd {
546 1.1 cgd bestmatches = 5;
547 1.1 cgd bestmatch = thisentry;
548 1.1 cgd break;
549 1.1 cgd }
550 1.1 cgd }
551 1.1 cgd
552 1.1 cgd if (bestmatch == (struct scsidevs *)0)
553 1.1 cgd printf(" No explicit device driver match for \"%s %s\".\n",
554 1.1 cgd manu, model);
555 1.1 cgd
556 1.1 cgd return(bestmatch);
557 1.1 cgd }
558 1.1 cgd
559 1.1 cgd static int recurse = 0;
560 1.1 cgd /***********************************************\
561 1.1 cgd * Do a scsi operation asking a device if it is *
562 1.1 cgd * ready. Use the scsi_cmd routine in the switch *
563 1.1 cgd * table. *
564 1.1 cgd \***********************************************/
565 1.1 cgd scsi_ready(unit,target,lu,scsi_switch, flags)
566 1.1 cgd struct scsi_switch *scsi_switch;
567 1.1 cgd {
568 1.1 cgd struct scsi_test_unit_ready scsi_cmd;
569 1.1 cgd struct scsi_xfer scsi_xfer;
570 1.1 cgd volatile int rval;
571 1.1 cgd int key;
572 1.1 cgd
573 1.1 cgd bzero(&scsi_cmd, sizeof(scsi_cmd));
574 1.1 cgd bzero(&scsi_xfer, sizeof(scsi_xfer));
575 1.1 cgd scsi_cmd.op_code = TEST_UNIT_READY;
576 1.1 cgd
577 1.1 cgd scsi_xfer.flags=flags | INUSE;
578 1.1 cgd scsi_xfer.adapter=unit;
579 1.1 cgd scsi_xfer.targ=target;
580 1.1 cgd scsi_xfer.lu=lu;
581 1.1 cgd scsi_xfer.cmd=(struct scsi_generic *)&scsi_cmd;
582 1.1 cgd scsi_xfer.retries=8;
583 1.1 cgd scsi_xfer.timeout=10000;
584 1.1 cgd scsi_xfer.cmdlen=sizeof(scsi_cmd);
585 1.1 cgd scsi_xfer.data=0;
586 1.1 cgd scsi_xfer.datalen=0;
587 1.1 cgd scsi_xfer.resid=0;
588 1.1 cgd scsi_xfer.when_done=0;
589 1.1 cgd scsi_xfer.done_arg=0;
590 1.1 cgd retry: scsi_xfer.error=0;
591 1.1 cgd /*******************************************************\
592 1.1 cgd * do not use interrupts *
593 1.1 cgd \*******************************************************/
594 1.1 cgd rval = (*(scsi_switch->scsi_cmd))(&scsi_xfer);
595 1.1 cgd if (rval != COMPLETE)
596 1.1 cgd {
597 1.1 cgd if(scsi_debug)
598 1.1 cgd {
599 1.1 cgd printf("scsi error, rval = 0x%x\n",rval);
600 1.1 cgd printf("code from driver: 0x%x\n",scsi_xfer.error);
601 1.1 cgd }
602 1.1 cgd switch(scsi_xfer.error)
603 1.1 cgd {
604 1.1 cgd case XS_SENSE:
605 1.1 cgd /*******************************************************\
606 1.1 cgd * Any sense value is illegal except UNIT ATTENTION *
607 1.1 cgd * In which case we need to check again to get the *
608 1.1 cgd * correct response. *
609 1.1 cgd *( especially exabytes) *
610 1.1 cgd \*******************************************************/
611 1.1 cgd if(scsi_xfer.sense.error_class == 7 )
612 1.1 cgd {
613 1.1 cgd key = scsi_xfer.sense.ext.extended.sense_key ;
614 1.1 cgd switch(key)
615 1.1 cgd {
616 1.1 cgd case 2: /* not ready BUT PRESENT! */
617 1.1 cgd return(COMPLETE);
618 1.1 cgd case 6:
619 1.1 cgd spinwait(1000);
620 1.1 cgd if(scsi_xfer.retries--)
621 1.1 cgd {
622 1.1 cgd scsi_xfer.flags &= ~ITSDONE;
623 1.1 cgd goto retry;
624 1.1 cgd }
625 1.1 cgd return(COMPLETE);
626 1.1 cgd default:
627 1.1 cgd if(scsi_debug)
628 1.1 cgd printf("%d:%d,key=%x.",
629 1.1 cgd target,lu,key);
630 1.1 cgd }
631 1.1 cgd }
632 1.1 cgd return(HAD_ERROR);
633 1.1 cgd case XS_BUSY:
634 1.1 cgd spinwait(1000);
635 1.1 cgd if(scsi_xfer.retries--)
636 1.1 cgd {
637 1.1 cgd scsi_xfer.flags &= ~ITSDONE;
638 1.1 cgd goto retry;
639 1.1 cgd }
640 1.1 cgd return(COMPLETE); /* it's busy so it's there */
641 1.1 cgd case XS_TIMEOUT:
642 1.1 cgd default:
643 1.1 cgd return(HAD_ERROR);
644 1.1 cgd }
645 1.1 cgd }
646 1.1 cgd return(COMPLETE);
647 1.1 cgd }
648 1.1 cgd /***********************************************\
649 1.1 cgd * Do a scsi operation asking a device what it is*
650 1.1 cgd * Use the scsi_cmd routine in the switch table. *
651 1.1 cgd \***********************************************/
652 1.1 cgd scsi_inquire(unit,target,lu,scsi_switch,inqbuf, flags)
653 1.1 cgd struct scsi_switch *scsi_switch;
654 1.1 cgd u_char *inqbuf;
655 1.1 cgd {
656 1.1 cgd struct scsi_inquiry scsi_cmd;
657 1.1 cgd struct scsi_xfer scsi_xfer;
658 1.1 cgd volatile int rval;
659 1.1 cgd
660 1.1 cgd bzero(&scsi_cmd, sizeof(scsi_cmd));
661 1.1 cgd bzero(&scsi_xfer, sizeof(scsi_xfer));
662 1.1 cgd scsi_cmd.op_code = INQUIRY;
663 1.1 cgd scsi_cmd.length = sizeof(struct scsi_inquiry_data);
664 1.1 cgd
665 1.1 cgd scsi_xfer.flags=flags | SCSI_DATA_IN | INUSE;
666 1.1 cgd scsi_xfer.adapter=unit;
667 1.1 cgd scsi_xfer.targ=target;
668 1.1 cgd scsi_xfer.lu=lu;
669 1.1 cgd scsi_xfer.retries=8;
670 1.1 cgd scsi_xfer.timeout=10000;
671 1.1 cgd scsi_xfer.cmd=(struct scsi_generic *)&scsi_cmd;
672 1.1 cgd scsi_xfer.cmdlen= sizeof(struct scsi_inquiry);
673 1.1 cgd scsi_xfer.data=inqbuf;
674 1.1 cgd scsi_xfer.datalen=sizeof(struct scsi_inquiry_data);
675 1.1 cgd scsi_xfer.resid=sizeof(struct scsi_inquiry_data);
676 1.1 cgd scsi_xfer.when_done=0;
677 1.1 cgd scsi_xfer.done_arg=0;
678 1.1 cgd retry: scsi_xfer.error=0;
679 1.1 cgd /*******************************************************\
680 1.1 cgd * do not use interrupts *
681 1.1 cgd \*******************************************************/
682 1.1 cgd if ((*(scsi_switch->scsi_cmd))(&scsi_xfer) != COMPLETE)
683 1.1 cgd {
684 1.1 cgd if(scsi_debug) printf("inquiry had error(0x%x) ",scsi_xfer.error);
685 1.1 cgd switch(scsi_xfer.error)
686 1.1 cgd {
687 1.1 cgd case XS_NOERROR:
688 1.1 cgd break;
689 1.1 cgd case XS_SENSE:
690 1.1 cgd /*******************************************************\
691 1.1 cgd * Any sense value is illegal except UNIT ATTENTION *
692 1.1 cgd * In which case we need to check again to get the *
693 1.1 cgd * correct response. *
694 1.1 cgd *( especially exabytes) *
695 1.1 cgd \*******************************************************/
696 1.1 cgd if((scsi_xfer.sense.error_class == 7 )
697 1.1 cgd && (scsi_xfer.sense.ext.extended.sense_key == 6))
698 1.1 cgd { /* it's changed so it's there */
699 1.1 cgd spinwait(1000);
700 1.1 cgd {
701 1.1 cgd if(scsi_xfer.retries--)
702 1.1 cgd {
703 1.1 cgd scsi_xfer.flags &= ~ITSDONE;
704 1.1 cgd goto retry;
705 1.1 cgd }
706 1.1 cgd }
707 1.1 cgd return( COMPLETE);
708 1.1 cgd }
709 1.1 cgd return(HAD_ERROR);
710 1.1 cgd case XS_BUSY:
711 1.1 cgd spinwait(1000);
712 1.1 cgd if(scsi_xfer.retries--)
713 1.1 cgd {
714 1.1 cgd scsi_xfer.flags &= ~ITSDONE;
715 1.1 cgd goto retry;
716 1.1 cgd }
717 1.1 cgd case XS_TIMEOUT:
718 1.1 cgd default:
719 1.1 cgd return(HAD_ERROR);
720 1.1 cgd }
721 1.1 cgd }
722 1.1 cgd return(COMPLETE);
723 1.1 cgd }
724 1.1 cgd
725 1.1 cgd
726 1.1 cgd
727 1.1 cgd
728 1.1 cgd /***********************************************\
729 1.1 cgd * Utility routines often used in SCSI stuff *
730 1.1 cgd \***********************************************/
731 1.1 cgd
732 1.1 cgd /***********************************************\
733 1.1 cgd * convert a physical address to 3 bytes, *
734 1.1 cgd * MSB at the lowest address, *
735 1.1 cgd * LSB at the highest. *
736 1.1 cgd \***********************************************/
737 1.1 cgd
738 1.1 cgd lto3b(val, bytes)
739 1.1 cgd u_char *bytes;
740 1.1 cgd {
741 1.1 cgd *bytes++ = (val&0xff0000)>>16;
742 1.1 cgd *bytes++ = (val&0xff00)>>8;
743 1.1 cgd *bytes = val&0xff;
744 1.1 cgd }
745 1.1 cgd
746 1.1 cgd /***********************************************\
747 1.1 cgd * The reverse of lto3b *
748 1.1 cgd \***********************************************/
749 1.1 cgd _3btol(bytes)
750 1.1 cgd u_char *bytes;
751 1.1 cgd {
752 1.1 cgd int rc;
753 1.1 cgd rc = (*bytes++ << 16);
754 1.1 cgd rc += (*bytes++ << 8);
755 1.1 cgd rc += *bytes;
756 1.1 cgd return(rc);
757 1.1 cgd }
758 1.1 cgd
759