Deleted Added
full compact
scsi_sa.c (58934) scsi_sa.c (59249)
1/*
1/*
2 * $FreeBSD: head/sys/cam/scsi/scsi_sa.c 58934 2000-04-02 15:24:56Z phk $
2 * $FreeBSD: head/sys/cam/scsi/scsi_sa.c 59249 2000-04-15 05:54:02Z phk $
3 *
4 * Implementation of SCSI Sequential Access Peripheral driver for CAM.
5 *
6 * Copyright (c) 1999, 2000 Matthew Jacob
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions

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

185 dev_t nr_dev;
186 dev_t er_dev;
187};
188
189struct sa_softc {
190 sa_state state;
191 sa_flags flags;
192 sa_quirks quirks;
3 *
4 * Implementation of SCSI Sequential Access Peripheral driver for CAM.
5 *
6 * Copyright (c) 1999, 2000 Matthew Jacob
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions

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

185 dev_t nr_dev;
186 dev_t er_dev;
187};
188
189struct sa_softc {
190 sa_state state;
191 sa_flags flags;
192 sa_quirks quirks;
193 struct buf_queue_head buf_queue;
193 struct bio_queue_head bio_queue;
194 int queue_count;
195 struct devstat device_stats;
196 struct sa_devs devs;
197 int blk_gran;
198 int blk_mask;
199 int blk_shift;
200 u_int32_t max_blk;
201 u_int32_t min_blk;

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

615}
616
617/*
618 * Actually translate the requested transfer into one the physical driver
619 * can understand. The transfer is described by a buf and will include
620 * only one physical transfer.
621 */
622static void
194 int queue_count;
195 struct devstat device_stats;
196 struct sa_devs devs;
197 int blk_gran;
198 int blk_mask;
199 int blk_shift;
200 u_int32_t max_blk;
201 u_int32_t min_blk;

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

