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} |