2 * Copyright (c) 1998 - 2005 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.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
34 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/module.h>
38 #include <sys/malloc.h>
43 #include <sys/devicestat.h>
45 #include <sys/taskqueue.h>
47 #include <machine/bus.h>
48 #include <dev/ata/ata-all.h>
49 #include <dev/ata/atapi-tape.h>
52 /* device structure */
53 static d_open_t ast_open;
54 static d_close_t ast_close;
55 static d_ioctl_t ast_ioctl;
56 static d_strategy_t ast_strategy;
57 static struct cdevsw ast_cdevsw = {
58 .d_version = D_VERSION,
64 .d_strategy = ast_strategy,
66 .d_flags = D_TAPE | D_TRACKCLOSE,
70 static int ast_sense(device_t);
71 static void ast_describe(device_t);
72 static void ast_done(struct ata_request *);
73 static int ast_mode_sense(device_t, int, void *, int);
74 static int ast_mode_select(device_t, void *, int);
75 static int ast_write_filemark(device_t, u_int8_t);
76 static int ast_read_position(device_t, int, struct ast_readposition *);
77 static int ast_space(device_t, u_int8_t, int32_t);
78 static int ast_locate(device_t, int, u_int32_t);
79 static int ast_prevent_allow(device_t, int);
80 static int ast_load_unload(device_t, u_int8_t);
81 static int ast_rewind(device_t);
82 static int ast_erase(device_t);
83 static int ast_test_ready(device_t);
84 static int ast_wait_dsc(device_t, int);
87 static u_int64_t ast_total = 0;
88 static MALLOC_DEFINE(M_AST, "AST driver", "ATAPI tape driver buffers");
91 ast_identify(driver_t *driver, device_t parent)
93 ata_identify(driver, parent, ATA_ATAPI_TYPE_TAPE, "ast");
97 ast_probe(device_t dev)
103 ast_attach(device_t dev)
105 struct ata_channel *ch = device_get_softc(device_get_parent(dev));
106 struct ata_device *atadev = device_get_softc(dev);
107 struct ast_softc *stp;
108 struct ast_readposition position;
111 if (!(stp = malloc(sizeof(struct ast_softc), M_AST, M_NOWAIT | M_ZERO))) {
112 device_printf(dev, "out of memory\n");
113 device_set_softc(dev, NULL);
117 device_set_ivars(dev, stp);
118 ATA_SETMODE(device_get_parent(dev), dev);
120 if (ast_sense(dev)) {
121 device_set_ivars(dev, NULL);
123 device_set_softc(dev, NULL);
127 if (!strcmp(atadev->param.model, "OnStream DI-30")) {
128 struct ast_transferpage transfer;
129 struct ast_identifypage identify;
131 stp->flags |= F_ONSTREAM;
132 bzero(&transfer, sizeof(struct ast_transferpage));
133 ast_mode_sense(dev, ATAPI_TAPE_TRANSFER_PAGE,
134 &transfer, sizeof(transfer));
135 bzero(&identify, sizeof(struct ast_identifypage));
136 ast_mode_sense(dev, ATAPI_TAPE_IDENTIFY_PAGE,
137 &identify, sizeof(identify));
138 strncpy(identify.ident, "FBSD", 4);
139 ast_mode_select(dev, &identify, sizeof(identify));
140 ast_read_position(dev, 0, &position);
143 stp->stats = devstat_new_entry("ast", device_get_unit(dev), DEV_BSIZE,
144 DEVSTAT_NO_ORDERED_TAGS,
145 DEVSTAT_TYPE_SEQUENTIAL | DEVSTAT_TYPE_IF_IDE,
146 DEVSTAT_PRIORITY_TAPE);
147 device = make_dev(&ast_cdevsw, 2 * device_get_unit(dev),
148 UID_ROOT, GID_OPERATOR, 0640, "ast%d",
149 device_get_unit(dev));
150 device->si_drv1 = dev;
152 device->si_iosize_max = ch->dma->max_iosize;
154 device->si_iosize_max = DFLTPHYS;
156 device = make_dev(&ast_cdevsw, 2 * device_get_unit(dev) + 1,
157 UID_ROOT, GID_OPERATOR, 0640, "nast%d",
158 device_get_unit(dev));
159 device->si_drv1 = dev;
161 device->si_iosize_max = ch->dma->max_iosize;
163 device->si_iosize_max = DFLTPHYS;
166 /* announce we are here and ready */
172 ast_detach(device_t dev)
174 struct ata_channel *ch = device_get_softc(device_get_parent(dev));
175 struct ata_device *atadev = device_get_softc(dev);
176 struct ast_softc *stp = device_get_ivars(dev);
178 /* detroy devices from the system so we dont get any further requests */
179 destroy_dev(stp->dev1);
180 destroy_dev(stp->dev2);
182 /* fail requests on the queue and any thats "in flight" for this device */
183 ata_fail_requests(ch, dev);
185 /* dont leave anything behind */
186 devstat_remove_entry(stp->stats);
187 device_set_ivars(dev, NULL);
189 device_set_softc(dev, NULL);
195 ast_shutdown(device_t dev)
197 struct ata_device *atadev = device_get_softc(dev);
199 if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE)
200 ata_controlcmd(atadev, ATA_FLUSHCACHE, 0, 0, 0);
204 ast_reinit(device_t dev)
206 struct ata_channel *ch = device_get_softc(device_get_parent(dev));
207 struct ata_device *atadev = device_get_softc(dev);
208 struct ast_softc *stp = device_get_ivars(dev);
210 if (((atadev->unit == ATA_MASTER) && !(ch->devices & ATA_ATAPI_MASTER)) ||
211 ((atadev->unit == ATA_SLAVE) && !(ch->devices & ATA_ATAPI_SLAVE))) {
212 device_set_ivars(dev, NULL);
216 ATA_SETMODE(device_get_parent(dev), dev);
221 ast_open(struct cdev *cdev, int flags, int fmt, struct thread *td)
223 device_t dev = cdev->si_drv1;
224 struct ata_device *atadev = device_get_softc(dev);
225 struct ast_softc *stp = device_get_ivars(dev);
229 if (!device_is_attached(dev))
234 ast_prevent_allow(dev, 1);
236 device_printf(dev, "sense media type failed\n");
238 atadev->flags &= ~ATA_D_MEDIA_CHANGED;
239 stp->flags &= ~(F_DATA_WRITTEN | F_FM_WRITTEN);
245 ast_close(struct cdev *cdev, int flags, int fmt, struct thread *td)
247 device_t dev = cdev->si_drv1;
248 struct ast_softc *stp = device_get_ivars(dev);
250 /* flush buffers, some drives fail here, they should report ctl = 0 */
251 if (stp->cap.ctl && (stp->flags & F_DATA_WRITTEN))
252 ast_write_filemark(dev, 0);
254 /* write filemark if data written to tape */
255 if (!(stp->flags & F_ONSTREAM) &&
256 (stp->flags & (F_DATA_WRITTEN | F_FM_WRITTEN)) == F_DATA_WRITTEN)
257 ast_write_filemark(dev, ATAPI_WF_WRITE);
259 /* if minor is even rewind on close */
260 if (!(minor(cdev) & 0x01))
263 if (stp->cap.lock && count_dev(cdev) == 1)
264 ast_prevent_allow(dev, 0);
266 stp->flags &= ~F_CTL_WARN;
268 device_printf(dev, "%ju total bytes transferred\n", (uintmax_t)ast_total);
274 ast_ioctl(struct cdev *cdev, u_long cmd, caddr_t addr, int flag, struct thread *td)
276 device_t dev = cdev->si_drv1;
277 struct ast_softc *stp = device_get_ivars(dev);
283 struct mtget *g = (struct mtget *) addr;
285 bzero(g, sizeof(struct mtget));
288 g->mt_blksiz = stp->blksize;
289 g->mt_comp = stp->cap.compress;
290 g->mt_density0 = 0; g->mt_density1 = 0;
291 g->mt_density2 = 0; g->mt_density3 = 0;
292 g->mt_blksiz0 = 0; g->mt_blksiz1 = 0;
293 g->mt_blksiz2 = 0; g->mt_blksiz3 = 0;
294 g->mt_comp0 = 0; g->mt_comp1 = 0;
295 g->mt_comp2 = 0; g->mt_comp3 = 0;
302 struct mtop *mt = (struct mtop *)addr;
304 switch ((int16_t) (mt->mt_op)) {
307 for (i=0; i < mt->mt_count && !error; i++)
308 error = ast_write_filemark(dev, ATAPI_WF_WRITE);
313 error = ast_space(dev, ATAPI_SP_FM, mt->mt_count);
318 error = ast_space(dev, ATAPI_SP_FM, -(mt->mt_count));
322 error = ast_rewind(dev);
326 error = ast_load_unload(dev, ATAPI_SS_EJECT);
330 error = ast_write_filemark(dev, 0);
334 error = ast_erase(dev);
338 error = ast_space(dev, ATAPI_SP_EOD, 0);
342 error = ast_load_unload(dev, ATAPI_SS_RETENSION|ATAPI_SS_LOAD);
360 struct ast_readposition position;
362 if ((error = ast_read_position(dev, 0, &position)))
364 *(u_int32_t *)addr = position.tape;
370 struct ast_readposition position;
372 if ((error = ast_read_position(dev, 1, &position)))
374 *(u_int32_t *)addr = position.tape;
379 error = ast_locate(dev, 0, *(u_int32_t *)addr);
383 error = ast_locate(dev, 1, *(u_int32_t *)addr);
393 ast_strategy(struct bio *bp)
395 device_t dev = bp->bio_dev->si_drv1;
396 struct ata_device *atadev = device_get_softc(dev);
397 struct ast_softc *stp = device_get_ivars(dev);
398 struct ata_request *request;
402 /* if it's a null transfer, return immediatly. */
403 if (bp->bio_bcount == 0) {
408 if (!(bp->bio_cmd == BIO_READ) && stp->flags & F_WRITEPROTECT) {
409 biofinish(bp, NULL, EPERM);
413 /* check for != blocksize requests */
414 if (bp->bio_bcount % stp->blksize) {
415 device_printf(dev, "transfers must be multiple of %d\n", stp->blksize);
416 biofinish(bp, NULL, EIO);
420 /* warn about transfers bigger than the device suggests */
421 if (bp->bio_bcount > stp->blksize * stp->cap.ctl) {
422 if ((stp->flags & F_CTL_WARN) == 0) {
423 device_printf(dev, "WARNING: CTL exceeded %ld>%d\n",
424 bp->bio_bcount, stp->blksize * stp->cap.ctl);
425 stp->flags |= F_CTL_WARN;
429 bzero(ccb, sizeof(ccb));
431 if (bp->bio_cmd == BIO_READ)
434 ccb[0] = ATAPI_WRITE;
436 blkcount = bp->bio_bcount / stp->blksize;
439 ccb[2] = blkcount >> 16;
440 ccb[3] = blkcount >> 8;
443 if (!(request = ata_alloc_request())) {
444 biofinish(bp, NULL, ENOMEM);
448 request->driver = bp;
449 bcopy(ccb, request->u.atapi.ccb,
450 (atadev->param.config & ATA_PROTO_MASK) ==
451 ATA_PROTO_ATAPI_12 ? 16 : 12);
452 request->data = bp->bio_data;
453 request->bytecount = blkcount * stp->blksize;
454 request->transfersize = min(request->bytecount, 65534);
455 request->timeout = (ccb[0] == ATAPI_WRITE_BIG) ? 180 : 120;
456 request->retries = 2;
457 request->callback = ast_done;
458 switch (bp->bio_cmd) {
460 request->flags |= (ATA_R_ATAPI | ATA_R_READ);
463 request->flags |= (ATA_R_ATAPI | ATA_R_WRITE);
466 device_printf(dev, "unknown BIO operation\n");
467 ata_free_request(request);
468 biofinish(bp, NULL, EIO);
471 devstat_start_transaction_bio(stp->stats, bp);
472 ata_queue_request(request);
476 ast_done(struct ata_request *request)
478 struct ast_softc *stp = device_get_ivars(request->dev);
479 struct bio *bp = request->driver;
481 /* finish up transfer */
482 if ((bp->bio_error = request->result))
483 bp->bio_flags |= BIO_ERROR;
484 if (bp->bio_cmd == BIO_WRITE)
485 stp->flags |= F_DATA_WRITTEN;
486 bp->bio_resid = bp->bio_bcount - request->donecount;
487 ast_total += (bp->bio_bcount - bp->bio_resid);
488 biofinish(bp, stp->stats, 0);
489 ata_free_request(request);
493 ast_sense(device_t dev)
495 struct ast_softc *stp = device_get_ivars(dev);
498 /* get drive capabilities, some bugridden drives needs this repeated */
499 for (count = 0 ; count < 5 ; count++) {
500 if (!ast_mode_sense(dev, ATAPI_TAPE_CAP_PAGE,
501 &stp->cap, sizeof(stp->cap)) &&
502 stp->cap.page_code == ATAPI_TAPE_CAP_PAGE) {
504 stp->blksize = 32768;
505 if (stp->cap.blk1024)
511 stp->cap.max_speed = ntohs(stp->cap.max_speed);
512 stp->cap.max_defects = ntohs(stp->cap.max_defects);
513 stp->cap.ctl = ntohs(stp->cap.ctl);
514 stp->cap.speed = ntohs(stp->cap.speed);
515 stp->cap.buffer_size = ntohs(stp->cap.buffer_size);
523 ast_mode_sense(device_t dev, int page, void *pagebuf, int pagesize)
525 struct ata_device *atadev = device_get_softc(dev);
526 int8_t ccb[16] = { ATAPI_MODE_SENSE, 0x08, page, pagesize>>8, pagesize,
527 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
530 error = ata_atapicmd(atadev, ccb, pagebuf, pagesize, ATA_R_READ, 10);
535 ast_mode_select(device_t dev, void *pagebuf, int pagesize)
537 struct ata_device *atadev = device_get_softc(dev);
538 int8_t ccb[16] = { ATAPI_MODE_SELECT, 0x10, 0, pagesize>>8, pagesize,
539 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
541 return ata_atapicmd(atadev, ccb, pagebuf, pagesize, 0, 10);
545 ast_write_filemark(device_t dev, u_int8_t function)
547 struct ata_device *atadev = device_get_softc(dev);
548 struct ast_softc *stp = device_get_ivars(dev);
549 int8_t ccb[16] = { ATAPI_WEOF, 0x01, 0, 0, function, 0, 0, 0,
550 0, 0, 0, 0, 0, 0, 0, 0 };
553 if (stp->flags & F_ONSTREAM)
554 ccb[4] = 0x00; /* only flush buffers supported */
557 if (stp->flags & F_FM_WRITTEN)
558 stp->flags &= ~F_DATA_WRITTEN;
560 stp->flags |= F_FM_WRITTEN;
563 error = ata_atapicmd(atadev, ccb, NULL, 0, 0, 10);
566 return ast_wait_dsc(dev, 10*60);
570 ast_read_position(device_t dev, int hard, struct ast_readposition *position)
572 struct ata_device *atadev = device_get_softc(dev);
573 int8_t ccb[16] = { ATAPI_READ_POSITION, (hard ? 0x01 : 0), 0, 0, 0, 0, 0, 0,
574 0, 0, 0, 0, 0, 0, 0, 0 };
577 error = ata_atapicmd(atadev, ccb, (caddr_t)position,
578 sizeof(struct ast_readposition), ATA_R_READ, 10);
579 position->tape = ntohl(position->tape);
580 position->host = ntohl(position->host);
585 ast_space(device_t dev, u_int8_t function, int32_t count)
587 struct ata_device *atadev = device_get_softc(dev);
588 int8_t ccb[16] = { ATAPI_SPACE, function, count>>16, count>>8, count,
589 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
591 return ata_atapicmd(atadev, ccb, NULL, 0, 0, 60*60);
595 ast_locate(device_t dev, int hard, u_int32_t pos)
597 struct ata_device *atadev = device_get_softc(dev);
598 int8_t ccb[16] = { ATAPI_LOCATE, 0x01 | (hard ? 0x4 : 0), 0,
599 pos>>24, pos>>16, pos>>8, pos,
600 0, 0, 0, 0, 0, 0, 0, 0, 0 };
603 error = ata_atapicmd(atadev, ccb, NULL, 0, 0, 10);
606 return ast_wait_dsc(dev, 60*60);
610 ast_prevent_allow(device_t dev, int lock)
612 struct ata_device *atadev = device_get_softc(dev);
613 int8_t ccb[16] = { ATAPI_PREVENT_ALLOW, 0, 0, 0, lock,
614 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
616 return ata_atapicmd(atadev, ccb, NULL, 0, 0, 30);
620 ast_load_unload(device_t dev, u_int8_t function)
622 struct ata_device *atadev = device_get_softc(dev);
623 struct ast_softc *stp = device_get_ivars(dev);
624 int8_t ccb[16] = { ATAPI_START_STOP, 0x01, 0, 0, function, 0, 0, 0,
625 0, 0, 0, 0, 0, 0, 0, 0 };
628 if ((function & ATAPI_SS_EJECT) && !stp->cap.eject)
630 error = ata_atapicmd(atadev, ccb, NULL, 0, 0, 10);
633 tsleep((caddr_t)&error, PRIBIO, "astlu", 1 * hz);
634 if (function == ATAPI_SS_EJECT)
636 return ast_wait_dsc(dev, 60*60);
640 ast_rewind(device_t dev)
642 struct ata_device *atadev = device_get_softc(dev);
643 int8_t ccb[16] = { ATAPI_REZERO, 0x01, 0, 0, 0, 0, 0, 0,
644 0, 0, 0, 0, 0, 0, 0, 0 };
647 error = ata_atapicmd(atadev, ccb, NULL, 0, 0, 10);
650 return ast_wait_dsc(dev, 60*60);
654 ast_erase(device_t dev)
656 struct ata_device *atadev = device_get_softc(dev);
657 int8_t ccb[16] = { ATAPI_ERASE, 3, 0, 0, 0, 0, 0, 0,
658 0, 0, 0, 0, 0, 0, 0, 0 };
661 if ((error = ast_rewind(dev)))
664 return ata_atapicmd(atadev, ccb, NULL, 0, 0, 60*60);
668 ast_test_ready(device_t dev)
670 struct ata_device *atadev = device_get_softc(dev);
672 int8_t ccb[16] = { ATAPI_TEST_UNIT_READY, 0, 0, 0, 0,
673 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
675 return ata_atapicmd(atadev, ccb, NULL, 0, 0, 30);
679 ast_wait_dsc(device_t dev, int timeout)
681 struct ata_device *atadev = device_get_softc(dev);
684 int8_t ccb[16] = { ATAPI_POLL_DSC, 0, 0, 0, 0,
685 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
688 while (timeout > 0) {
689 error = ata_atapicmd(atadev, ccb, NULL, 0, 0, 0);
692 tsleep(&error, PRIBIO, "atpwt", hz / 2);
699 ast_describe(device_t dev)
701 struct ata_channel *ch = device_get_softc(device_get_parent(dev));
702 struct ata_device *atadev = device_get_softc(dev);
703 struct ast_softc *stp = device_get_ivars(dev);
706 device_printf(dev, "<%.40s/%.8s> tape drive at ata%d as %s\n",
707 atadev->param.model, atadev->param.revision,
708 device_get_unit(ch->dev),
709 (atadev->unit == ATA_MASTER) ? "master" : "slave");
710 device_printf(dev, "%dKB/s, ", stp->cap.max_speed);
711 printf("transfer limit %d blk%s, ",
712 stp->cap.ctl, (stp->cap.ctl > 1) ? "s" : "");
713 printf("%dKB buffer, ", (stp->cap.buffer_size * DEV_BSIZE) / 1024);
714 printf("%s\n", ata_mode2str(atadev->mode));
715 device_printf(dev, "Medium: ");
716 switch (stp->cap.medium_type) {
718 printf("none"); break;
720 printf("Travan 1 (400 Mbyte)"); break;
722 printf("Travan 4 (4 Gbyte)"); break;
724 printf("OnStream ADR (15Gyte)"); break;
726 printf("unknown (0x%x)", stp->cap.medium_type);
728 if (stp->cap.readonly) printf(", readonly");
729 if (stp->cap.reverse) printf(", reverse");
730 if (stp->cap.eformat) printf(", eformat");
731 if (stp->cap.qfa) printf(", qfa");
732 if (stp->cap.lock) printf(", lock");
733 if (stp->cap.locked) printf(", locked");
734 if (stp->cap.prevent) printf(", prevent");
735 if (stp->cap.eject) printf(", eject");
736 if (stp->cap.disconnect) printf(", disconnect");
737 if (stp->cap.ecc) printf(", ecc");
738 if (stp->cap.compress) printf(", compress");
739 if (stp->cap.blk512) printf(", 512b");
740 if (stp->cap.blk1024) printf(", 1024b");
741 if (stp->cap.blk32k) printf(", 32kb");
745 device_printf(dev, "TAPE <%.40s/%.8s> at ata%d-%s %s\n",
746 atadev->param.model, atadev->param.revision,
747 device_get_unit(ch->dev),
748 (atadev->unit == ATA_MASTER) ? "master" : "slave",
749 ata_mode2str(atadev->mode));
753 static device_method_t ast_methods[] = {
754 /* device interface */
755 DEVMETHOD(device_identify, ast_identify),
756 DEVMETHOD(device_probe, ast_probe),
757 DEVMETHOD(device_attach, ast_attach),
758 DEVMETHOD(device_detach, ast_detach),
759 DEVMETHOD(device_shutdown, ast_shutdown),
762 DEVMETHOD(ata_reinit, ast_reinit),
767 static driver_t ast_driver = {
773 static devclass_t ast_devclass;
776 ast_modevent(module_t mod, int what, void *arg)
781 if (what == MOD_UNLOAD) {
782 if (!devclass_get_devices(ast_devclass, &devs, &ndevs) && devs) {
783 for (i = 0; i < ndevs; i++)
784 device_delete_child(device_get_parent(devs[i]), devs[i]);
791 DRIVER_MODULE(ast, ata, ast_driver, ast_devclass, ast_modevent, NULL);
792 MODULE_VERSION(ast, 1);
793 MODULE_DEPEND(ast, ata, 1, 1, 1);