615}
616
617/*
618 * Actually translate the requested transfer into one the physical driver
619 * can understand. The transfer is described by a buf and will include
620 * only one physical transfer.
621 */
622static void
623sastrategy(struct buf *bp)
623sastrategy(struct bio *bp)
624{
625 struct cam_periph *periph;
626 struct sa_softc *softc;
627 u_int unit;
628 int s;
629
624{
625 struct cam_periph *periph;
626 struct sa_softc *softc;
627 u_int unit;
628 int s;
629
630 if (SA_IS_CTRL(bp->b_dev)) {
631 bp->b_error = EINVAL;
630 if (SA_IS_CTRL(bp->bio_dev)) {
631 bp->bio_error = EINVAL;
632 goto bad;
633 }
632 goto bad;
633 }
634 unit = SAUNIT(bp->b_dev);
634 unit = SAUNIT(bp->bio_dev);
635 periph = cam_extend_get(saperiphs, unit);
636 if (periph == NULL) {
635 periph = cam_extend_get(saperiphs, unit);
636 if (periph == NULL) {
637 bp->b_error = ENXIO;
637 bp->bio_error = ENXIO;
638 goto bad;
639 }
640 softc = (struct sa_softc *)periph->softc;
641
642 s = splsoftcam();
643
644 if (softc->flags & SA_FLAG_INVALID) {
645 splx(s);
638 goto bad;
639 }
640 softc = (struct sa_softc *)periph->softc;
641
642 s = splsoftcam();
643
644 if (softc->flags & SA_FLAG_INVALID) {
645 splx(s);
646 bp->b_error = ENXIO;
646 bp->bio_error = ENXIO;
647 goto bad;
648 }
649
650 if (softc->flags & SA_FLAG_TAPE_FROZEN) {
651 splx(s);
647 goto bad;
648 }
649
650 if (softc->flags & SA_FLAG_TAPE_FROZEN) {
651 splx(s);
652 bp->b_error = EPERM;
652 bp->bio_error = EPERM;
653 goto bad;
654 }
655
656 splx(s);
657
658 /*
659 * If it's a null transfer, return immediatly
660 */
653 goto bad;
654 }
655
656 splx(s);
657
658 /*
659 * If it's a null transfer, return immediatly
660 */
661 if (bp->b_bcount == 0)
661 if (bp->bio_bcount == 0)
662 goto done;
663
664 /* valid request? */
665 if (softc->flags & SA_FLAG_FIXED) {
666 /*
667 * Fixed block device. The byte count must
668 * be a multiple of our block size.
669 */
670 if (((softc->blk_mask != ~0) &&
662 goto done;
663
664 /* valid request? */
665 if (softc->flags & SA_FLAG_FIXED) {
666 /*
667 * Fixed block device. The byte count must
668 * be a multiple of our block size.
669 */
670 if (((softc->blk_mask != ~0) &&
671 ((bp->b_bcount & softc->blk_mask) != 0)) ||
671 ((bp->bio_bcount & softc->blk_mask) != 0)) ||
672 ((softc->blk_mask == ~0) &&
672 ((softc->blk_mask == ~0) &&
673 ((bp->b_bcount % softc->min_blk) != 0))) {
673 ((bp->bio_bcount % softc->min_blk) != 0))) {
674 xpt_print_path(periph->path);
675 printf("Invalid request. Fixed block device "
676 "requests must be a multiple "
677 "of %d bytes\n", softc->min_blk);
674 xpt_print_path(periph->path);
675 printf("Invalid request. Fixed block device "
676 "requests must be a multiple "
677 "of %d bytes\n", softc->min_blk);
678 bp->b_error = EINVAL;
678 bp->bio_error = EINVAL;
679 goto bad;
680 }
679 goto bad;
680 }
681 } else if ((bp->b_bcount > softc->max_blk) ||
682 (bp->b_bcount < softc->min_blk) ||
683 (bp->b_bcount & softc->blk_mask) != 0) {
681 } else if ((bp->bio_bcount > softc->max_blk) ||
682 (bp->bio_bcount < softc->min_blk) ||
683 (bp->bio_bcount & softc->blk_mask) != 0) {
684
685 xpt_print_path(periph->path);
686 printf("Invalid request. Variable block device "
687 "requests must be ");
688 if (softc->blk_mask != 0) {
689 printf("a multiple of %d ", (0x1 << softc->blk_gran));
690 }
691 printf("between %d and %d bytes\n", softc->min_blk,
692 softc->max_blk);
684
685 xpt_print_path(periph->path);
686 printf("Invalid request. Variable block device "
687 "requests must be ");
688 if (softc->blk_mask != 0) {
689 printf("a multiple of %d ", (0x1 << softc->blk_gran));
690 }
691 printf("between %d and %d bytes\n", softc->min_blk,
692 softc->max_blk);
693 bp->b_error = EINVAL;
693 bp->bio_error = EINVAL;
694 goto bad;
695 }
696
697 /*
698 * Mask interrupts so that the device cannot be invalidated until
699 * after we are in the queue. Otherwise, we might not properly
700 * clean up one of the buffers.
701 */
702 s = splbio();
703
704 /*
705 * Place it at the end of the queue.
706 */
694 goto bad;
695 }
696
697 /*
698 * Mask interrupts so that the device cannot be invalidated until
699 * after we are in the queue. Otherwise, we might not properly
700 * clean up one of the buffers.
701 */
702 s = splbio();
703
704 /*
705 * Place it at the end of the queue.
706 */
707 bufq_insert_tail(&softc->buf_queue, bp);
707 bioq_insert_tail(&softc->bio_queue, bp);
708
709 softc->queue_count++;
710 CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("sastrategy: enqueuing a %d "
708
709 softc->queue_count++;
710 CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("sastrategy: enqueuing a %d "
711 "%s byte %s queue count now %d\n", (int) bp->b_bcount,
711 "%s byte %s queue count now %d\n", (int) bp->bio_bcount,
712 (softc->flags & SA_FLAG_FIXED)? "fixed" : "variable",
712 (softc->flags & SA_FLAG_FIXED)? "fixed" : "variable",
713 (bp->b_iocmd == BIO_READ)? "read" : "write", softc->queue_count));
713 (bp->bio_cmd == BIO_READ)? "read" : "write", softc->queue_count));
714
715 splx(s);
716
717 /*
718 * Schedule ourselves for performing the work.
719 */
720 xpt_schedule(periph, 1);
721
722 return;
723bad:
714
715 splx(s);
716
717 /*
718 * Schedule ourselves for performing the work.
719 */
720 xpt_schedule(periph, 1);
721
722 return;
723bad:
724 bp->b_ioflags |= BIO_ERROR;
724 bp->bio_flags |= BIO_ERROR;
725done:
726
727 /*
728 * Correctly set the buf to indicate a completed xfer
729 */
725done:
726
727 /*
728 * Correctly set the buf to indicate a completed xfer
729 */
730 bp->b_resid = bp->b_bcount;
730 bp->bio_resid = bp->bio_bcount;
731 biodone(bp);
732}
733
734static int
735saioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
736{
737 struct cam_periph *periph;
738 struct sa_softc *softc;

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

1216 "due to status 0x%x!\n", status);
1217 }
1218}
1219
1220static void
1221saoninvalidate(struct cam_periph *periph)
1222{
1223 struct sa_softc *softc;
731 biodone(bp);
732}
733
734static int
735saioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
736{
737 struct cam_periph *periph;
738 struct sa_softc *softc;

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

1216 "due to status 0x%x!\n", status);
1217 }
1218}
1219
1220static void
1221saoninvalidate(struct cam_periph *periph)
1222{
1223 struct sa_softc *softc;
1224 struct buf *q_bp;
1224 struct bio *q_bp;
1225 struct ccb_setasync csa;
1226 int s;
1227
1228 softc = (struct sa_softc *)periph->softc;
1229
1230 /*
1231 * De-register any async callbacks.
1232 */

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

1247 */
1248 s = splbio();
1249
1250 /*
1251 * Return all queued I/O with ENXIO.
1252 * XXX Handle any transactions queued to the card
1253 * with XPT_ABORT_CCB.
1254 */
1225 struct ccb_setasync csa;
1226 int s;
1227
1228 softc = (struct sa_softc *)periph->softc;
1229
1230 /*
1231 * De-register any async callbacks.
1232 */

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

1247 */
1248 s = splbio();
1249
1250 /*
1251 * Return all queued I/O with ENXIO.
1252 * XXX Handle any transactions queued to the card
1253 * with XPT_ABORT_CCB.
1254 */
1255 while ((q_bp = bufq_first(&softc->buf_queue)) != NULL){
1256 bufq_remove(&softc->buf_queue, q_bp);
1257 q_bp->b_resid = q_bp->b_bcount;
1258 q_bp->b_error = ENXIO;
1259 q_bp->b_ioflags |= BIO_ERROR;
1255 while ((q_bp = bioq_first(&softc->bio_queue)) != NULL){
1256 bioq_remove(&softc->bio_queue, q_bp);
1257 q_bp->bio_resid = q_bp->bio_bcount;
1258 q_bp->bio_error = ENXIO;
1259 q_bp->bio_flags |= BIO_ERROR;
1260 biodone(q_bp);
1261 }
1262 softc->queue_count = 0;
1263 splx(s);
1264
1265 xpt_print_path(periph->path);
1266 printf("lost device\n");
1267

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

1362 }
1363
1364 bzero(softc, sizeof(*softc));
1365 softc->scsi_rev = SID_ANSI_REV(&cgd->inq_data);
1366 softc->state = SA_STATE_NORMAL;
1367 softc->fileno = (daddr_t) -1;
1368 softc->blkno = (daddr_t) -1;
1369
1260 biodone(q_bp);
1261 }
1262 softc->queue_count = 0;
1263 splx(s);
1264
1265 xpt_print_path(periph->path);
1266 printf("lost device\n");
1267

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

