2 * Copyright (c) 1998 - 2006 Søren Schmidt <sos@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification, immediately at the beginning of the file.
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.
26 * $FreeBSD: src/sys/dev/ata/atapi-fd.c,v 1.109 2006/03/30 05:29:57 marcel Exp $
29 #include <sys/param.h>
34 #include <sys/device.h>
35 #include <sys/devicestat.h>
37 #include <sys/endian.h>
38 #include <sys/kernel.h>
39 #include <sys/libkern.h>
40 #include <sys/malloc.h>
41 #include <sys/module.h>
43 #include <sys/systm.h>
50 /* device structure */
51 static d_open_t afd_open
;
52 static d_close_t afd_close
;
53 static d_ioctl_t afd_ioctl
;
54 static d_strategy_t afd_strategy
;
55 static struct dev_ops afd_ops
= {
56 { "afd", 118, D_DISK
| D_TRACKCLOSE
},
62 .d_strategy
= afd_strategy
,
66 static int afd_sense(device_t
);
67 static void afd_describe(device_t
);
68 static void afd_done(struct ata_request
*);
69 static int afd_prevent_allow(device_t
, int);
70 static int afd_test_ready(device_t
);
73 static MALLOC_DEFINE(M_AFD
, "afd_driver", "ATAPI floppy driver buffers");
76 afd_probe(device_t dev
)
78 struct ata_device
*atadev
= device_get_softc(dev
);
79 if ((atadev
->param
.config
& ATA_PROTO_ATAPI
) &&
80 (atadev
->param
.config
& ATA_ATAPI_TYPE_MASK
) == ATA_ATAPI_TYPE_DIRECT
)
87 afd_attach(device_t dev
)
89 struct ata_channel
*ch
= device_get_softc(device_get_parent(dev
));
90 struct ata_device
*atadev
= device_get_softc(dev
);
91 struct afd_softc
*fdp
;
94 fdp
= kmalloc(sizeof(struct afd_softc
), M_AFD
, M_WAITOK
| M_ZERO
);
95 device_set_ivars(dev
, fdp
);
96 ATA_SETMODE(device_get_parent(dev
), dev
);
99 device_set_ivars(dev
, NULL
);
103 atadev
->flags
|= ATA_D_MEDIA_CHANGED
;
105 /* create the disk device */
106 devstat_add_entry(&fdp
->stats
, "afd", device_get_unit(dev
), DEV_BSIZE
,
107 DEVSTAT_NO_ORDERED_TAGS
, DEVSTAT_TYPE_DIRECT
|
108 DEVSTAT_TYPE_IF_IDE
, DEVSTAT_PRIORITY_WFD
);
109 cdev
= disk_create(device_get_unit(dev
), &fdp
->disk
, &afd_ops
);
110 disk_setdisktype(&fdp
->disk
, "floppy");
113 cdev
->si_iosize_max
= ch
->dma
->max_iosize
;
115 cdev
->si_iosize_max
= min(MAXPHYS
,64*1024);
118 /* announce we are here */
124 afd_detach(device_t dev
)
126 struct afd_softc
*fdp
= device_get_ivars(dev
);
128 /* check that we have a valid device to detach */
129 if (!device_get_ivars(dev
))
132 /* detroy disk from the system so we dont get any further requests */
133 disk_invalidate(&fdp
->disk
);
134 disk_destroy(&fdp
->disk
);
136 /* fail requests on the queue and any thats "in flight" for this device */
137 ata_fail_requests(dev
);
139 /* dont leave anything behind */
140 /* disk_destroy() already took care of the dev_ops */
141 devstat_remove_entry(&fdp
->stats
);
142 device_set_ivars(dev
, NULL
);
148 afd_shutdown(device_t dev
)
150 struct ata_device
*atadev
= device_get_softc(dev
);
152 if (atadev
->param
.support
.command2
& ATA_SUPPORT_FLUSHCACHE
)
153 ata_controlcmd(dev
, ATA_FLUSHCACHE
, 0, 0, 0);
157 afd_reinit(device_t dev
)
159 struct ata_channel
*ch
= device_get_softc(device_get_parent(dev
));
160 struct ata_device
*atadev
= device_get_softc(dev
);
161 struct afd_softc
*fdp
= device_get_ivars(dev
);
163 if (((atadev
->unit
== ATA_MASTER
) && !(ch
->devices
& ATA_ATAPI_MASTER
)) ||
164 ((atadev
->unit
== ATA_SLAVE
) && !(ch
->devices
& ATA_ATAPI_SLAVE
))) {
165 device_set_ivars(dev
, NULL
);
169 ATA_SETMODE(device_get_parent(dev
), dev
);
174 afd_open(struct dev_open_args
*ap
)
176 device_t dev
= ap
->a_head
.a_dev
->si_drv1
;
177 struct ata_device
*atadev
= device_get_softc(dev
);
178 struct afd_softc
*fdp
= device_get_ivars(dev
);
179 struct disk_info info
;
183 if (!device_is_attached(dev
))
187 afd_prevent_allow(dev
, 1);
190 device_printf(dev
, "sense media type failed\n");
191 atadev
->flags
&= ~ATA_D_MEDIA_CHANGED
;
196 bzero(&info
, sizeof(info
));
197 info
.d_media_blksize
= fdp
->sectorsize
; /* mandatory */
198 info
.d_media_size
= fdp
->mediasize
; /* (this is in bytes) */
200 info
.d_secpertrack
= fdp
->sectors
; /* optional */
201 info
.d_nheads
= fdp
->heads
;
203 ((fdp
->mediasize
/fdp
->sectorsize
)/fdp
->sectors
)/fdp
->heads
;
204 info
.d_secpercyl
= fdp
->sectors
* fdp
->heads
;
206 disk_setdiskinfo(&fdp
->disk
, &info
);
211 afd_close(struct dev_close_args
*ap
)
213 device_t dev
= ap
->a_head
.a_dev
->si_drv1
;
214 struct afd_softc
*fdp
= device_get_ivars(dev
);
216 if (count_dev(fdp
->cdev
) == 1)
217 afd_prevent_allow(dev
, 0);
222 afd_ioctl(struct dev_ioctl_args
*ap
)
224 return ata_device_ioctl(ap
->a_head
.a_dev
->si_drv1
, ap
->a_cmd
, ap
->a_data
);
228 afd_strategy(struct dev_strategy_args
*ap
)
230 device_t dev
= ap
->a_head
.a_dev
->si_drv1
;
231 struct bio
*bp
= ap
->a_bio
;
232 struct buf
*bbp
= bp
->bio_buf
;
233 struct ata_device
*atadev
= device_get_softc(dev
);
234 struct afd_softc
*fdp
= device_get_ivars(dev
);
235 struct ata_request
*request
;
240 /* if it's a null transfer, return immediatly. */
241 if (bbp
->b_bcount
== 0) {
247 /* should reject all queued entries if media have changed. */
248 if (atadev
->flags
& ATA_D_MEDIA_CHANGED
) {
249 bbp
->b_flags
|= B_ERROR
;
255 lba
= bp
->bio_offset
/ fdp
->sectorsize
;
256 count
= bbp
->b_bcount
/ fdp
->sectorsize
;
257 bbp
->b_resid
= bbp
->b_bcount
;
259 bzero(ccb
, sizeof(ccb
));
263 ccb
[0] = ATAPI_READ_BIG
;
266 ccb
[0] = ATAPI_WRITE_BIG
;
269 device_printf(dev
, "unknown BUF operation\n");
270 bbp
->b_flags
|= B_ERROR
;
283 if (!(request
= ata_alloc_request())) {
284 bbp
->b_flags
|= B_ERROR
;
285 bbp
->b_error
= ENOMEM
;
291 bcopy(ccb
, request
->u
.atapi
.ccb
,
292 (atadev
->param
.config
& ATA_PROTO_MASK
) ==
293 ATA_PROTO_ATAPI_12
? 16 : 12);
294 request
->data
= bbp
->b_data
;
295 request
->bytecount
= count
* fdp
->sectorsize
;
296 request
->transfersize
= min(request
->bytecount
, 65534);
297 request
->timeout
= (ccb
[0] == ATAPI_WRITE_BIG
) ? 60 : 30;
298 request
->retries
= 2;
299 request
->callback
= afd_done
;
301 switch (bbp
->b_cmd
) {
303 request
->flags
= (ATA_R_ATAPI
| ATA_R_READ
);
306 request
->flags
= (ATA_R_ATAPI
| ATA_R_WRITE
);
311 if (atadev
->mode
>= ATA_DMA
)
312 request
->flags
|= ATA_R_DMA
;
313 request
->flags
|= ATA_R_ORDERED
;
314 devstat_start_transaction(&fdp
->stats
);
315 ata_queue_request(request
);
320 afd_done(struct ata_request
*request
)
322 struct afd_softc
*fdp
= device_get_ivars(request
->dev
);
323 struct bio
*bp
= request
->bio
;
324 struct buf
*bbp
= bp
->bio_buf
;
326 /* finish up transfer */
327 if ((bbp
->b_error
= request
->result
))
328 bbp
->b_flags
|= B_ERROR
;
329 bbp
->b_resid
= bbp
->b_bcount
- request
->donecount
;
330 devstat_end_transaction_buf(&fdp
->stats
, bbp
);
332 ata_free_request(request
);
336 afd_sense(device_t dev
)
338 struct ata_device
*atadev
= device_get_softc(dev
);
339 struct afd_softc
*fdp
= device_get_ivars(dev
);
340 struct afd_capacity capacity
;
341 struct afd_capacity_big capacity_big
;
342 struct afd_capabilities capabilities
;
343 int8_t ccb1
[16] = { ATAPI_READ_CAPACITY
, 0, 0, 0, 0, 0, 0, 0,
344 0, 0, 0, 0, 0, 0, 0, 0 };
345 int8_t ccb2
[16] = { ATAPI_READ_CAPACITY_16
, 0x10, 0, 0, 0, 0, 0, 0, 0, 0,
346 0, 0, 0, sizeof(struct afd_capacity_big
) & 0xff, 0, 0 };
347 int8_t ccb3
[16] = { ATAPI_MODE_SENSE_BIG
, 0, ATAPI_REWRITEABLE_CAP_PAGE
,
348 0, 0, 0, 0, sizeof(struct afd_capabilities
) >> 8,
349 sizeof(struct afd_capabilities
) & 0xff,
350 0, 0, 0, 0, 0, 0, 0 };
356 /* wait for device to get ready */
357 while ((error
= afd_test_ready(dev
)) && timeout
--) {
363 /* The IOMEGA Clik! doesn't support reading the cap page, fake it */
364 if (!strncmp(atadev
->param
.model
, "IOMEGA Clik!", 12)) {
367 fdp
->mediasize
= 39441 * 1024;
368 fdp
->sectorsize
= 512;
373 /* get drive capacity */
374 if (!ata_atapicmd(dev
, ccb1
, (caddr_t
)&capacity
,
375 sizeof(struct afd_capacity
), ATA_R_READ
, 30)) {
378 fdp
->sectorsize
= be32toh(capacity
.blocksize
);
379 fdp
->mediasize
= (u_int64_t
)be32toh(capacity
.capacity
)*fdp
->sectorsize
;
384 /* get drive capacity big */
385 if (!ata_atapicmd(dev
, ccb2
, (caddr_t
)&capacity_big
,
386 sizeof(struct afd_capacity_big
),
387 ATA_R_READ
| ATA_R_QUIET
, 30)) {
390 fdp
->sectorsize
= be32toh(capacity_big
.blocksize
);
391 fdp
->mediasize
= be64toh(capacity_big
.capacity
)*fdp
->sectorsize
;
396 /* get drive capabilities, some bugridden drives needs this repeated */
397 for (count
= 0 ; count
< 5 ; count
++) {
398 if (!ata_atapicmd(dev
, ccb3
, (caddr_t
)&capabilities
,
399 sizeof(struct afd_capabilities
), ATA_R_READ
, 30) &&
400 capabilities
.page_code
== ATAPI_REWRITEABLE_CAP_PAGE
) {
401 fdp
->heads
= capabilities
.heads
;
402 fdp
->sectors
= capabilities
.sectors
;
403 fdp
->sectorsize
= be16toh(capabilities
.sector_size
);
404 fdp
->mediasize
= be16toh(capabilities
.cylinders
) *
405 fdp
->heads
* fdp
->sectors
* fdp
->sectorsize
;
406 if (!capabilities
.medium_type
)
415 afd_prevent_allow(device_t dev
, int lock
)
417 struct ata_device
*atadev
= device_get_softc(dev
);
418 int8_t ccb
[16] = { ATAPI_PREVENT_ALLOW
, 0, 0, 0, lock
,
419 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
421 if (!strncmp(atadev
->param
.model
, "IOMEGA Clik!", 12))
423 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
427 afd_test_ready(device_t dev
)
429 int8_t ccb
[16] = { ATAPI_TEST_UNIT_READY
, 0, 0, 0, 0,
430 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
432 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
436 afd_describe(device_t dev
)
438 struct ata_channel
*ch
= device_get_softc(device_get_parent(dev
));
439 struct ata_device
*atadev
= device_get_softc(dev
);
440 struct afd_softc
*fdp
= device_get_ivars(dev
);
443 if (fdp
->mediasize
> 1048576 * 5)
444 ksprintf(sizestring
, "%lluMB", (unsigned long long)
445 (fdp
->mediasize
/ 1048576));
446 else if (fdp
->mediasize
)
447 ksprintf(sizestring
, "%lluKB", (unsigned long long)
448 (fdp
->mediasize
/ 1024));
450 strcpy(sizestring
, "(no media)");
452 device_printf(dev
, "%s <%.40s %.8s> at ata%d-%s %s\n",
453 sizestring
, atadev
->param
.model
, atadev
->param
.revision
,
454 device_get_unit(ch
->dev
),
455 (atadev
->unit
== ATA_MASTER
) ? "master" : "slave",
456 ata_mode2str(atadev
->mode
));
458 device_printf(dev
, "%llu sectors [%lluC/%dH/%dS]\n",
459 (unsigned long long)(fdp
->mediasize
/ fdp
->sectorsize
),
461 (fdp
->mediasize
/(fdp
->sectorsize
*fdp
->sectors
*fdp
->heads
)),
462 fdp
->heads
, fdp
->sectors
);
466 static device_method_t afd_methods
[] = {
467 /* device interface */
468 DEVMETHOD(device_probe
, afd_probe
),
469 DEVMETHOD(device_attach
, afd_attach
),
470 DEVMETHOD(device_detach
, afd_detach
),
471 DEVMETHOD(device_shutdown
, afd_shutdown
),
474 DEVMETHOD(ata_reinit
, afd_reinit
),
479 static driver_t afd_driver
= {
485 static devclass_t afd_devclass
;
487 DRIVER_MODULE(afd
, ata
, afd_driver
, afd_devclass
, NULL
, NULL
);
488 MODULE_VERSION(afd
, 1);
489 MODULE_DEPEND(afd
, ata
, 1, 1, 1);