Deleted Added
full compact
atapi-tape.c (86014) atapi-tape.c (90215)
1/*-
1/*-
2 * Copyright (c) 1998,1999,2000,2001 S�ren Schmidt
2 * Copyright (c) 1998,1999,2000,2001,2002 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.

--- 9 unchanged lines hidden (view full) ---

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.
27 *
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.

--- 9 unchanged lines hidden (view full) ---

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.
27 *
28 * $FreeBSD: head/sys/dev/ata/atapi-tape.c 86014 2001-11-04 09:09:41Z phk $
28 * $FreeBSD: head/sys/dev/ata/atapi-tape.c 90215 2002-02-04 19:23:40Z sos $
29 */
30
31#include <sys/param.h>
32#include <sys/systm.h>
33#include <sys/ata.h>
34#include <sys/kernel.h>
35#include <sys/conf.h>
36#include <sys/malloc.h>

--- 43 unchanged lines hidden (view full) ---

80static int ast_erase(struct ast_softc *);
81
82/* internal vars */
83static u_int32_t ast_lun_map = 0;
84static u_int64_t ast_total = 0;
85static MALLOC_DEFINE(M_AST, "AST driver", "ATAPI tape driver buffers");
86
87int
29 */
30
31#include <sys/param.h>
32#include <sys/systm.h>
33#include <sys/ata.h>
34#include <sys/kernel.h>
35#include <sys/conf.h>
36#include <sys/malloc.h>

--- 43 unchanged lines hidden (view full) ---