1362 }
1363
1364 bzero(softc, sizeof(*softc));
1365 softc->scsi_rev = SID_ANSI_REV(&cgd->inq_data);
1366 softc->state = SA_STATE_NORMAL;
1367 softc->fileno = (daddr_t) -1;
1368 softc->blkno = (daddr_t) -1;
1369
1370 bufq_init(&softc->buf_queue);
1370 bioq_init(&softc->bio_queue);
1371 periph->softc = softc;
1372 cam_extend_set(saperiphs, periph->unit_number, periph);
1373
1374 /*
1375 * See if this device has any quirks.
1376 */
1377 match = cam_quirkmatch((caddr_t)&cgd->inq_data,
1378 (caddr_t)sa_quirk_table,

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

1459 softc = (struct sa_softc *)periph->softc;
1460
1461 CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("sastart"));
1462
1463 switch (softc->state) {
1464 case SA_STATE_NORMAL:
1465 {
1466 /* Pull a buffer from the queue and get going on it */
1371 periph->softc = softc;
1372 cam_extend_set(saperiphs, periph->unit_number, periph);
1373
1374 /*
1375 * See if this device has any quirks.
1376 */
1377 match = cam_quirkmatch((caddr_t)&cgd->inq_data,
1378 (caddr_t)sa_quirk_table,

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

1459 softc = (struct sa_softc *)periph->softc;
1460
1461 CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("sastart"));
1462
1463 switch (softc->state) {
1464 case SA_STATE_NORMAL:
1465 {
1466 /* Pull a buffer from the queue and get going on it */
1467 struct buf *bp;
1467 struct bio *bp;
1468 int s;
1469
1470 /*
1471 * See if there is a buf with work for us to do..
1472 */
1473 s = splbio();
1468 int s;
1469
1470 /*
1471 * See if there is a buf with work for us to do..
1472 */
1473 s = splbio();
1474 bp = bufq_first(&softc->buf_queue);
1474 bp = bioq_first(&softc->bio_queue);
1475 if (periph->immediate_priority <= periph->pinfo.priority) {
1476 CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
1477 ("queuing for immediate ccb\n"));
1478 start_ccb->ccb_h.ccb_type = SA_CCB_WAITING;
1479 SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
1480 periph_links.sle);
1481 periph->immediate_priority = CAM_PRIORITY_NONE;
1482 splx(s);
1483 wakeup(&periph->ccb_list);
1484 } else if (bp == NULL) {
1485 splx(s);
1486 xpt_release_ccb(start_ccb);
1487 } else if ((softc->flags & SA_FLAG_ERR_PENDING) != 0) {
1475 if (periph->immediate_priority <= periph->pinfo.priority) {
1476 CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
1477 ("queuing for immediate ccb\n"));
1478 start_ccb->ccb_h.ccb_type = SA_CCB_WAITING;
1479 SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
1480 periph_links.sle);
1481 periph->immediate_priority = CAM_PRIORITY_NONE;
1482 splx(s);
1483 wakeup(&periph->ccb_list);
1484 } else if (bp == NULL) {
1485 splx(s);
1486 xpt_release_ccb(start_ccb);
1487 } else if ((softc->flags & SA_FLAG_ERR_PENDING) != 0) {
1488 struct buf *done_bp;
1488 struct bio *done_bp;
1489 softc->queue_count--;
1489 softc->queue_count--;
1490 bufq_remove(&softc->buf_queue, bp);
1491 bp->b_resid = bp->b_bcount;
1492 bp->b_ioflags |= BIO_ERROR;
1490 bioq_remove(&softc->bio_queue, bp);
1491 bp->bio_resid = bp->bio_bcount;
1492 bp->bio_flags |= BIO_ERROR;
1493 if ((softc->flags & SA_FLAG_EOM_PENDING) != 0) {
1493 if ((softc->flags & SA_FLAG_EOM_PENDING) != 0) {
1494 if (bp->b_iocmd == BIO_WRITE)
1495 bp->b_error = ENOSPC;
1494 if (bp->bio_cmd == BIO_WRITE)
1495 bp->bio_error = ENOSPC;
1496 else
1496 else
1497 bp->b_error = EIO;
1497 bp->bio_error = EIO;
1498 }
1499 if ((softc->flags & SA_FLAG_EOF_PENDING) != 0) {
1498 }
1499 if ((softc->flags & SA_FLAG_EOF_PENDING) != 0) {
1500 bp->b_error = EIO;
1500 bp->bio_error = EIO;
1501 }
1502 if ((softc->flags & SA_FLAG_EIO_PENDING) != 0) {
1501 }
1502 if ((softc->flags & SA_FLAG_EIO_PENDING) != 0) {
1503 bp->b_error = EIO;
1503 bp->bio_error = EIO;
1504 }
1505 done_bp = bp;
1504 }
1505 done_bp = bp;
1506 bp = bufq_first(&softc->buf_queue);
1506 bp = bioq_first(&softc->bio_queue);
1507 /*
1508 * Only if we have no other buffers queued up
1509 * do we clear the pending error flag.
1510 */
1511 if (bp == NULL)
1512 softc->flags &= ~SA_FLAG_ERR_PENDING;
1513 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
1514 ("sastart- ERR_PENDING now 0x%x, bp is %sNULL, "
1515 "%d more buffers queued up\n",
1516 (softc->flags & SA_FLAG_ERR_PENDING),
1517 (bp != NULL)? "not " : " ", softc->queue_count));
1518 splx(s);
1519 xpt_release_ccb(start_ccb);
1520 biodone(done_bp);
1521 } else {
1522 u_int32_t length;
1523
1507 /*
1508 * Only if we have no other buffers queued up
1509 * do we clear the pending error flag.
1510 */
1511 if (bp == NULL)
1512 softc->flags &= ~SA_FLAG_ERR_PENDING;
1513 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
1514 ("sastart- ERR_PENDING now 0x%x, bp is %sNULL, "
1515 "%d more buffers queued up\n",
1516 (softc->flags & SA_FLAG_ERR_PENDING),
1517 (bp != NULL)? "not " : " ", softc->queue_count));
1518 splx(s);
1519 xpt_release_ccb(start_ccb);
1520 biodone(done_bp);
1521 } else {
1522 u_int32_t length;
1523
1524 bufq_remove(&softc->buf_queue, bp);
1524 bioq_remove(&softc->bio_queue, bp);
1525 softc->queue_count--;
1526
1527 if ((softc->flags & SA_FLAG_FIXED) != 0) {
1528 if (softc->blk_shift != 0) {
1529 length =
1525 softc->queue_count--;
1526
1527 if ((softc->flags & SA_FLAG_FIXED) != 0) {
1528 if (softc->blk_shift != 0) {
1529 length =
1530 bp->b_bcount >> softc->blk_shift;
1530 bp->bio_bcount >> softc->blk_shift;
1531 } else if (softc->media_blksize != 0) {
1532 length =
1531 } else if (softc->media_blksize != 0) {
1532 length =
1533 bp->b_bcount / softc->media_blksize;
1533 bp->bio_bcount / softc->media_blksize;
1534 } else {
1534 } else {
1535 bp->b_error = EIO;
1535 bp->bio_error = EIO;
1536 xpt_print_path(periph->path);
1537 printf("zero blocksize for "
1538 "FIXED length writes?\n");
1539 splx(s);
1540 biodone(bp);
1541 break;
1542 }
1543 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
1544 ("Fixed Record Count is %d\n", length));
1545 } else {
1536 xpt_print_path(periph->path);
1537 printf("zero blocksize for "
1538 "FIXED length writes?\n");
1539 splx(s);
1540 biodone(bp);
1541 break;
1542 }
1543 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
1544 ("Fixed Record Count is %d\n", length));
1545 } else {
1546 length = bp->b_bcount;
1546 length = bp->bio_bcount;
1547 CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO,
1548 ("Variable Record Count is %d\n", length));
1549 }
1550 devstat_start_transaction(&softc->device_stats);
1551 /*
1552 * Some people have theorized that we should
1553 * suppress illegal length indication if we are
1554 * running in variable block mode so that we don't

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

1563 *
1564 * I believe that this is a non-issue. If user apps
1565 * don't adjust their read size to match our record
1566 * size, that's just life. Anyway, the typical usage
1567 * would be to issue, e.g., 64KB reads and occasionally
1568 * have to do deal with 512 byte or 1KB intermediate
1569 * records.
1570 */
1547 CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO,
1548 ("Variable Record Count is %d\n", length));
1549 }
1550 devstat_start_transaction(&softc->device_stats);
1551 /*
1552 * Some people have theorized that we should
1553 * suppress illegal length indication if we are
1554 * running in variable block mode so that we don't

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

1563 *
1564 * I believe that this is a non-issue. If user apps
1565 * don't adjust their read size to match our record
1566 * size, that's just life. Anyway, the typical usage
1567 * would be to issue, e.g., 64KB reads and occasionally
1568 * have to do deal with 512 byte or 1KB intermediate
1569 * records.
1570 */
1571 softc->dsreg = (bp->b_iocmd == BIO_READ)?
1571 softc->dsreg = (bp->bio_cmd == BIO_READ)?
1572 MTIO_DSREG_RD : MTIO_DSREG_WR;
1573 scsi_sa_read_write(&start_ccb->csio, 0, sadone,
1572 MTIO_DSREG_RD : MTIO_DSREG_WR;
1573 scsi_sa_read_write(&start_ccb->csio, 0, sadone,
1574 MSG_SIMPLE_Q_TAG, (bp->b_iocmd == BIO_READ),
1574 MSG_SIMPLE_Q_TAG, (bp->bio_cmd == BIO_READ),
1575 FALSE, (softc->flags & SA_FLAG_FIXED) != 0,
1575 FALSE, (softc->flags & SA_FLAG_FIXED) != 0,
1576 length, bp->b_data, bp->b_bcount, SSD_FULL_SIZE,
1576 length, bp->bio_data, bp->bio_bcount, SSD_FULL_SIZE,
1577 120 * 60 * 1000);
1578 start_ccb->ccb_h.ccb_type = SA_CCB_BUFFER_IO;
1579 start_ccb->ccb_h.ccb_bp = bp;
1577 120 * 60 * 1000);
1578 start_ccb->ccb_h.ccb_type = SA_CCB_BUFFER_IO;
1579 start_ccb->ccb_h.ccb_bp = bp;
1580 bp = bufq_first(&softc->buf_queue);
1580 bp = bioq_first(&softc->bio_queue);
1581 splx(s);
1582 xpt_action(start_ccb);
1583 }
1584
1585 if (bp != NULL) {
1586 /* Have more work to do, so ensure we stay scheduled */
1587 xpt_schedule(periph, 1);
1588 }

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

