]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ata/atapi-tape.c
This commit was generated by cvs2svn to compensate for changes in r178528,
[FreeBSD/FreeBSD.git] / sys / dev / ata / atapi-tape.c
1 /*-
2  * Copyright (c) 1998 - 2008 Søren Schmidt <sos@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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  *
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.
25  */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include "opt_ata.h"
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/ata.h>
34 #include <sys/kernel.h>
35 #include <sys/module.h>
36 #include <sys/malloc.h>
37 #include <sys/conf.h>
38 #include <sys/bio.h>
39 #include <sys/bus.h>
40 #include <sys/mtio.h>
41 #include <sys/devicestat.h>
42 #include <sys/sema.h>
43 #include <sys/taskqueue.h>
44 #include <vm/uma.h>
45 #include <machine/bus.h>
46 #include <dev/ata/ata-all.h>
47 #include <dev/ata/atapi-tape.h>
48 #include <ata_if.h>
49
50 /* device structure */
51 static  d_open_t        ast_open;
52 static  d_close_t       ast_close;
53 static  d_ioctl_t       ast_ioctl;
54 static  d_strategy_t    ast_strategy;
55 static struct cdevsw ast_cdevsw = {
56         .d_version =    D_VERSION,
57         .d_open =       ast_open,
58         .d_close =      ast_close,
59         .d_read =       physread,
60         .d_write =      physwrite,
61         .d_ioctl =      ast_ioctl,
62         .d_strategy =   ast_strategy,
63         .d_name =       "ast",
64         .d_flags =      D_TAPE | D_TRACKCLOSE,
65 };
66
67 /* prototypes */
68 static int ast_sense(device_t);
69 static void ast_describe(device_t);
70 static void ast_done(struct ata_request *);
71 static int ast_mode_sense(device_t, int, void *, int); 
72 static int ast_mode_select(device_t, void *, int);
73 static int ast_write_filemark(device_t, u_int8_t);
74 static int ast_read_position(device_t, int, struct ast_readposition *);
75 static int ast_space(device_t, u_int8_t, int32_t);
76 static int ast_locate(device_t, int, u_int32_t);
77 static int ast_prevent_allow(device_t, int);
78 static int ast_load_unload(device_t, u_int8_t);
79 static int ast_rewind(device_t);
80 static int ast_erase(device_t);
81 static int ast_test_ready(device_t);
82 static int ast_wait_dsc(device_t, int);
83
84 /* internal vars */
85 static u_int64_t ast_total = 0;
86 static MALLOC_DEFINE(M_AST, "ast_driver", "ATAPI tape driver buffers");
87
88 static int
89 ast_probe(device_t dev)
90 {
91     struct ata_device *atadev = device_get_softc(dev);
92
93     if ((atadev->param.config & ATA_PROTO_ATAPI) &&
94         (atadev->param.config & ATA_ATAPI_TYPE_MASK) == ATA_ATAPI_TYPE_TAPE)
95         return 0;
96     else
97         return ENXIO;
98 }
99
100 static int
101 ast_attach(device_t dev)
102 {
103     struct ata_channel *ch = device_get_softc(device_get_parent(dev));
104     struct ata_device *atadev = device_get_softc(dev);
105     struct ast_softc *stp;
106     struct ast_readposition position;
107     struct cdev *device;
108
109     if (!(stp = malloc(sizeof(struct ast_softc), M_AST, M_NOWAIT | M_ZERO))) {
110         device_printf(dev, "out of memory\n");
111         return ENOMEM;
112     }
113     device_set_ivars(dev, stp);
114     ATA_SETMODE(device_get_parent(dev), dev);
115
116     if (ast_sense(dev)) {
117         device_set_ivars(dev, NULL);
118         free(stp, M_AST);
119         return ENXIO;
120     }
121     if (!strcmp(atadev->param.model, "OnStream DI-30")) {
122         struct ast_transferpage transfer;
123         struct ast_identifypage identify;
124
125         stp->flags |= F_ONSTREAM;
126         bzero(&transfer, sizeof(struct ast_transferpage));
127         ast_mode_sense(dev, ATAPI_TAPE_TRANSFER_PAGE,
128                        &transfer, sizeof(transfer));
129         bzero(&identify, sizeof(struct ast_identifypage));
130         ast_mode_sense(dev, ATAPI_TAPE_IDENTIFY_PAGE,
131                        &identify, sizeof(identify));
132         strncpy(identify.ident, "FBSD", 4);
133         ast_mode_select(dev, &identify, sizeof(identify));
134         ast_read_position(dev, 0, &position);
135     }
136
137     stp->stats = devstat_new_entry("ast", device_get_unit(dev), DEV_BSIZE,
138                       DEVSTAT_NO_ORDERED_TAGS,
139                       DEVSTAT_TYPE_SEQUENTIAL | DEVSTAT_TYPE_IF_IDE,
140                       DEVSTAT_PRIORITY_TAPE);
141     device = make_dev(&ast_cdevsw, 2 * device_get_unit(dev),
142                       UID_ROOT, GID_OPERATOR, 0640, "ast%d",
143                       device_get_unit(dev));
144     device->si_drv1 = dev;
145     device->si_iosize_max = ch->dma.max_iosize;
146     stp->dev1 = device;
147     device = make_dev(&ast_cdevsw, 2 * device_get_unit(dev) + 1,
148                       UID_ROOT, GID_OPERATOR, 0640, "nast%d",
149                       device_get_unit(dev));
150     device->si_drv1 = dev;
151     device->si_iosize_max = ch->dma.max_iosize;
152     stp->dev2 = device;
153
154     /* announce we are here and ready */
155     ast_describe(dev);
156     return 0;
157 }
158
159 static int      
160 ast_detach(device_t dev)
161 {   
162     struct ast_softc *stp = device_get_ivars(dev);
163     
164     /* detroy devices from the system so we dont get any further requests */
165     destroy_dev(stp->dev1);
166     destroy_dev(stp->dev2);
167
168     /* fail requests on the queue and any thats "in flight" for this device */
169     ata_fail_requests(dev);
170
171     /* dont leave anything behind */
172     devstat_remove_entry(stp->stats);
173     device_set_ivars(dev, NULL);
174     free(stp, M_AST);
175     return 0;
176 }
177
178 static void
179 ast_shutdown(device_t dev)
180 {
181     struct ata_device *atadev = device_get_softc(dev);
182
183     if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE)
184         ata_controlcmd(dev, ATA_FLUSHCACHE, 0, 0, 0);
185 }
186
187 static int
188 ast_reinit(device_t dev)
189 {
190     struct ata_channel *ch = device_get_softc(device_get_parent(dev));
191     struct ata_device *atadev = device_get_softc(dev);
192
193     if (((atadev->unit == ATA_MASTER) && !(ch->devices & ATA_ATAPI_MASTER)) ||
194         ((atadev->unit == ATA_SLAVE) && !(ch->devices & ATA_ATAPI_SLAVE))) {
195         return 1;
196     }
197     ATA_SETMODE(device_get_parent(dev), dev);
198     return 0;
199 }
200
201 static int
202 ast_open(struct cdev *cdev, int flags, int fmt, struct thread *td)
203 {
204     device_t dev = cdev->si_drv1;
205     struct ata_device *atadev = device_get_softc(dev);
206     struct ast_softc *stp = device_get_ivars(dev);
207
208     if (!stp)
209         return ENXIO;
210     if (!device_is_attached(dev))
211         return EBUSY;
212
213     ast_test_ready(dev);
214     if (stp->cap.lock)
215         ast_prevent_allow(dev, 1);
216     if (ast_sense(dev))
217         device_printf(dev, "sense media type failed\n");
218
219     atadev->flags &= ~ATA_D_MEDIA_CHANGED;
220     stp->flags &= ~(F_DATA_WRITTEN | F_FM_WRITTEN);
221     ast_total = 0;
222     return 0;
223 }
224
225 static int 
226 ast_close(struct cdev *cdev, int flags, int fmt, struct thread *td)
227 {
228     device_t dev = cdev->si_drv1;
229     struct ast_softc *stp = device_get_ivars(dev);
230
231     /* flush buffers, some drives fail here, they should report ctl = 0 */
232     if (stp->cap.ctl && (stp->flags & F_DATA_WRITTEN))
233         ast_write_filemark(dev, 0);
234
235     /* write filemark if data written to tape */
236     if (!(stp->flags & F_ONSTREAM) &&
237         (stp->flags & (F_DATA_WRITTEN | F_FM_WRITTEN)) == F_DATA_WRITTEN)
238         ast_write_filemark(dev, ATAPI_WF_WRITE);
239
240     /* if minor is even rewind on close */
241     if (!(minor(cdev) & 0x01))
242         ast_rewind(dev);
243
244     if (stp->cap.lock && count_dev(cdev) == 1)
245         ast_prevent_allow(dev, 0);
246
247     stp->flags &= ~F_CTL_WARN;
248 #ifdef AST_DEBUG
249     device_printf(dev, "%ju total bytes transferred\n", (uintmax_t)ast_total);
250 #endif
251     return 0;
252 }
253
254 static int 
255 ast_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int flag, struct thread *td)
256 {
257     device_t dev = cdev->si_drv1;
258     struct ast_softc *stp = device_get_ivars(dev);
259     int error = 0;
260
261     switch (cmd) {
262     case MTIOCGET:
263         {
264             struct mtget *g = (struct mtget *) data;
265
266             bzero(g, sizeof(struct mtget));
267             g->mt_type = 7;
268             g->mt_density = 1;
269             g->mt_blksiz = stp->blksize;
270             g->mt_comp = stp->cap.compress;
271             g->mt_density0 = 0; g->mt_density1 = 0;
272             g->mt_density2 = 0; g->mt_density3 = 0;
273             g->mt_blksiz0 = 0; g->mt_blksiz1 = 0;
274             g->mt_blksiz2 = 0; g->mt_blksiz3 = 0;
275             g->mt_comp0 = 0; g->mt_comp1 = 0;
276             g->mt_comp2 = 0; g->mt_comp3 = 0;
277         }
278         break;   
279
280     case MTIOCTOP:
281         {       
282             int i;
283             struct mtop *mt = (struct mtop *)data;
284
285             switch ((int16_t) (mt->mt_op)) {
286
287             case MTWEOF:
288                 for (i=0; i < mt->mt_count && !error; i++)
289                     error = ast_write_filemark(dev, ATAPI_WF_WRITE);
290                 break;
291
292             case MTFSF:
293                 if (mt->mt_count)
294                     error = ast_space(dev, ATAPI_SP_FM, mt->mt_count);
295                 break;
296
297             case MTBSF:
298                 if (mt->mt_count)
299                     error = ast_space(dev, ATAPI_SP_FM, -(mt->mt_count));
300                 break;
301
302             case MTREW:
303                 error = ast_rewind(dev);
304                 break;
305
306             case MTOFFL:
307                 error = ast_load_unload(dev, ATAPI_SS_EJECT);
308                 break;
309
310             case MTNOP:
311                 error = ast_write_filemark(dev, 0);
312                 break;
313
314             case MTERASE:
315                 error = ast_erase(dev);
316                 break;
317
318             case MTEOD:
319                 error = ast_space(dev, ATAPI_SP_EOD, 0);
320                 break;
321
322             case MTRETENS:
323                 error = ast_load_unload(dev, ATAPI_SS_RETENSION|ATAPI_SS_LOAD);
324                 break;
325
326             case MTFSR:         
327             case MTBSR:
328             case MTCACHE:
329             case MTNOCACHE:
330             case MTSETBSIZ:
331             case MTSETDNSTY:
332             case MTCOMP:
333             default:
334                 error = EINVAL;
335             }
336         }
337         break;
338
339     case MTIOCRDSPOS:
340         {
341             struct ast_readposition position;
342
343             if ((error = ast_read_position(dev, 0, &position)))
344                 break;
345             *(u_int32_t *)data = position.tape;
346         }
347         break;
348
349     case MTIOCRDHPOS:
350         {
351             struct ast_readposition position;
352
353             if ((error = ast_read_position(dev, 1, &position)))
354                 break;
355             *(u_int32_t *)data = position.tape;
356         }
357         break;
358
359     case MTIOCSLOCATE:
360         error = ast_locate(dev, 0, *(u_int32_t *)data);
361         break;
362
363     case MTIOCHLOCATE:
364         error = ast_locate(dev, 1, *(u_int32_t *)data);
365         break;
366
367     default:
368         error = ata_device_ioctl(dev, cmd, data);
369     }
370     return error;
371 }
372
373 static void 
374 ast_strategy(struct bio *bp)
375 {
376     device_t dev = bp->bio_dev->si_drv1;
377     struct ata_device *atadev = device_get_softc(dev);
378     struct ast_softc *stp = device_get_ivars(dev);
379     struct ata_request *request;
380     u_int32_t blkcount;
381     int8_t ccb[16];
382
383     /* if it's a null transfer, return immediatly. */
384     if (bp->bio_bcount == 0) {
385         bp->bio_resid = 0;
386         biodone(bp);
387         return;
388     }
389     if (!(bp->bio_cmd == BIO_READ) && stp->flags & F_WRITEPROTECT) {
390         biofinish(bp, NULL, EPERM);
391         return;
392     }
393         
394     /* check for != blocksize requests */
395     if (bp->bio_bcount % stp->blksize) {
396         device_printf(dev, "transfers must be multiple of %d\n", stp->blksize);
397         biofinish(bp, NULL, EIO);
398         return;
399     }
400
401     /* warn about transfers bigger than the device suggests */
402     if (bp->bio_bcount > stp->blksize * stp->cap.ctl) {  
403         if ((stp->flags & F_CTL_WARN) == 0) {
404             device_printf(dev, "WARNING: CTL exceeded %ld>%d\n",
405                           bp->bio_bcount, stp->blksize * stp->cap.ctl);
406             stp->flags |= F_CTL_WARN;
407         }
408     }
409
410     bzero(ccb, sizeof(ccb));
411
412     if (bp->bio_cmd == BIO_READ)
413         ccb[0] = ATAPI_READ;
414     else
415         ccb[0] = ATAPI_WRITE;
416     
417     blkcount = bp->bio_bcount / stp->blksize;
418
419     ccb[1] = 1;
420     ccb[2] = blkcount >> 16;
421     ccb[3] = blkcount >> 8;
422     ccb[4] = blkcount;
423
424     if (!(request = ata_alloc_request())) {
425         biofinish(bp, NULL, ENOMEM);
426         return;
427     }
428     request->dev = dev;
429     request->driver = bp;
430     bcopy(ccb, request->u.atapi.ccb,
431           (atadev->param.config & ATA_PROTO_MASK) == 
432           ATA_PROTO_ATAPI_12 ? 16 : 12);
433     request->data = bp->bio_data;
434     request->bytecount = blkcount * stp->blksize;
435     request->transfersize = min(request->bytecount, 65534);
436     request->timeout = (ccb[0] == ATAPI_WRITE_BIG) ? 180 : 120;
437     request->retries = 2;
438     request->callback = ast_done;
439     switch (bp->bio_cmd) {
440     case BIO_READ:
441         request->flags |= (ATA_R_ATAPI | ATA_R_READ);
442         break;
443     case BIO_WRITE:
444         request->flags |= (ATA_R_ATAPI | ATA_R_WRITE);
445         break;
446     default:
447         device_printf(dev, "unknown BIO operation\n");
448         ata_free_request(request);
449         biofinish(bp, NULL, EIO);
450         return;
451     }
452     devstat_start_transaction_bio(stp->stats, bp);
453     ata_queue_request(request);
454 }
455
456 static void 
457 ast_done(struct ata_request *request)
458 {
459     struct ast_softc *stp = device_get_ivars(request->dev);
460     struct bio *bp = request->driver;
461
462     /* finish up transfer */
463     if ((bp->bio_error = request->result))
464         bp->bio_flags |= BIO_ERROR;
465     if (bp->bio_cmd == BIO_WRITE)
466         stp->flags |= F_DATA_WRITTEN;
467     bp->bio_resid = bp->bio_bcount - request->donecount;
468     ast_total += (bp->bio_bcount - bp->bio_resid);
469     biofinish(bp, stp->stats, 0);
470     ata_free_request(request);
471 }
472
473 static int
474 ast_sense(device_t dev)
475 {
476     struct ast_softc *stp = device_get_ivars(dev);
477     int count;
478
479     /* get drive capabilities, some bugridden drives needs this repeated */
480     for (count = 0 ; count < 5 ; count++) {
481         if (!ast_mode_sense(dev, ATAPI_TAPE_CAP_PAGE,
482                             &stp->cap, sizeof(stp->cap)) &&
483             stp->cap.page_code == ATAPI_TAPE_CAP_PAGE) {
484             if (stp->cap.blk32k)
485                 stp->blksize = 32768;
486             if (stp->cap.blk1024)
487                 stp->blksize = 1024;
488             if (stp->cap.blk512)
489                 stp->blksize = 512;
490             if (!stp->blksize)
491                 continue;
492             stp->cap.max_speed = ntohs(stp->cap.max_speed);
493             stp->cap.max_defects = ntohs(stp->cap.max_defects);
494             stp->cap.ctl = ntohs(stp->cap.ctl);
495             stp->cap.speed = ntohs(stp->cap.speed);
496             stp->cap.buffer_size = ntohs(stp->cap.buffer_size);
497             return 0;
498         }
499     }
500     return 1;
501 }
502
503 static int
504 ast_mode_sense(device_t dev, int page, void *pagebuf, int pagesize)
505 {
506     int8_t ccb[16] = { ATAPI_MODE_SENSE, 0x08, page, pagesize>>8, pagesize,
507                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
508     int error;
509  
510     error = ata_atapicmd(dev, ccb, pagebuf, pagesize, ATA_R_READ, 10);
511     return error;
512 }
513
514 static int       
515 ast_mode_select(device_t dev, void *pagebuf, int pagesize)
516 {
517     int8_t ccb[16] = { ATAPI_MODE_SELECT, 0x10, 0, pagesize>>8, pagesize,
518                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
519      
520     return ata_atapicmd(dev, ccb, pagebuf, pagesize, 0, 10);
521 }
522
523 static int
524 ast_write_filemark(device_t dev, u_int8_t function)
525 {
526     struct ast_softc *stp = device_get_ivars(dev);
527     int8_t ccb[16] = { ATAPI_WEOF, 0x01, 0, 0, function, 0, 0, 0,
528                        0, 0, 0, 0, 0, 0, 0, 0 };
529     int error;
530
531     if (stp->flags & F_ONSTREAM)
532         ccb[4] = 0x00;          /* only flush buffers supported */
533     else {
534         if (function) {
535             if (stp->flags & F_FM_WRITTEN)
536                 stp->flags &= ~F_DATA_WRITTEN;
537             else
538                 stp->flags |= F_FM_WRITTEN;
539         }
540     }
541     error = ata_atapicmd(dev, ccb, NULL, 0, 0, 10);
542     if (error)
543         return error;
544     return ast_wait_dsc(dev, 10*60);
545 }
546
547 static int
548 ast_read_position(device_t dev, int hard, struct ast_readposition *position)
549 {
550     int8_t ccb[16] = { ATAPI_READ_POSITION, (hard ? 0x01 : 0), 0, 0, 0, 0, 0, 0,
551                        0, 0, 0, 0, 0, 0, 0, 0 };
552     int error;
553
554     error = ata_atapicmd(dev, ccb, (caddr_t)position, 
555                          sizeof(struct ast_readposition), ATA_R_READ, 10);
556     position->tape = ntohl(position->tape);
557     position->host = ntohl(position->host);
558     return error;
559 }
560
561 static int
562 ast_space(device_t dev, u_int8_t function, int32_t count)
563 {
564     int8_t ccb[16] = { ATAPI_SPACE, function, count>>16, count>>8, count,
565                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
566
567     return ata_atapicmd(dev, ccb, NULL, 0, 0, 60*60);
568 }
569
570 static int
571 ast_locate(device_t dev, int hard, u_int32_t pos)
572 {
573     int8_t ccb[16] = { ATAPI_LOCATE, 0x01 | (hard ? 0x4 : 0), 0,
574                        pos>>24, pos>>16, pos>>8, pos,
575                        0, 0, 0, 0, 0, 0, 0, 0, 0 };
576     int error;
577
578     error = ata_atapicmd(dev, ccb, NULL, 0, 0, 10);
579     if (error)
580         return error;
581     return ast_wait_dsc(dev, 60*60);
582 }
583
584 static int
585 ast_prevent_allow(device_t dev, int lock)
586 {
587     int8_t ccb[16] = { ATAPI_PREVENT_ALLOW, 0, 0, 0, lock,
588                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
589
590     return ata_atapicmd(dev, ccb, NULL, 0, 0, 30);
591 }
592
593 static int
594 ast_load_unload(device_t dev, u_int8_t function)
595 {
596     struct ast_softc *stp = device_get_ivars(dev);
597     int8_t ccb[16] = { ATAPI_START_STOP, 0x01, 0, 0, function, 0, 0, 0,
598                        0, 0, 0, 0, 0, 0, 0, 0 };
599     int error;
600
601     if ((function & ATAPI_SS_EJECT) && !stp->cap.eject)
602         return 0;
603     error = ata_atapicmd(dev, ccb, NULL, 0, 0, 10);
604     if (error)
605         return error;
606     pause("astlu", 1 * hz);
607     if (function == ATAPI_SS_EJECT)
608         return 0;
609     return ast_wait_dsc(dev, 60*60);
610 }
611
612 static int
613 ast_rewind(device_t dev)
614 {
615     int8_t ccb[16] = { ATAPI_REZERO, 0x01, 0, 0, 0, 0, 0, 0,
616                        0, 0, 0, 0, 0, 0, 0, 0 };
617     int error;
618
619     error = ata_atapicmd(dev, ccb, NULL, 0, 0, 10);
620     if (error)
621         return error;
622     return ast_wait_dsc(dev, 60*60);
623 }
624
625 static int
626 ast_erase(device_t dev)
627 {
628     int8_t ccb[16] = { ATAPI_ERASE, 3, 0, 0, 0, 0, 0, 0,
629                        0, 0, 0, 0, 0, 0, 0, 0 };
630     int error;
631
632     if ((error = ast_rewind(dev)))
633         return error;
634
635     return ata_atapicmd(dev, ccb, NULL, 0, 0, 60*60);
636 }
637
638 static int
639 ast_test_ready(device_t dev)
640 {
641     int8_t ccb[16] = { ATAPI_TEST_UNIT_READY, 0, 0, 0, 0,
642                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
643
644     return ata_atapicmd(dev, ccb, NULL, 0, 0, 30);
645 }
646
647 static int
648 ast_wait_dsc(device_t dev, int timeout)
649 {
650     int error = 0;
651     int8_t ccb[16] = { ATAPI_POLL_DSC, 0, 0, 0, 0,
652                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
653
654     timeout *= hz;
655     while (timeout > 0) {
656         error = ata_atapicmd(dev, ccb, NULL, 0, 0, 0);
657         if (error != EBUSY)
658             break;
659         pause("atpwt", hz / 2);
660         timeout -= (hz / 2);
661     }
662     return error;
663 }
664
665 static void 
666 ast_describe(device_t dev)
667 {
668     struct ata_channel *ch = device_get_softc(device_get_parent(dev));
669     struct ata_device *atadev = device_get_softc(dev);
670     struct ast_softc *stp = device_get_ivars(dev);
671
672     if (bootverbose) {
673         device_printf(dev, "<%.40s/%.8s> tape drive at ata%d as %s\n",
674                       atadev->param.model, atadev->param.revision,
675                       device_get_unit(ch->dev), ata_unit2str(atadev));
676         device_printf(dev, "%dKB/s, ", stp->cap.max_speed);
677         printf("transfer limit %d blk%s, ",
678                stp->cap.ctl, (stp->cap.ctl > 1) ? "s" : "");
679         printf("%dKB buffer, ", (stp->cap.buffer_size * DEV_BSIZE) / 1024);
680         printf("%s\n", ata_mode2str(atadev->mode));
681         device_printf(dev, "Medium: ");
682         switch (stp->cap.medium_type) {
683             case 0x00:
684                 printf("none"); break;
685             case 0x17:
686                 printf("Travan 1 (400 Mbyte)"); break;
687             case 0xb6:
688                 printf("Travan 4 (4 Gbyte)"); break;
689             case 0xda:
690                 printf("OnStream ADR (15Gyte)"); break;
691             default:
692                 printf("unknown (0x%x)", stp->cap.medium_type);
693         }
694         if (stp->cap.readonly) printf(", readonly");
695         if (stp->cap.reverse) printf(", reverse");
696         if (stp->cap.eformat) printf(", eformat");
697         if (stp->cap.qfa) printf(", qfa");
698         if (stp->cap.lock) printf(", lock");
699         if (stp->cap.locked) printf(", locked");
700         if (stp->cap.prevent) printf(", prevent");
701         if (stp->cap.eject) printf(", eject");
702         if (stp->cap.disconnect) printf(", disconnect");
703         if (stp->cap.ecc) printf(", ecc");
704         if (stp->cap.compress) printf(", compress");
705         if (stp->cap.blk512) printf(", 512b");
706         if (stp->cap.blk1024) printf(", 1024b");
707         if (stp->cap.blk32k) printf(", 32kb");
708         printf("\n");
709     }
710     else {
711         device_printf(dev, "TAPE <%.40s/%.8s> at ata%d-%s %s\n",
712                       atadev->param.model, atadev->param.revision,
713                       device_get_unit(ch->dev), ata_unit2str(atadev),
714                       ata_mode2str(atadev->mode));
715     }
716 }
717
718 static device_method_t ast_methods[] = {
719     /* device interface */
720     DEVMETHOD(device_probe,     ast_probe),
721     DEVMETHOD(device_attach,    ast_attach),
722     DEVMETHOD(device_detach,    ast_detach),
723     DEVMETHOD(device_shutdown,  ast_shutdown),
724                            
725     /* ATA methods */
726     DEVMETHOD(ata_reinit,       ast_reinit),
727
728     { 0, 0 }
729 };
730             
731 static driver_t ast_driver = {
732     "ast",
733     ast_methods,
734     0,
735 };
736
737 static devclass_t ast_devclass;
738
739 DRIVER_MODULE(ast, ata, ast_driver, ast_devclass, NULL, NULL);
740 MODULE_VERSION(ast, 1);
741 MODULE_DEPEND(ast, ata, 1, 1, 1);