Annotation of src/sys/dev/scsipi/atapiconf.c, Revision 1.2.2.3
1.2.2.3 ! thorpej 1: /* $NetBSD: atapiconf.c,v 1.2.2.2 1997/09/01 20:58:57 thorpej Exp $ */
1.2.2.2 thorpej 2:
3: /*
4: * Copyright (c) 1996 Manuel Bouyer. All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer.
11: * 2. Redistributions in binary form must reproduce the above copyright
12: * notice, this list of conditions and the following disclaimer in the
13: * documentation and/or other materials provided with the distribution.
14: * 3. All advertising materials mentioning features or use of this software
15: * must display the following acknowledgement:
16: * This product includes software developed by Manuel Bouyer.
17: * 4. The name of the author may not be used to endorse or promote products
18: * derived from this software without specific prior written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30: */
31:
32: #include <sys/types.h>
33: #include <sys/param.h>
34: #include <sys/systm.h>
35: #include <sys/malloc.h>
36: #include <sys/device.h>
37: #include <sys/buf.h>
38: #include <sys/proc.h>
39:
40: #include <dev/scsipi/scsipi_all.h>
41: #include <dev/scsipi/scsi_all.h>
42: #include <dev/scsipi/scsipiconf.h>
43: #include <dev/scsipi/atapiconf.h>
44: #include "locators.h"
45:
46: #define SILENT_PRINTF(flags,string) if (!(flags & A_SILENT)) printf string
47:
48: struct atapibus_softc {
49: struct device sc_dev;
50: struct scsipi_link *adapter_link; /* proto supplied by adapter */
51: struct scsipi_link **sc_link; /* dynamically allocated */
52: };
53:
54: #ifdef __BROKEN_INDIRECT_CONFIG
55: int atapibusmatch __P((struct device *, void *, void *));
56: int atapibussubmatch __P((struct device *, void *, void *));
57: #else
58: int atapibusmatch __P((struct device *, struct cfdata *, void *));
59: int atapibussubmatch __P((struct device *, struct cfdata *, void *));
60: #endif
61: void atapibusattach __P((struct device *, struct device *, void *));
62: int atapiprint __P((void *, const char *));
63:
64: int atapi_probe_bus __P((int, int));
65: void atapi_probedev __P((struct atapibus_softc *, int ));
66:
67: struct cfattach atapibus_ca = {
68: sizeof(struct atapibus_softc), atapibusmatch, atapibusattach
69: };
70:
71: struct cfdriver atapibus_cd = {
72: NULL, "atapibus", DV_DULL
73: };
74:
75: int atapibusprint __P((void *, const char *));
76:
77: struct scsi_quirk_inquiry_pattern atapi_quirk_patterns[] = {
78: {{T_CDROM, T_REMOV,
79: "GCD-R580B", "", "1.00"}, ADEV_LITTLETOC},
80: {{T_CDROM, T_REMOV,
81: "SANYO CRD-256P", "", "1.02"}, ADEV_NOCAPACITY},
82: {{T_CDROM, T_REMOV,
1.2.2.3 ! thorpej 83: "SANYO CRD-254P", "", "1.02"}, ADEV_NOCAPACITY},
! 84: {{T_CDROM, T_REMOV,
1.2.2.2 thorpej 85: "UJDCD8730", "", "1.14"}, ADEV_NODOORLOCK},
86: {{T_CDROM, T_REMOV,
87: "ALPS ELECTRIC CO.,LTD. DC544C", "", "SW03D"}, ADEV_NOTUR},
88: {{T_CDROM, T_REMOV,
89: "NEC CD-ROM DRIVE:273", "", "4.21"}, ADEV_NOTUR},
1.2.2.3 ! thorpej 90: {{T_CDROM, T_REMOV,
! 91: "MATSHITA CR-574", "", "1.06"}, ADEV_NOCAPACITY},
1.2.2.2 thorpej 92: };
93:
94: int
95: #ifdef __BROKEN_INDIRECT_CONFIG
96: atapibusmatch(parent, match, aux)
97: struct device *parent;
98: void *match, *aux;
99: {
100: #else
101: atapibusmatch(parent, cf, aux)
102: struct device *parent;
103: struct cfdata *cf;
104: void *aux;
105: {
106: #endif
107: struct scsipi_link *sc_link = aux;
108:
109: if (sc_link == NULL)
110: return 0;
111: if (sc_link->type != BUS_ATAPI)
112: return 0;
113: return 1;
114: }
115:
116: int
117: #ifdef __BROKEN_INDIRECT_CONFIG
118: atapibussubmatch(parent, match, aux)
119: struct device *parent;
120: void *match, *aux;
121: {
122: struct cfdata *cf = match;
123: #else
124: atapibussubmatch(parent, cf, aux)
125: struct device *parent;
126: struct cfdata *cf;
127: void *aux;
128: {
129: #endif
130: struct scsipibus_attach_args *sa = aux;
131: struct scsipi_link *sc_link = sa->sa_sc_link;
132:
133: if (cf->cf_loc[ATAPIBUSCF_DRIVE] != ATAPIBUSCF_DRIVE_DEFAULT &&
134: cf->cf_loc[ATAPIBUSCF_DRIVE] != sc_link->scsipi_atapi.drive)
135: return 0;
136: return ((*cf->cf_attach->ca_match)(parent, cf, aux));
137: }
138:
139:
140: #if 0
141: void
142: atapi_fixquirk(sc_link)
143: struct scsipi_link *ad_link;
144: {
145: struct atapi_identify *id = &ad_link->id;
146: struct atapi_quirk_inquiry_pattern *quirk;
147:
148:
149: /*
150: * Clean up the model name, serial and
151: * revision numbers.
152: */
153: btrim(id->model, sizeof(id->model));
154: btrim(id->serial_number, sizeof(id->serial_number));
155: btrim(id->firmware_revision, sizeof(id->firmware_revision));
156:
157: }
158: #endif
159:
160:
161: void
162: atapibusattach(parent, self, aux)
163: struct device *parent, *self;
164: void *aux;
165: {
166: struct atapibus_softc *ab = (struct atapibus_softc *)self;
167: struct scsipi_link *sc_link_proto = aux;
168: int nbytes;
169:
170: printf("\n");
171:
172: sc_link_proto->scsipi_atapi.atapibus = ab->sc_dev.dv_unit;
173: sc_link_proto->scsipi_cmd = atapi_scsipi_cmd;
174: sc_link_proto->scsipi_interpret_sense = atapi_interpret_sense;
175: sc_link_proto->sc_print_addr = atapi_print_addr;
176:
177: ab->adapter_link = sc_link_proto;
178:
179: nbytes = 2 * sizeof(struct scsipi_link **);
180: ab->sc_link = (struct scsipi_link **)malloc(nbytes, M_DEVBUF,
181: M_NOWAIT);
182: if (ab->sc_link == NULL)
183: panic("scsibusattach: can't allocate target links");
184: bzero(ab->sc_link, nbytes);
185: atapi_probe_bus(ab->sc_dev.dv_unit, -1);
186: }
187:
188: int
189: atapi_probe_bus(bus, target)
190: int bus, target;
191: {
192: int maxtarget, mintarget;
193: struct atapibus_softc *atapi;
194: if (bus < 0 || bus >= atapibus_cd.cd_ndevs)
195: return ENXIO;
196: atapi = atapibus_cd.cd_devs[bus];
197: if (!atapi)
198: return ENXIO;
199:
200: if (target == -1) {
201: maxtarget = 1;
202: mintarget = 0;
203: } else {
204: if (target < 0 || target > 1)
205: return ENXIO;
206: maxtarget = mintarget = target;
207: }
208: for (target = mintarget; target <= maxtarget; target++) {
209: atapi_probedev(atapi, target);
210: }
211: return 0;
212: }
213:
214: void
215: atapi_probedev(atapi, target)
216: struct atapibus_softc *atapi;
217: int target;
218: {
219: struct scsipi_link *sc_link;
220: struct scsipibus_attach_args sa;
221: struct atapi_identify ids;
222: struct atapi_identify *id = &ids;
223: struct cfdata *cf;
224: struct scsi_quirk_inquiry_pattern *finger;
225: int priority;
226: char serial_number[20], model[40], firmware_revision[8];
227:
228: /* skip if already attached */
229: if (atapi->sc_link[target])
230: return;
231:
232: if (wdc_atapi_get_params(atapi->adapter_link, target, id)) {
233: #ifdef ATAPI_DEBUG_PROBE
234: printf("%s drive %d: cmdsz 0x%x drqtype 0x%x\n",
235: atapi->sc_dev.dv_xname, target,
236: id->config.cmd_drq_rem & ATAPI_PACKET_SIZE_MASK,
237: id->config.cmd_drq_rem & ATAPI_DRQ_MASK);
238: #endif
239: /*
240: * Shuffle string byte order.
241: * Mitsumi and NEC drives don't need this.
242: */
243: if (((id->model[0] == 'N' && id->model[1] == 'E') ||
244: (id->model[0] == 'F' && id->model[1] == 'X')) == 0)
245: bswap(id->model, sizeof(id->model));
246: bswap(id->serial_number, sizeof(id->serial_number));
247: bswap(id->firmware_revision, sizeof(id->firmware_revision));
248:
249: /*
250: * Allocate a device link and try and attach
251: * a driver to this device. If we fail, free
252: * the link.
253: */
254: sc_link = malloc(sizeof(*sc_link), M_DEVBUF, M_NOWAIT);
255: if (sc_link == NULL) {
256: printf("%s: can't allocate link for drive %d\n",
257: atapi->sc_dev.dv_xname, target);
258: return;
259: }
260: /* Fill in link. */
261: *sc_link = *atapi->adapter_link;
262: sc_link->scsipi_atapi.drive = target;
263: sc_link->device = NULL;
264: #if defined(SCSIDEBUG) && DEBUGTYPE == BUS_ATAPI
265: if (DEBUGTARGET == -1 || target == DEBUGTARGET)
266: sc_link->flags |= DEBUGLEVEL;
267: #endif /* SCSIDEBUG */
268: if (id->config.cmd_drq_rem & ATAPI_PACKET_SIZE_16)
269: sc_link->scsipi_atapi.cap |= ACAP_LEN;
270: sc_link->scsipi_atapi.cap |=
271: (id->config.cmd_drq_rem & ATAPI_DRQ_MASK) << 3;
272: #if 0
273: bcopy(id, &ad_link->id, sizeof(*id));
274: /* Fix strings and look through the quirk table. */
275: atapi_fixquirk(ad_link, id);
276: #endif
277: sa.sa_sc_link = sc_link;
278: sa.sa_inqbuf.type = id->config.device_type & SID_TYPE;
279: sa.sa_inqbuf.removable =
280: id->config.cmd_drq_rem & ATAPI_REMOVABLE ?
281: T_REMOV : T_FIXED;
282: if (sa.sa_inqbuf.removable)
283: sc_link->flags |= SDEV_REMOVABLE;
284: scsipi_strvis(model, id->model, 40);
285: scsipi_strvis(serial_number, id->serial_number, 20);
286: scsipi_strvis(firmware_revision, id->firmware_revision, 8);
287: sa.sa_inqbuf.vendor = model;
288: sa.sa_inqbuf.product = serial_number;
289: sa.sa_inqbuf.revision = firmware_revision;
290:
291: finger = (struct scsi_quirk_inquiry_pattern *)scsipi_inqmatch(
292: &sa.sa_inqbuf, (caddr_t)atapi_quirk_patterns,
293: sizeof(atapi_quirk_patterns) /
294: sizeof(atapi_quirk_patterns[0]),
295: sizeof(atapi_quirk_patterns[0]), &priority);
296: if (priority != 0)
297: sc_link->quirks |= finger->quirks;
298:
299: if ((cf = config_search(atapibussubmatch, &atapi->sc_dev,
300: &sa)) != 0) {
301: atapi->sc_link[target] = sc_link;
302: config_attach(&atapi->sc_dev, cf, &sa, atapibusprint);
303: return;
304: } else {
305: atapibusprint(&sa, atapi->sc_dev.dv_xname);
306: printf(" not configured\n");
307: free(sc_link, M_DEVBUF);
308: return;
309: }
310:
311: #if 0 /* WAS: */
312: /* Try to find a match. */
313: if (config_found(self, ad_link, atapiprint) == NULL)
314: free(ad_link, M_DEVBUF);
315: #endif
316: }
317: }
318:
319: int
320: atapibusprint(aux, pnp)
321: void *aux;
322: const char *pnp;
323: {
324: struct scsipibus_attach_args *sa = aux;
325: struct scsipi_inquiry_pattern *inqbuf;
326: char *dtype;
327:
328: if (pnp != NULL)
329: printf("%s", pnp);
330:
331: inqbuf = &sa->sa_inqbuf;
332:
333: dtype = scsipi_dtype(inqbuf->type & SID_TYPE);
334: printf(" drive %d: <%s, %s, %s> type %d %s %s",
335: sa->sa_sc_link->scsipi_atapi.drive,inqbuf->vendor,
336: inqbuf->product, inqbuf->revision, inqbuf->type, dtype,
337: inqbuf->removable ? "removable" : "fixed");
338: return (UNCONF);
339: }
CVSweb <webmaster@jp.NetBSD.org>