1602 struct sa_softc *softc;
1603 struct ccb_scsiio *csio;
1604
1605 softc = (struct sa_softc *)periph->softc;
1606 csio = &done_ccb->csio;
1607 switch (csio->ccb_h.ccb_type) {
1608 case SA_CCB_BUFFER_IO:
1609 {
1581 splx(s);
1582 xpt_action(start_ccb);
1583 }
1584
1585 if (bp != NULL) {
1586 /* Have more work to do, so ensure we stay scheduled */
1587 xpt_schedule(periph, 1);
1588 }

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

1602 struct sa_softc *softc;
1603 struct ccb_scsiio *csio;
1604
1605 softc = (struct sa_softc *)periph->softc;
1606 csio = &done_ccb->csio;
1607 switch (csio->ccb_h.ccb_type) {
1608 case SA_CCB_BUFFER_IO:
1609 {
1610 struct buf *bp;
1610 struct bio *bp;
1611 int error;
1612
1613 softc->dsreg = MTIO_DSREG_REST;
1611 int error;
1612
1613 softc->dsreg = MTIO_DSREG_REST;
1614 bp = (struct buf *)done_ccb->ccb_h.ccb_bp;
1614 bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
1615 error = 0;
1616 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1617 if ((error = saerror(done_ccb, 0, 0)) == ERESTART) {
1618 /*
1619 * A retry was scheduled, so just return.
1620 */
1621 return;
1622 }
1623 }
1624
1625 if (error == EIO) {
1626 int s;
1615 error = 0;
1616 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1617 if ((error = saerror(done_ccb, 0, 0)) == ERESTART) {
1618 /*
1619 * A retry was scheduled, so just return.
1620 */
1621 return;
1622 }
1623 }
1624
1625 if (error == EIO) {
1626 int s;
1627 struct buf *q_bp;
1627 struct bio *q_bp;
1628
1629 /*
1630 * Catastrophic error. Mark the tape as frozen
1631 * (we no longer know tape position).
1632 *
1633 * Return all queued I/O with EIO, and unfreeze
1634 * our queue so that future transactions that
1635 * attempt to fix this problem can get to the
1636 * device.
1637 *
1638 */
1639
1640 s = splbio();
1641 softc->flags |= SA_FLAG_TAPE_FROZEN;
1628
1629 /*
1630 * Catastrophic error. Mark the tape as frozen
1631 * (we no longer know tape position).
1632 *
1633 * Return all queued I/O with EIO, and unfreeze
1634 * our queue so that future transactions that
1635 * attempt to fix this problem can get to the
1636 * device.
1637 *
1638 */
1639
1640 s = splbio();
1641 softc->flags |= SA_FLAG_TAPE_FROZEN;
1642 while ((q_bp = bufq_first(&softc->buf_queue)) != NULL) {
1643 bufq_remove(&softc->buf_queue, q_bp);
1644 q_bp->b_resid = q_bp->b_bcount;
1645 q_bp->b_error = EIO;
1646 q_bp->b_ioflags |= BIO_ERROR;
1642 while ((q_bp = bioq_first(&softc->bio_queue)) != NULL) {
1643 bioq_remove(&softc->bio_queue, q_bp);
1644 q_bp->bio_resid = q_bp->bio_bcount;
1645 q_bp->bio_error = EIO;
1646 q_bp->bio_flags |= BIO_ERROR;
1647 biodone(q_bp);
1648 }
1649 splx(s);
1650 }
1651 if (error != 0) {
1647 biodone(q_bp);
1648 }
1649 splx(s);
1650 }
1651 if (error != 0) {
1652 bp->b_resid = bp->b_bcount;
1653 bp->b_error = error;
1654 bp->b_ioflags |= BIO_ERROR;
1652 bp->bio_resid = bp->bio_bcount;
1653 bp->bio_error = error;
1654 bp->bio_flags |= BIO_ERROR;
1655 /*
1656 * In the error case, position is updated in saerror.
1657 */
1658 } else {
1655 /*
1656 * In the error case, position is updated in saerror.
1657 */
1658 } else {
1659 bp->b_resid = csio->resid;
1660 bp->b_error = 0;
1659 bp->bio_resid = csio->resid;
1660 bp->bio_error = 0;
1661 if (csio->resid != 0) {
1661 if (csio->resid != 0) {
1662 bp->b_ioflags |= BIO_ERROR;
1662 bp->bio_flags |= BIO_ERROR;
1663 }
1663 }
1664 if (bp->b_iocmd == BIO_WRITE) {
1664 if (bp->bio_cmd == BIO_WRITE) {
1665 softc->flags |= SA_FLAG_TAPE_WRITTEN;
1666 softc->filemarks = 0;
1667 }
1668 if (softc->blkno != (daddr_t) -1) {
1669 if ((softc->flags & SA_FLAG_FIXED) != 0) {
1670 u_int32_t l;
1671 if (softc->blk_shift != 0) {
1665 softc->flags |= SA_FLAG_TAPE_WRITTEN;
1666 softc->filemarks = 0;
1667 }
1668 if (softc->blkno != (daddr_t) -1) {
1669 if ((softc->flags & SA_FLAG_FIXED) != 0) {
1670 u_int32_t l;
1671 if (softc->blk_shift != 0) {
1672 l = bp->b_bcount >>
1672 l = bp->bio_bcount >>
1673 softc->blk_shift;
1674 } else {
1673 softc->blk_shift;
1674 } else {
1675 l = bp->b_bcount /
1675 l = bp->bio_bcount /
1676 softc->media_blksize;
1677 }
1678 softc->blkno += (daddr_t) l;
1679 } else {
1680 softc->blkno++;
1681 }
1682 }
1683 }
1684 /*
1685 * If we had an error (immediate or pending),
1686 * release the device queue now.
1687 */
1688 if (error || (softc->flags & SA_FLAG_ERR_PENDING))
1689 cam_release_devq(done_ccb->ccb_h.path, 0, 0, 0, 0);
1690#ifdef CAMDEBUG
1676 softc->media_blksize;
1677 }
1678 softc->blkno += (daddr_t) l;
1679 } else {
1680 softc->blkno++;
1681 }
1682 }
1683 }
1684 /*
1685 * If we had an error (immediate or pending),
1686 * release the device queue now.
1687 */
1688 if (error || (softc->flags & SA_FLAG_ERR_PENDING))
1689 cam_release_devq(done_ccb->ccb_h.path, 0, 0, 0, 0);
1690#ifdef CAMDEBUG
1691 if (error || bp->b_resid) {
1691 if (error || bp->bio_resid) {
1692 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
1693 ("error %d resid %ld count %ld\n", error,
1692 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
1693 ("error %d resid %ld count %ld\n", error,
1694 bp->b_resid, bp->b_bcount));
1694 bp->bio_resid, bp->bio_bcount));
1695 }
1696#endif
1695 }
1696#endif
1697 devstat_end_transaction_buf(&softc->device_stats, bp);
1697 devstat_end_transaction_bio(&softc->device_stats, bp);
1698 biodone(bp);
1699 break;
1700 }
1701 case SA_CCB_WAITING:
1702 {
1703 /* Caller will release the CCB */
1704 wakeup(&done_ccb->ccb_h.cbfcnp);
1705 return;

--- 1735 unchanged lines hidden ---
1698 biodone(bp);
1699 break;
1700 }
1701 case SA_CCB_WAITING:
1702 {
1703 /* Caller will release the CCB */
1704 wakeup(&done_ccb->ccb_h.cbfcnp);
1705 return;

--- 1735 unchanged lines hidden ---