1 /* $NetBSD: st_atapi.c,v 1.25 2009/10/21 21:12:06 rmind Exp $ */
4 * Copyright (c) 2001 Manuel Bouyer.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: st_atapi.c,v 1.25 2009/10/21 21:12:06 rmind Exp $");
34 #include <sys/param.h>
35 #include <sys/device.h>
39 #include <sys/kernel.h>
40 #include <sys/systm.h>
42 #include <dev/scsipi/stvar.h>
43 #include <dev/scsipi/atapi_tape.h>
45 static int st_atapibus_match(device_t
, cfdata_t
, void *);
46 static void st_atapibus_attach(device_t
, device_t
, void *);
47 static int st_atapibus_ops(struct st_softc
*, int, int);
48 static int st_atapibus_mode_sense(struct st_softc
*, int);
50 CFATTACH_DECL(st_atapibus
, sizeof(struct st_softc
),
51 st_atapibus_match
, st_atapibus_attach
, stdetach
, NULL
);
53 static const struct scsipi_inquiry_pattern st_atapibus_patterns
[] = {
54 {T_SEQUENTIAL
, T_REMOV
,
59 st_atapibus_match(device_t parent
, cfdata_t match
,
62 struct scsipibus_attach_args
*sa
= aux
;
65 if (scsipi_periph_bustype(sa
->sa_periph
) != SCSIPI_BUSTYPE_ATAPI
)
68 (void)scsipi_inqmatch(&sa
->sa_inqbuf
,
70 sizeof(st_atapibus_patterns
)/sizeof(st_atapibus_patterns
[0]),
71 sizeof(st_atapibus_patterns
[0]), &priority
);
76 st_atapibus_attach(device_t parent
, device_t self
, void *aux
)
78 struct st_softc
*st
= device_private(self
);
79 struct scsipibus_attach_args
*sa
= aux
;
80 struct scsipi_periph
*periph
= sa
->sa_periph
;
82 if (strcmp(sa
->sa_inqbuf
.vendor
, "OnStream DI-30") == 0) {
83 struct ast_identifypage identify
;
86 error
= scsipi_mode_sense(periph
, SMS_DBD
,
87 ATAPI_TAPE_IDENTIFY_PAGE
, &identify
.header
,
88 sizeof(identify
), XS_CTL_DISCOVERY
,
89 ST_RETRIES
, ST_CTL_TIME
);
91 printf("onstream get identify: error %d\n", error
);
94 strncpy(identify
.ident
, "NBSD", 4);
95 error
= scsipi_mode_select(periph
, SMS_PF
,
96 &identify
.header
, sizeof(identify
),
97 XS_CTL_DISCOVERY
, ST_RETRIES
, ST_CTL_TIME
);
99 printf("onstream set identify: error %d\n", error
);
104 st
->ops
= st_atapibus_ops
;
105 stattach(parent
, st
, aux
);
109 st_atapibus_ops(struct st_softc
*st
, int op
, int flags
)
113 /* done in mode_sense */
115 case ST_OPS_MODESENSE
:
116 return st_atapibus_mode_sense(st
, flags
);
117 case ST_OPS_MODESELECT
:
118 return st_mode_select(st
, flags
);
119 case ST_OPS_CMPRSS_ON
:
120 case ST_OPS_CMPRSS_OFF
:
123 panic("st_scsibus_ops: invalid op");
129 st_atapibus_mode_sense(struct st_softc
*st
, int flags
)
132 struct atapi_cappage cappage
;
133 struct scsipi_periph
*periph
= st
->sc_periph
;
135 /* get drive capabilities, some drives needs this repeated */
136 for (count
= 0 ; count
< 5 ; count
++) {
137 error
= scsipi_mode_sense(periph
, SMS_DBD
,
138 ATAPI_TAPE_CAP_PAGE
, &cappage
.header
, sizeof(cappage
),
139 flags
, ST_RETRIES
, ST_CTL_TIME
);
141 st
->numblks
= 0; /* unused anyway */
142 if (cappage
.cap4
& ATAPI_TAPE_CAP_PAGE_BLK32K
)
143 st
->media_blksize
= 32768;
144 else if (cappage
.cap4
& ATAPI_TAPE_CAP_PAGE_BLK1K
)
145 st
->media_blksize
= 1024;
146 else if (cappage
.cap4
& ATAPI_TAPE_CAP_PAGE_BLK512
)
147 st
->media_blksize
= 512;
152 st
->blkmin
= st
->blkmax
= st
->media_blksize
;
153 st
->media_density
= 0;
154 if (cappage
.header
.dev_spec
& SMH_DSP_WRITE_PROT
)
155 st
->flags
|= ST_READONLY
;
157 st
->flags
&= ~ST_READONLY
;
158 SC_DEBUG(periph
, SCSIPI_DB3
,
159 ("density code %d, %d-byte blocks, write-%s, ",
160 st
->media_density
, st
->media_blksize
,
161 st
->flags
& ST_READONLY
? "protected" : "enabled"));
162 SC_DEBUG(periph
, SCSIPI_DB3
,
164 cappage
.header
.dev_spec
& SMH_DSP_BUFF_MODE
?
166 periph
->periph_flags
|= PERIPH_MEDIA_LOADED
;