80static int ast_erase(struct ast_softc *);
81
82/* internal vars */
83static u_int32_t ast_lun_map = 0;
84static u_int64_t ast_total = 0;
85static MALLOC_DEFINE(M_AST, "AST driver", "ATAPI tape driver buffers");
86
87int
88astattach(struct atapi_softc *atp)
88astattach(struct ata_device *atadev)
89{
90 struct ast_softc *stp;
91 struct ast_readposition position;
92 dev_t dev;
93
94 stp = malloc(sizeof(struct ast_softc), M_AST, M_NOWAIT | M_ZERO);
95 if (!stp) {
89{
90 struct ast_softc *stp;
91 struct ast_readposition position;
92 dev_t dev;
93
94 stp = malloc(sizeof(struct ast_softc), M_AST, M_NOWAIT | M_ZERO);
95 if (!stp) {
96 ata_printf(atp->controller, atp->unit, "out of memory\n");
96 ata_prtdev(atadev, "out of memory\n");
97 return -1;
98 }
99
97 return -1;
98 }
99
100 stp->atp = atp;
100 stp->device = atadev;
101 stp->lun = ata_get_lun(&ast_lun_map);
101 stp->lun = ata_get_lun(&ast_lun_map);
102 ata_set_name(atp->controller, atp->unit, "ast", stp->lun);
102 ata_set_name(atadev, "ast", stp->lun);
103 bioq_init(&stp->queue);
104
105 if (ast_sense(stp)) {
106 free(stp, M_AST);
107 return -1;
108 }
109
103 bioq_init(&stp->queue);
104
105 if (ast_sense(stp)) {
106 free(stp, M_AST);
107 return -1;
108 }
109
110 if (!strcmp(ATA_PARAM(stp->atp->controller, stp->atp->unit)->model,
111 "OnStream DI-30")) {
110 if (!strcmp(atadev->param->model, "OnStream DI-30")) {
112 struct ast_transferpage transfer;
113 struct ast_identifypage identify;
114
115 stp->flags |= F_ONSTREAM;
116 bzero(&transfer, sizeof(struct ast_transferpage));
117 ast_mode_sense(stp, ATAPI_TAPE_TRANSFER_PAGE,
118 &transfer, sizeof(transfer));
119 bzero(&identify, sizeof(struct ast_identifypage));

--- 13 unchanged lines hidden (view full) ---

133 dev->si_drv1 = stp;
134 dev->si_iosize_max = 252 * DEV_BSIZE;
135 stp->dev1 = dev;
136 dev = make_dev(&ast_cdevsw, dkmakeminor(stp->lun, 0, 1),
137 UID_ROOT, GID_OPERATOR, 0640, "nast%d", stp->lun);
138 dev->si_drv1 = stp;
139 dev->si_iosize_max = 252 * DEV_BSIZE;
140 stp->dev2 = dev;
111 struct ast_transferpage transfer;
112 struct ast_identifypage identify;
113
114 stp->flags |= F_ONSTREAM;
115 bzero(&transfer, sizeof(struct ast_transferpage));
116 ast_mode_sense(stp, ATAPI_TAPE_TRANSFER_PAGE,
117 &transfer, sizeof(transfer));
118 bzero(&identify, sizeof(struct ast_identifypage));

--- 13 unchanged lines hidden (view full) ---

132 dev->si_drv1 = stp;
133 dev->si_iosize_max = 252 * DEV_BSIZE;
134 stp->dev1 = dev;
135 dev = make_dev(&ast_cdevsw, dkmakeminor(stp->lun, 0, 1),
136 UID_ROOT, GID_OPERATOR, 0640, "nast%d", stp->lun);
137 dev->si_drv1 = stp;
138 dev->si_iosize_max = 252 * DEV_BSIZE;
139 stp->dev2 = dev;
141 stp->atp->flags |= ATAPI_F_MEDIA_CHANGED;
142 stp->atp->driver = stp;
140 stp->device->flags |= ATA_D_MEDIA_CHANGED;
143 ast_describe(stp);
141 ast_describe(stp);
142 atadev->driver = stp;
144 return 0;
145}
146
143 return 0;
144}
145
147void
148astdetach(struct atapi_softc *atp)
146void
147astdetach(struct ata_device *atadev)
149{
148{
150 struct ast_softc *stp = atp->driver;
149 struct ast_softc *stp = atadev->driver;
151 struct bio *bp;
152
153 while ((bp = bioq_first(&stp->queue))) {
150 struct bio *bp;
151
152 while ((bp = bioq_first(&stp->queue))) {
153 bioq_remove(&stp->queue, bp);
154 biofinish(bp, NULL, ENXIO);
155 }
156 destroy_dev(stp->dev1);
157 destroy_dev(stp->dev2);
158 devstat_remove_entry(&stp->stats);
154 biofinish(bp, NULL, ENXIO);
155 }
156 destroy_dev(stp->dev1);
157 destroy_dev(stp->dev2);
158 devstat_remove_entry(&stp->stats);
159 ata_free_name(atp->controller, atp->unit);
159 ata_free_name(atadev);
160 ata_free_lun(&ast_lun_map, stp->lun);
161 free(stp, M_AST);
160 ata_free_lun(&ast_lun_map, stp->lun);
161 free(stp, M_AST);
162 atadev->driver = NULL;
162}
163
164static int
165ast_sense(struct ast_softc *stp)
166{
167 int count, error = 0;
168
169 /* get drive capabilities, some drives needs this repeated */

--- 18 unchanged lines hidden (view full) ---

188 }
189 return 1;
190}
191
192static void
193ast_describe(struct ast_softc *stp)
194{
195 if (bootverbose) {
163}
164
165static int
166ast_sense(struct ast_softc *stp)
167{
168 int count, error = 0;
169
170 /* get drive capabilities, some drives needs this repeated */

--- 18 unchanged lines hidden (view full) ---

189 }
190 return 1;
191}
192
193static void
194ast_describe(struct ast_softc *stp)
195{
196 if (bootverbose) {
196 ata_printf(stp->atp->controller, stp->atp->unit,
197 "<%.40s/%.8s> tape drive at ata%d as %s\n",
198 ATA_PARAM(stp->atp->controller, stp->atp->unit)->model,
199 ATA_PARAM(stp->atp->controller, stp->atp->unit)->revision,
200 device_get_unit(stp->atp->controller->dev),
201 (stp->atp->unit == ATA_MASTER) ? "master" : "slave");
202 ata_printf(stp->atp->controller, stp->atp->unit, "%dKB/s, ",
203 stp->cap.max_speed);
197 ata_prtdev(stp->device, "<%.40s/%.8s> tape drive at ata%d as %s\n",
198 stp->device->param->model, stp->device->param->revision,
199 device_get_unit(stp->device->channel->dev),
200 (stp->device->unit == ATA_MASTER) ? "master" : "slave");
201 ata_prtdev(stp->device, "%dKB/s, ", stp->cap.max_speed);
204 printf("transfer limit %d blk%s, ",
205 stp->cap.ctl, (stp->cap.ctl > 1) ? "s" : "");
206 printf("%dKB buffer, ", (stp->cap.buffer_size * DEV_BSIZE) / 1024);
202 printf("transfer limit %d blk%s, ",
203 stp->cap.ctl, (stp->cap.ctl > 1) ? "s" : "");
204 printf("%dKB buffer, ", (stp->cap.buffer_size * DEV_BSIZE) / 1024);
207 printf("%s\n", ata_mode2str(stp->atp->controller->mode[
208 ATA_DEV(stp->atp->unit)]));
209 ata_printf(stp->atp->controller, stp->atp->unit, "Medium: ");
205 printf("%s\n", ata_mode2str(stp->device->mode));
206 ata_prtdev(stp->device, "Medium: ");
210 switch (stp->cap.medium_type) {
211 case 0x00:
212 printf("none"); break;
213 case 0x17:
214 printf("Travan 1 (400 Mbyte)"); break;
215 case 0xb6:
216 printf("Travan 4 (4 Gbyte)"); break;
217 case 0xda:

--- 13 unchanged lines hidden (view full) ---

231 if (stp->cap.ecc) printf(", ecc");
232 if (stp->cap.compress) printf(", compress");
233 if (stp->cap.blk512) printf(", 512b");
234 if (stp->cap.blk1024) printf(", 1024b");
235 if (stp->cap.blk32k) printf(", 32kb");
236 printf("\n");
237 }
238 else {
207 switch (stp->cap.medium_type) {
208 case 0x00:
209 printf("none"); break;
210 case 0x17:
211 printf("Travan 1 (400 Mbyte)"); break;
212 case 0xb6:
213 printf("Travan 4 (4 Gbyte)"); break;
214 case 0xda:

--- 13 unchanged lines hidden (view full) ---

228 if (stp->cap.ecc) printf(", ecc");
229 if (stp->cap.compress) printf(", compress");
230 if (stp->cap.blk512) printf(", 512b");
231 if (stp->cap.blk1024) printf(", 1024b");
232 if (stp->cap.blk32k) printf(", 32kb");
233 printf("\n");
234 }
235 else {
239 ata_printf(stp->atp->controller, stp->atp->unit,
240 "TAPE <%.40s> at ata%d-%s %s\n",
241 ATA_PARAM(stp->atp->controller, stp->atp->unit)->model,
242 device_get_unit(stp->atp->controller->dev),
243 (stp->atp->unit == ATA_MASTER) ? "master" : "slave",
244 ata_mode2str(stp->atp->controller->
245 mode[ATA_DEV(stp->atp->unit)]));
236 ata_prtdev(stp->device, "TAPE <%.40s> at ata%d-%s %s\n",
237 stp->device->param->model,
238 device_get_unit(stp->device->channel->dev),
239 (stp->device->unit == ATA_MASTER) ? "master" : "slave",
240 ata_mode2str(stp->device->mode));
246 }
247}
248
249static int
250astopen(dev_t dev, int flags, int fmt, struct thread *td)
251{
252 struct ast_softc *stp = dev->si_drv1;
253
254 if (!stp)
255 return ENXIO;
256
257 if (count_dev(dev) > 1)
258 return EBUSY;
259
241 }
242}
243
244static int
245astopen(dev_t dev, int flags, int fmt, struct thread *td)
246{
247 struct ast_softc *stp = dev->si_drv1;
248
249 if (!stp)
250 return ENXIO;
251
252 if (count_dev(dev) > 1)
253 return EBUSY;
254
260 atapi_test_ready(stp->atp);
255 atapi_test_ready(stp->device);
261
262 if (stp->cap.lock)
263 ast_prevent_allow(stp, 1);
264
265 if (ast_sense(stp))
256
257 if (stp->cap.lock)
258 ast_prevent_allow(stp, 1);
259
260 if (ast_sense(stp))
266 ata_printf(stp->atp->controller, stp->atp->unit,
267 "sense media type failed\n");
261 ata_prtdev(stp->device, "sense media type failed\n");
268
262
269 stp->atp->flags &= ~ATAPI_F_MEDIA_CHANGED;
263 stp->device->flags &= ~ATA_D_MEDIA_CHANGED;
270 stp->flags &= ~(F_DATA_WRITTEN | F_FM_WRITTEN);
271 ast_total = 0;
272 return 0;
273}
274
275static int
276astclose(dev_t dev, int flags, int fmt, struct thread *td)
277{

--- 12 unchanged lines hidden (view full) ---

290 if (!(minor(dev) & 0x01))
291 ast_rewind(stp);
292
293 if (stp->cap.lock && count_dev(dev) == 1)
294 ast_prevent_allow(stp, 0);
295
296 stp->flags &= F_CTL_WARN;
297#ifdef AST_DEBUG
264 stp->flags &= ~(F_DATA_WRITTEN | F_FM_WRITTEN);
265 ast_total = 0;
266 return 0;
267}
268
269static int
270astclose(dev_t dev, int flags, int fmt, struct thread *td)
271{

--- 12 unchanged lines hidden (view full) ---

284 if (!(minor(dev) & 0x01))
285 ast_rewind(stp);
286
287 if (stp->cap.lock && count_dev(dev) == 1)
288 ast_prevent_allow(stp, 0);
289
290 stp->flags &= F_CTL_WARN;
291#ifdef AST_DEBUG
298 ata_printf(stp->atp->controller, stp->atp->unit,
299 "%llu total bytes transferred\n", ast_total);
292 ata_prtdev(stp->device, "%llu total bytes transferred\n", ast_total);
300#endif
301 return 0;
302}
303
304static int
305astioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
306{
307 struct ast_softc *stp = dev->si_drv1;

--- 106 unchanged lines hidden (view full) ---

414}
415
416static void
417aststrategy(struct bio *bp)
418{
419 struct ast_softc *stp = bp->bio_dev->si_drv1;
420 int s;
421
293#endif
294 return 0;
295}
296
297static int
298astioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
299{
300 struct ast_softc *stp = dev->si_drv1;

--- 106 unchanged lines hidden (view full) ---

407}
408
409static void
410aststrategy(struct bio *bp)
411{
412 struct ast_softc *stp = bp->bio_dev->si_drv1;
413 int s;
414
422 if (stp->atp->flags & ATAPI_F_DETACHING) {
415 if (stp->device->flags & ATA_D_DETACHING) {
423 biofinish(bp, NULL, ENXIO);
424 return;
425 }
426
427 /* if it's a null transfer, return immediatly. */
428 if (bp->bio_bcount == 0) {
429 bp->bio_resid = 0;
430 biodone(bp);
431 return;
432 }
433 if (!(bp->bio_cmd == BIO_READ) && stp->flags & F_WRITEPROTECT) {
434 biofinish(bp, NULL, EPERM);
435 return;
436 }
437
438 /* check for != blocksize requests */
439 if (bp->bio_bcount % stp->blksize) {
416 biofinish(bp, NULL, ENXIO);
417 return;
418 }
419
420 /* if it's a null transfer, return immediatly. */
421 if (bp->bio_bcount == 0) {
422 bp->bio_resid = 0;
423 biodone(bp);
424 return;
425 }
426 if (!(bp->bio_cmd == BIO_READ) && stp->flags & F_WRITEPROTECT) {
427 biofinish(bp, NULL, EPERM);
428 return;
429 }
430
431 /* check for != blocksize requests */
432 if (bp->bio_bcount % stp->blksize) {
440 ata_printf(stp->atp->controller, stp->atp->unit,
441 "bad request, must be multiple of %d\n", stp->blksize);
433 ata_prtdev(stp->device, "transfers must be multiple of %d\n",
434 stp->blksize);
442 biofinish(bp, NULL, EIO);
443 return;
444 }
445
446 /* warn about transfers bigger than the device suggests */
435 biofinish(bp, NULL, EIO);
436 return;
437 }
438
439 /* warn about transfers bigger than the device suggests */
447 if (bp->bio_bcount > stp->blksize * stp->cap.ctl) {
440 if (bp->bio_bcount > stp->blksize * stp->cap.ctl) {
448 if ((stp->flags & F_CTL_WARN) == 0) {
441 if ((stp->flags & F_CTL_WARN) == 0) {
449 ata_printf(stp->atp->controller, stp->atp->unit,
450 "WARNING: CTL exceeded %ld>%d\n",
442 ata_prtdev(stp->device, "WARNING: CTL exceeded %ld>%d\n",
451 bp->bio_bcount, stp->blksize * stp->cap.ctl);
452 stp->flags |= F_CTL_WARN;
453 }
454 }
455
456 s = splbio();
457 bioq_insert_tail(&stp->queue, bp);
443 bp->bio_bcount, stp->blksize * stp->cap.ctl);
444 stp->flags |= F_CTL_WARN;
445 }
446 }
447
448 s = splbio();
449 bioq_insert_tail(&stp->queue, bp);
458 ata_start(stp->atp->controller);
450 ata_start(stp->device->channel);
459 splx(s);
460}
461
462void
451 splx(s);
452}
453
454void
463ast_start(struct atapi_softc *atp)
455ast_start(struct ata_device *atadev)
464{
456{
465 struct ast_softc *stp = atp->driver;
457 struct ast_softc *stp = atadev->driver;
466 struct bio *bp = bioq_first(&stp->queue);
467 u_int32_t blkcount;
468 int8_t ccb[16];
469
470 if (!bp)
471 return;
472
473 bzero(ccb, sizeof(ccb));

--- 8 unchanged lines hidden (view full) ---

482
483 ccb[1] = 1;
484 ccb[2] = blkcount>>16;
485 ccb[3] = blkcount>>8;
486 ccb[4] = blkcount;
487
488 devstat_start_transaction(&stp->stats);
489
458 struct bio *bp = bioq_first(&stp->queue);
459 u_int32_t blkcount;
460 int8_t ccb[16];
461
462 if (!bp)
463 return;
464
465 bzero(ccb, sizeof(ccb));

--- 8 unchanged lines hidden (view full) ---

474
475 ccb[1] = 1;
476 ccb[2] = blkcount>>16;
477 ccb[3] = blkcount>>8;
478 ccb[4] = blkcount;
479
480 devstat_start_transaction(&stp->stats);
481
490 atapi_queue_cmd(stp->atp, ccb, bp->bio_data, blkcount * stp->blksize,
482 atapi_queue_cmd(stp->device, ccb, bp->bio_data, blkcount * stp->blksize,
491 (bp->bio_cmd == BIO_READ) ? ATPR_F_READ : 0,
492 120, ast_done, bp);
493}
494
495static int
496ast_done(struct atapi_request *request)
497{
498 struct bio *bp = request->driver;
499 struct ast_softc *stp = request->device->driver;
500
501 if (request->error) {
502 bp->bio_error = request->error;
503 bp->bio_flags |= BIO_ERROR;
504 }
505 else {
506 if (!(bp->bio_cmd == BIO_READ))
507 stp->flags |= F_DATA_WRITTEN;
508 bp->bio_resid = bp->bio_bcount - request->donecount;
483 (bp->bio_cmd == BIO_READ) ? ATPR_F_READ : 0,
484 120, ast_done, bp);
485}
486
487static int
488ast_done(struct atapi_request *request)
489{
490 struct bio *bp = request->driver;
491 struct ast_softc *stp = request->device->driver;
492
493 if (request->error) {
494 bp->bio_error = request->error;
495 bp->bio_flags |= BIO_ERROR;
496 }
497 else {
498 if (!(bp->bio_cmd == BIO_READ))
499 stp->flags |= F_DATA_WRITTEN;
500 bp->bio_resid = bp->bio_bcount - request->donecount;
509 ast_total += (bp->bio_bcount - bp->bio_resid);
501 ast_total += (bp->bio_bcount - bp->bio_resid);
510 }
511 biofinish(bp, &stp->stats, 0);
512 return 0;
513}
514
515static int
516ast_mode_sense(struct ast_softc *stp, int page, void *pagebuf, int pagesize)
517{
518 int8_t ccb[16] = { ATAPI_MODE_SENSE, 0x08, page, pagesize>>8, pagesize,
519 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
520 int error;
521
502 }
503 biofinish(bp, &stp->stats, 0);
504 return 0;
505}
506
507static int
508ast_mode_sense(struct ast_softc *stp, int page, void *pagebuf, int pagesize)
509{
510 int8_t ccb[16] = { ATAPI_MODE_SENSE, 0x08, page, pagesize>>8, pagesize,
511 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
512 int error;
513
522 error = atapi_queue_cmd(stp->atp, ccb, pagebuf, pagesize, ATPR_F_READ, 10,
523 NULL, NULL);
514 error = atapi_queue_cmd(stp->device, ccb, pagebuf, pagesize, ATPR_F_READ,
515 10, NULL, NULL);
524#ifdef AST_DEBUG
525 atapi_dump("ast: mode sense ", pagebuf, pagesize);
526#endif
527 return error;
528}
529
530static int
531ast_mode_select(struct ast_softc *stp, void *pagebuf, int pagesize)
532{
533 int8_t ccb[16] = { ATAPI_MODE_SELECT, 0x10, 0, pagesize>>8, pagesize,
534 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
535
536#ifdef AST_DEBUG
516#ifdef AST_DEBUG
517 atapi_dump("ast: mode sense ", pagebuf, pagesize);
518#endif
519 return error;
520}
521
522static int
523ast_mode_select(struct ast_softc *stp, void *pagebuf, int pagesize)
524{
525 int8_t ccb[16] = { ATAPI_MODE_SELECT, 0x10, 0, pagesize>>8, pagesize,
526 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
527
528#ifdef AST_DEBUG
537 ata_printf(stp->atp->controller, stp->atp->unit,
538 "modeselect pagesize=%d\n", pagesize);
529 ata_prtdev(stp->device, "modeselect pagesize=%d\n", pagesize);
539 atapi_dump("mode select ", pagebuf, pagesize);
540#endif
530 atapi_dump("mode select ", pagebuf, pagesize);
531#endif
541 return atapi_queue_cmd(stp->atp, ccb, pagebuf, pagesize, 0, 10,
542 NULL, NULL);
532 return atapi_queue_cmd(stp->device, ccb, pagebuf, pagesize, 0,
533 10, NULL, NULL);
543}
544
545static int
546ast_write_filemark(struct ast_softc *stp, u_int8_t function)
547{
548 int8_t ccb[16] = { ATAPI_WEOF, 0x01, 0, 0, function, 0, 0, 0,
549 0, 0, 0, 0, 0, 0, 0, 0 };
550 int error;
551
552 if (stp->flags & F_ONSTREAM)
553 ccb[4] = 0x00; /* only flush buffers supported */
554 else {
555 if (function) {
556 if (stp->flags & F_FM_WRITTEN)
557 stp->flags &= ~F_DATA_WRITTEN;
558 else
559 stp->flags |= F_FM_WRITTEN;
560 }
561 }
534}
535
536static int
537ast_write_filemark(struct ast_softc *stp, u_int8_t function)
538{
539 int8_t ccb[16] = { ATAPI_WEOF, 0x01, 0, 0, function, 0, 0, 0,
540 0, 0, 0, 0, 0, 0, 0, 0 };
541 int error;
542
543 if (stp->flags & F_ONSTREAM)
544 ccb[4] = 0x00; /* only flush buffers supported */
545 else {
546 if (function) {
547 if (stp->flags & F_FM_WRITTEN)
548 stp->flags &= ~F_DATA_WRITTEN;
549 else
550 stp->flags |= F_FM_WRITTEN;
551 }
552 }
562 error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, 10, NULL, NULL);
553 error = atapi_queue_cmd(stp->device, ccb, NULL, 0, 0, 10, NULL, NULL);
563 if (error)
564 return error;
554 if (error)
555 return error;
565 return atapi_wait_dsc(stp->atp, 10*60);
556 return atapi_wait_dsc(stp->device, 10*60);
566}
567
568static int
569ast_read_position(struct ast_softc *stp, int hard,
570 struct ast_readposition *position)
571{
572 int8_t ccb[16] = { ATAPI_READ_POSITION, (hard ? 0x01 : 0), 0, 0, 0, 0, 0, 0,
573 0, 0, 0, 0, 0, 0, 0, 0 };
574 int error;
575
557}
558
559static int
560ast_read_position(struct ast_softc *stp, int hard,
561 struct ast_readposition *position)
562{
563 int8_t ccb[16] = { ATAPI_READ_POSITION, (hard ? 0x01 : 0), 0, 0, 0, 0, 0, 0,
564 0, 0, 0, 0, 0, 0, 0, 0 };
565 int error;
566
576 error = atapi_queue_cmd(stp->atp, ccb, (caddr_t)position,
567 error = atapi_queue_cmd(stp->device, ccb, (caddr_t)position,
577 sizeof(struct ast_readposition), ATPR_F_READ, 10,
578 NULL, NULL);
579 position->tape = ntohl(position->tape);
580 position->host = ntohl(position->host);
581 return error;
582}
583
584static int
585ast_space(struct ast_softc *stp, u_int8_t function, int32_t count)
586{
587 int8_t ccb[16] = { ATAPI_SPACE, function, count>>16, count>>8, count,
588 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
589
568 sizeof(struct ast_readposition), ATPR_F_READ, 10,
569 NULL, NULL);
570 position->tape = ntohl(position->tape);
571 position->host = ntohl(position->host);
572 return error;
573}
574
575static int
576ast_space(struct ast_softc *stp, u_int8_t function, int32_t count)
577{
578 int8_t ccb[16] = { ATAPI_SPACE, function, count>>16, count>>8, count,
579 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
580
590 return atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, 60*60, NULL, NULL);
581 return atapi_queue_cmd(stp->device, ccb, NULL, 0, 0, 60*60, NULL, NULL);
591}
592
593static int
594ast_locate(struct ast_softc *stp, int hard, u_int32_t pos)
595{
596 int8_t ccb[16] = { ATAPI_LOCATE, 0x01 | (hard ? 0x4 : 0), 0,
597 pos>>24, pos>>16, pos>>8, pos,
598 0, 0, 0, 0, 0, 0, 0, 0, 0 };
599 int error;
600
582}
583
584static int
585ast_locate(struct ast_softc *stp, int hard, u_int32_t pos)
586{
587 int8_t ccb[16] = { ATAPI_LOCATE, 0x01 | (hard ? 0x4 : 0), 0,
588 pos>>24, pos>>16, pos>>8, pos,
589 0, 0, 0, 0, 0, 0, 0, 0, 0 };
590 int error;
591
601 error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, 10, NULL, NULL);
592 error = atapi_queue_cmd(stp->device, ccb, NULL, 0, 0, 10, NULL, NULL);
602 if (error)
603 return error;
593 if (error)
594 return error;
604 return atapi_wait_dsc(stp->atp, 60*60);
595 return atapi_wait_dsc(stp->device, 60*60);
605}
606
607static int
608ast_prevent_allow(struct ast_softc *stp, int lock)
609{
610 int8_t ccb[16] = { ATAPI_PREVENT_ALLOW, 0, 0, 0, lock,
611 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
612
596}
597
598static int
599ast_prevent_allow(struct ast_softc *stp, int lock)
600{
601 int8_t ccb[16] = { ATAPI_PREVENT_ALLOW, 0, 0, 0, lock,
602 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
603
613 return atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0,30, NULL, NULL);
604 return atapi_queue_cmd(stp->device, ccb, NULL, 0, 0,30, NULL, NULL);
614}
615
616static int
617ast_load_unload(struct ast_softc *stp, u_int8_t function)
618{
619 int8_t ccb[16] = { ATAPI_START_STOP, 0x01, 0, 0, function, 0, 0, 0,
620 0, 0, 0, 0, 0, 0, 0, 0 };
621 int error;
622
623 if ((function & SS_EJECT) && !stp->cap.eject)
624 return 0;
605}
606
607static int
608ast_load_unload(struct ast_softc *stp, u_int8_t function)
609{
610 int8_t ccb[16] = { ATAPI_START_STOP, 0x01, 0, 0, function, 0, 0, 0,
611 0, 0, 0, 0, 0, 0, 0, 0 };
612 int error;
613
614 if ((function & SS_EJECT) && !stp->cap.eject)
615 return 0;
625 error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, 10, NULL, NULL);
616 error = atapi_queue_cmd(stp->device, ccb, NULL, 0, 0, 10, NULL, NULL);
626 if (error)
627 return error;
628 tsleep((caddr_t)&error, PRIBIO, "astlu", 1 * hz);
629 if (function == SS_EJECT)
630 return 0;
617 if (error)
618 return error;
619 tsleep((caddr_t)&error, PRIBIO, "astlu", 1 * hz);
620 if (function == SS_EJECT)
621 return 0;
631 return atapi_wait_dsc(stp->atp, 60*60);
622 return atapi_wait_dsc(stp->device, 60*60);
632}
633
634static int
635ast_rewind(struct ast_softc *stp)
636{
637 int8_t ccb[16] = { ATAPI_REZERO, 0x01, 0, 0, 0, 0, 0, 0,
638 0, 0, 0, 0, 0, 0, 0, 0 };
639 int error;
640
623}
624
625static int
626ast_rewind(struct ast_softc *stp)
627{
628 int8_t ccb[16] = { ATAPI_REZERO, 0x01, 0, 0, 0, 0, 0, 0,
629 0, 0, 0, 0, 0, 0, 0, 0 };
630 int error;
631
641 error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, 10, NULL, NULL);
632 error = atapi_queue_cmd(stp->device, ccb, NULL, 0, 0, 10, NULL, NULL);
642 if (error)
643 return error;
633 if (error)
634 return error;
644 return atapi_wait_dsc(stp->atp, 60*60);
635 return atapi_wait_dsc(stp->device, 60*60);
645}
646
647static int
648ast_erase(struct ast_softc *stp)
649{
650 int8_t ccb[16] = { ATAPI_ERASE, 3, 0, 0, 0, 0, 0, 0,
651 0, 0, 0, 0, 0, 0, 0, 0 };
652 int error;
653
654 if ((error = ast_rewind(stp)))
655 return error;
656
636}
637
638static int
639ast_erase(struct ast_softc *stp)
640{
641 int8_t ccb[16] = { ATAPI_ERASE, 3, 0, 0, 0, 0, 0, 0,
642 0, 0, 0, 0, 0, 0, 0, 0 };
643 int error;
644
645 if ((error = ast_rewind(stp)))
646 return error;
647
657 return atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, 60*60, NULL, NULL);
648 return atapi_queue_cmd(stp->device, ccb, NULL, 0, 0, 60*60, NULL, NULL);
658}
649}