| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: st.c,v 1.235 2019/02/03 03:19:28 mrg Exp $ */ | | 1 | /* $NetBSD: st.c,v 1.236 2019/02/12 13:43:40 kardel Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Charles M. Hannum. | | 8 | * by Charles M. Hannum. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -40,27 +40,27 @@ | | | @@ -40,27 +40,27 @@ |
40 | * organisations permission to use or modify this software. | | 40 | * organisations permission to use or modify this software. |
41 | * | | 41 | * |
42 | * TFS supplies this software to be publicly redistributed | | 42 | * TFS supplies this software to be publicly redistributed |
43 | * on the understanding that TFS is not responsible for the correct | | 43 | * on the understanding that TFS is not responsible for the correct |
44 | * functioning of this software in any circumstances. | | 44 | * functioning of this software in any circumstances. |
45 | * | | 45 | * |
46 | * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 | | 46 | * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 |
47 | * major changes by Julian Elischer (julian@jules.dialix.oz.au) May 1993 | | 47 | * major changes by Julian Elischer (julian@jules.dialix.oz.au) May 1993 |
48 | * | | 48 | * |
49 | * A lot of rewhacking done by mjacob (mjacob@nas.nasa.gov). | | 49 | * A lot of rewhacking done by mjacob (mjacob@nas.nasa.gov). |
50 | */ | | 50 | */ |
51 | | | 51 | |
52 | #include <sys/cdefs.h> | | 52 | #include <sys/cdefs.h> |
53 | __KERNEL_RCSID(0, "$NetBSD: st.c,v 1.235 2019/02/03 03:19:28 mrg Exp $"); | | 53 | __KERNEL_RCSID(0, "$NetBSD: st.c,v 1.236 2019/02/12 13:43:40 kardel Exp $"); |
54 | | | 54 | |
55 | #ifdef _KERNEL_OPT | | 55 | #ifdef _KERNEL_OPT |
56 | #include "opt_scsi.h" | | 56 | #include "opt_scsi.h" |
57 | #endif | | 57 | #endif |
58 | | | 58 | |
59 | #include <sys/param.h> | | 59 | #include <sys/param.h> |
60 | #include <sys/systm.h> | | 60 | #include <sys/systm.h> |
61 | #include <sys/fcntl.h> | | 61 | #include <sys/fcntl.h> |
62 | #include <sys/errno.h> | | 62 | #include <sys/errno.h> |
63 | #include <sys/ioctl.h> | | 63 | #include <sys/ioctl.h> |
64 | #include <sys/malloc.h> | | 64 | #include <sys/malloc.h> |
65 | #include <sys/buf.h> | | 65 | #include <sys/buf.h> |
66 | #include <sys/bufq.h> | | 66 | #include <sys/bufq.h> |
| @@ -605,28 +605,50 @@ stopen(dev_t dev, int flags, int mode, s | | | @@ -605,28 +605,50 @@ stopen(dev_t dev, int flags, int mode, s |
605 | error = scsipi_test_unit_ready(periph, sflags); | | 605 | error = scsipi_test_unit_ready(periph, sflags); |
606 | if (error == 0 || stmode == CTRL_MODE) | | 606 | if (error == 0 || stmode == CTRL_MODE) |
607 | break; | | 607 | break; |
608 | | | 608 | |
609 | /* | | 609 | /* |
610 | * We had an error. | | 610 | * We had an error. |
611 | * | | 611 | * |
612 | * If we're already mounted or we aren't configured for | | 612 | * If we're already mounted or we aren't configured for |
613 | * a mount delay, or the error isn't a NOT READY error, | | 613 | * a mount delay, or the error isn't a NOT READY error, |
614 | * skip to the error exit now. | | 614 | * skip to the error exit now. |
615 | */ | | 615 | */ |
616 | if ((st->flags & ST_MOUNTED) || ST_MOUNT_DELAY == 0 || | | 616 | if ((st->flags & ST_MOUNTED) || ST_MOUNT_DELAY == 0 || |
617 | (st->mt_key != SKEY_NOT_READY)) { | | 617 | (st->mt_key != SKEY_NOT_READY)) { |
618 | device_printf(st->sc_dev, "mount error (key=%d)\n", | | 618 | device_printf(st->sc_dev, |
619 | st->mt_key); | | 619 | "mount error (sense key=%d) - " |
| | | 620 | "terminating mount session\n", |
| | | 621 | st->mt_key); |
| | | 622 | /* |
| | | 623 | * the following should not trigger unless |
| | | 624 | * something serious happened while the device |
| | | 625 | * was open (PREVENT MEDIUM REMOVAL in effect) |
| | | 626 | */ |
| | | 627 | if (st->flags & ST_WRITTEN && |
| | | 628 | st->mt_key == SKEY_UNIT_ATTENTION) { |
| | | 629 | /* |
| | | 630 | * device / media state may have changed |
| | | 631 | * refrain from writing missing file marks |
| | | 632 | * onto potentially newly inserted/formatted |
| | | 633 | * media (e. g. emergency EJECT/RESET/etc.) |
| | | 634 | */ |
| | | 635 | st->flags &= ~(ST_WRITTEN|ST_FM_WRITTEN); |
| | | 636 | |
| | | 637 | device_printf(st->sc_dev, |
| | | 638 | "CAUTION: file marks/data may be missing" |
| | | 639 | " - ASC = 0x%02x, ASCQ = 0x%02x\n", |
| | | 640 | st->asc, st->ascq); |
| | | 641 | } |
620 | goto bad; | | 642 | goto bad; |
621 | } | | 643 | } |
622 | | | 644 | |
623 | /* clear any latched errors. */ | | 645 | /* clear any latched errors. */ |
624 | st->mt_resid = 0; | | 646 | st->mt_resid = 0; |
625 | st->mt_erreg = 0; | | 647 | st->mt_erreg = 0; |
626 | st->asc = 0; | | 648 | st->asc = 0; |
627 | st->ascq = 0; | | 649 | st->ascq = 0; |
628 | | | 650 | |
629 | /* | | 651 | /* |
630 | * Fake that we have the device open so | | 652 | * Fake that we have the device open so |
631 | * we block other apps from getting in. | | 653 | * we block other apps from getting in. |
632 | */ | | 654 | */ |
| @@ -717,35 +739,50 @@ stclose(dev_t dev, int flags, int mode, | | | @@ -717,35 +739,50 @@ stclose(dev_t dev, int flags, int mode, |
717 | * | | 739 | * |
718 | * This is for SUN compatibility. Actually, the Sun way of | | 740 | * This is for SUN compatibility. Actually, the Sun way of |
719 | * things is to: | | 741 | * things is to: |
720 | * | | 742 | * |
721 | * only write filemarks if there are fmks to be written and | | 743 | * only write filemarks if there are fmks to be written and |
722 | * - open for write (possibly read/write) | | 744 | * - open for write (possibly read/write) |
723 | * - the last operation was a write | | 745 | * - the last operation was a write |
724 | * or: | | 746 | * or: |
725 | * - opened for wronly | | 747 | * - opened for wronly |
726 | * - no data was written (including filemarks) | | 748 | * - no data was written (including filemarks) |
727 | */ | | 749 | */ |
728 | | | 750 | |
729 | stxx = st->flags & (ST_WRITTEN | ST_FM_WRITTEN); | | 751 | stxx = st->flags & (ST_WRITTEN | ST_FM_WRITTEN); |
730 | if (((flags & FWRITE) && stxx == ST_WRITTEN) || | | 752 | if ((flags & FWRITE) != 0) { |
731 | ((flags & O_ACCMODE) == FWRITE && stxx == 0)) { | | 753 | int nm = 0; |
732 | int nm; | | 754 | #ifdef ST_SUNCOMPAT |
| | | 755 | /* |
| | | 756 | * on request only |
| | | 757 | * original compat code has not been working |
| | | 758 | * since ~1998 |
| | | 759 | */ |
| | | 760 | if ((flags & O_ACCMODE) == FWRITE && (stxx == 0)) { |
| | | 761 | st->flags |= ST_WRITTEN; |
| | | 762 | SC_DEBUG(st->sc_periph, SCSIPI_DB3, |
| | | 763 | ("SUN compatibility: write FM(s) at close\n")); |
| | | 764 | } |
| | | 765 | #endif |
733 | error = st_check_eod(st, FALSE, &nm, 0); | | 766 | error = st_check_eod(st, FALSE, &nm, 0); |
| | | 767 | SC_DEBUG(st->sc_periph, SCSIPI_DB3, |
| | | 768 | ("wrote %d FM(s) at close error=%d\n", nm, error)); |
734 | } | | 769 | } |
735 | | | 770 | |
736 | /* Allow robots to eject tape if needed. */ | | 771 | /* Allow robots to eject tape if needed. */ |
737 | scsipi_prevent(periph, SPAMR_ALLOW, | | 772 | if (!(st->quirks & ST_Q_NOPREVENT)) { |
738 | XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_NOT_READY); | | 773 | scsipi_prevent(periph, SPAMR_ALLOW, |
| | | 774 | XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_NOT_READY); |
| | | 775 | } |
739 | | | 776 | |
740 | switch (STMODE(dev)) { | | 777 | switch (STMODE(dev)) { |
741 | case NORMAL_MODE: | | 778 | case NORMAL_MODE: |
742 | st_unmount(st, NOEJECT); | | 779 | st_unmount(st, NOEJECT); |
743 | break; | | 780 | break; |
744 | case NOREW_MODE: | | 781 | case NOREW_MODE: |
745 | case CTRL_MODE: | | 782 | case CTRL_MODE: |
746 | /* | | 783 | /* |
747 | * Leave mounted unless media seems to have been removed. | | 784 | * Leave mounted unless media seems to have been removed. |
748 | * | | 785 | * |
749 | * Otherwise, if we're to terminate a tape with more than one | | 786 | * Otherwise, if we're to terminate a tape with more than one |
750 | * filemark [ and because we're not rewinding here ], backspace | | 787 | * filemark [ and because we're not rewinding here ], backspace |
751 | * one filemark so that later appends will see an unbroken | | 788 | * one filemark so that later appends will see an unbroken |
| @@ -759,38 +796,48 @@ stclose(dev_t dev, int flags, int mode, | | | @@ -759,38 +796,48 @@ stclose(dev_t dev, int flags, int mode, |
759 | /* | | 796 | /* |
760 | * ST_WRITTEN was preserved from above. | | 797 | * ST_WRITTEN was preserved from above. |
761 | * | | 798 | * |
762 | * All we need to know here is: | | 799 | * All we need to know here is: |
763 | * | | 800 | * |
764 | * Were we writing this tape and was the last | | 801 | * Were we writing this tape and was the last |
765 | * operation a write? | | 802 | * operation a write? |
766 | * | | 803 | * |
767 | * Are there supposed to be 2FM at EOD? | | 804 | * Are there supposed to be 2FM at EOD? |
768 | * | | 805 | * |
769 | * If both statements are true, then we backspace | | 806 | * If both statements are true, then we backspace |
770 | * one filemark. | | 807 | * one filemark. |
771 | */ | | 808 | */ |
| | | 809 | stxx &= ~ST_FM_WRITTEN; |
772 | stxx |= (st->flags & ST_2FM_AT_EOD); | | 810 | stxx |= (st->flags & ST_2FM_AT_EOD); |
773 | if ((flags & FWRITE) != 0 && | | 811 | if ((flags & FWRITE) != 0 && |
774 | (stxx == (ST_2FM_AT_EOD|ST_WRITTEN))) { | | 812 | (stxx == (ST_2FM_AT_EOD|ST_WRITTEN))) { |
775 | error = st_space(st, -1, SP_FILEMARKS, 0); | | 813 | error = st_space(st, -1, SP_FILEMARKS, 0); |
| | | 814 | SC_DEBUG(st->sc_periph, SCSIPI_DB3, ("st_space(-1) error=%d\n", error)); |
| | | 815 | } else { |
| | | 816 | SC_DEBUG(st->sc_periph, SCSIPI_DB3, ("no backspacing - flags = 0x%x, stxx=0x%x, st->flags=0x%x\n", flags, stxx, st->flags)); |
776 | } | | 817 | } |
| | | 818 | } else { |
| | | 819 | SC_DEBUG(st->sc_periph, SCSIPI_DB3, ("error %d from st_check_eod\n", error)); |
777 | } | | 820 | } |
| | | 821 | |
778 | break; | | 822 | break; |
779 | case EJECT_MODE: | | 823 | case EJECT_MODE: |
780 | st_unmount(st, EJECT); | | 824 | st_unmount(st, EJECT); |
781 | break; | | 825 | break; |
782 | } | | 826 | } |
783 | | | 827 | |
| | | 828 | KASSERTMSG((st->flags & ST_WRITTEN) == 0, |
| | | 829 | "pending ST_WRITTEN flag NOT cleared (flags=0x%x)", st->flags); |
| | | 830 | |
784 | scsipi_wait_drain(periph); | | 831 | scsipi_wait_drain(periph); |
785 | | | 832 | |
786 | scsipi_adapter_delref(adapt); | | 833 | scsipi_adapter_delref(adapt); |
787 | periph->periph_flags &= ~PERIPH_OPEN; | | 834 | periph->periph_flags &= ~PERIPH_OPEN; |
788 | | | 835 | |
789 | return error; | | 836 | return error; |
790 | } | | 837 | } |
791 | | | 838 | |
792 | /* | | 839 | /* |
793 | * Start a new mount session. | | 840 | * Start a new mount session. |
794 | * Copy in all the default parameters from the selected device mode. | | 841 | * Copy in all the default parameters from the selected device mode. |
795 | * and try guess any that seem to be defaulted. | | 842 | * and try guess any that seem to be defaulted. |
796 | */ | | 843 | */ |
| @@ -898,27 +945,27 @@ static void | | | @@ -898,27 +945,27 @@ static void |
898 | st_unmount(struct st_softc *st, boolean eject) | | 945 | st_unmount(struct st_softc *st, boolean eject) |
899 | { | | 946 | { |
900 | struct scsipi_periph *periph = st->sc_periph; | | 947 | struct scsipi_periph *periph = st->sc_periph; |
901 | int nmarks; | | 948 | int nmarks; |
902 | | | 949 | |
903 | if ((st->flags & ST_MOUNTED) == 0) | | 950 | if ((st->flags & ST_MOUNTED) == 0) |
904 | return; | | 951 | return; |
905 | SC_DEBUG(periph, SCSIPI_DB1, ("unmounting\n")); | | 952 | SC_DEBUG(periph, SCSIPI_DB1, ("unmounting\n")); |
906 | st_check_eod(st, FALSE, &nmarks, XS_CTL_IGNORE_NOT_READY); | | 953 | st_check_eod(st, FALSE, &nmarks, XS_CTL_IGNORE_NOT_READY); |
907 | st_rewind(st, 0, XS_CTL_IGNORE_NOT_READY); | | 954 | st_rewind(st, 0, XS_CTL_IGNORE_NOT_READY); |
908 | | | 955 | |
909 | /* | | 956 | /* |
910 | * Section 9.3.3 of the SCSI specs states that a device shall return | | 957 | * Section 9.3.3 of the SCSI specs states that a device shall return |
911 | * the density value specified in the last succesfull MODE SELECT | | 958 | * the density value specified in the last successful MODE SELECT |
912 | * after an unload operation, in case it is not able to | | 959 | * after an unload operation, in case it is not able to |
913 | * automatically determine the density of the new medium. | | 960 | * automatically determine the density of the new medium. |
914 | * | | 961 | * |
915 | * So we instruct the device to use the default density, which will | | 962 | * So we instruct the device to use the default density, which will |
916 | * prevent the use of stale density values (in particular, | | 963 | * prevent the use of stale density values (in particular, |
917 | * in st_touch_tape(). | | 964 | * in st_touch_tape(). |
918 | */ | | 965 | */ |
919 | st->density = 0; | | 966 | st->density = 0; |
920 | if (st->ops(st, ST_OPS_MODESELECT, 0) != 0) { | | 967 | if (st->ops(st, ST_OPS_MODESELECT, 0) != 0) { |
921 | aprint_error_dev(st->sc_dev, | | 968 | aprint_error_dev(st->sc_dev, |
922 | "WARNING: cannot revert to default density\n"); | | 969 | "WARNING: cannot revert to default density\n"); |
923 | } | | 970 | } |
924 | | | 971 | |
| @@ -1056,26 +1103,28 @@ ststrategy(struct buf *bp) | | | @@ -1056,26 +1103,28 @@ ststrategy(struct buf *bp) |
1056 | struct st_softc *st = device_lookup_private(&st_cd, STUNIT(bp->b_dev)); | | 1103 | struct st_softc *st = device_lookup_private(&st_cd, STUNIT(bp->b_dev)); |
1057 | struct scsipi_periph *periph = st->sc_periph; | | 1104 | struct scsipi_periph *periph = st->sc_periph; |
1058 | struct scsipi_channel *chan = periph->periph_channel; | | 1105 | struct scsipi_channel *chan = periph->periph_channel; |
1059 | | | 1106 | |
1060 | SC_DEBUG(periph, SCSIPI_DB1, | | 1107 | SC_DEBUG(periph, SCSIPI_DB1, |
1061 | ("ststrategy %d bytes @ blk %" PRId64 "\n", bp->b_bcount, | | 1108 | ("ststrategy %d bytes @ blk %" PRId64 "\n", bp->b_bcount, |
1062 | bp->b_blkno)); | | 1109 | bp->b_blkno)); |
1063 | /* If it's a null transfer, return immediately */ | | 1110 | /* If it's a null transfer, return immediately */ |
1064 | if (bp->b_bcount == 0) | | 1111 | if (bp->b_bcount == 0) |
1065 | goto abort; | | 1112 | goto abort; |
1066 | | | 1113 | |
1067 | /* If offset is negative, error */ | | 1114 | /* If offset is negative, error */ |
1068 | if (bp->b_blkno < 0) { | | 1115 | if (bp->b_blkno < 0) { |
| | | 1116 | SC_DEBUG(periph, SCSIPI_DB3, |
| | | 1117 | ("EINVAL: ststrategy negative blockcount %ld\n", bp->b_blkno)); |
1069 | bp->b_error = EINVAL; | | 1118 | bp->b_error = EINVAL; |
1070 | goto abort; | | 1119 | goto abort; |
1071 | } | | 1120 | } |
1072 | | | 1121 | |
1073 | /* Odd sized request on fixed drives are verboten */ | | 1122 | /* Odd sized request on fixed drives are verboten */ |
1074 | if (st->flags & ST_FIXEDBLOCKS) { | | 1123 | if (st->flags & ST_FIXEDBLOCKS) { |
1075 | if (bp->b_bcount % st->blksize) { | | 1124 | if (bp->b_bcount % st->blksize) { |
1076 | aprint_error_dev(st->sc_dev, "bad request, must be multiple of %d\n", | | 1125 | aprint_error_dev(st->sc_dev, "bad request, must be multiple of %d\n", |
1077 | st->blksize); | | 1126 | st->blksize); |
1078 | bp->b_error = EIO; | | 1127 | bp->b_error = EIO; |
1079 | goto abort; | | 1128 | goto abort; |
1080 | } | | 1129 | } |
1081 | } | | 1130 | } |
| @@ -1353,37 +1402,45 @@ stdone(struct scsipi_xfer *xs, int error | | | @@ -1353,37 +1402,45 @@ stdone(struct scsipi_xfer *xs, int error |
1353 | mutex_exit(&st->sc_iolock); | | 1402 | mutex_exit(&st->sc_iolock); |
1354 | | | 1403 | |
1355 | rnd_add_uint32(&st->rnd_source, bp->b_blkno); | | 1404 | rnd_add_uint32(&st->rnd_source, bp->b_blkno); |
1356 | | | 1405 | |
1357 | biodone(bp); | | 1406 | biodone(bp); |
1358 | } | | 1407 | } |
1359 | } | | 1408 | } |
1360 | | | 1409 | |
1361 | static int | | 1410 | static int |
1362 | stread(dev_t dev, struct uio *uio, int iomode) | | 1411 | stread(dev_t dev, struct uio *uio, int iomode) |
1363 | { | | 1412 | { |
1364 | struct st_softc *st = device_lookup_private(&st_cd, STUNIT(dev)); | | 1413 | struct st_softc *st = device_lookup_private(&st_cd, STUNIT(dev)); |
1365 | | | 1414 | |
1366 | return physio(ststrategy, NULL, dev, B_READ, | | 1415 | int r = physio(ststrategy, NULL, dev, B_READ, |
1367 | st->sc_periph->periph_channel->chan_adapter->adapt_minphys, uio); | | 1416 | st->sc_periph->periph_channel->chan_adapter->adapt_minphys, uio); |
| | | 1417 | |
| | | 1418 | SC_DEBUG(st->sc_periph, SCSIPI_DB1, ("[stread: result=%d]\n", r)); |
| | | 1419 | |
| | | 1420 | return r; |
1368 | } | | 1421 | } |
1369 | | | 1422 | |
1370 | static int | | 1423 | static int |
1371 | stwrite(dev_t dev, struct uio *uio, int iomode) | | 1424 | stwrite(dev_t dev, struct uio *uio, int iomode) |
1372 | { | | 1425 | { |
1373 | struct st_softc *st = device_lookup_private(&st_cd, STUNIT(dev)); | | 1426 | struct st_softc *st = device_lookup_private(&st_cd, STUNIT(dev)); |
1374 | | | 1427 | |
1375 | return physio(ststrategy, NULL, dev, B_WRITE, | | 1428 | int r = physio(ststrategy, NULL, dev, B_WRITE, |
1376 | st->sc_periph->periph_channel->chan_adapter->adapt_minphys, uio); | | 1429 | st->sc_periph->periph_channel->chan_adapter->adapt_minphys, uio); |
| | | 1430 | |
| | | 1431 | SC_DEBUG(st->sc_periph, SCSIPI_DB1, ("[stwrite: result=%d]\n", r)); |
| | | 1432 | |
| | | 1433 | return r; |
1377 | } | | 1434 | } |
1378 | | | 1435 | |
1379 | /* | | 1436 | /* |
1380 | * Perform special action on behalf of the user; | | 1437 | * Perform special action on behalf of the user; |
1381 | * knows about the internals of this device | | 1438 | * knows about the internals of this device |
1382 | */ | | 1439 | */ |
1383 | static int | | 1440 | static int |
1384 | stioctl(dev_t dev, u_long cmd, void *arg, int flag, struct lwp *l) | | 1441 | stioctl(dev_t dev, u_long cmd, void *arg, int flag, struct lwp *l) |
1385 | { | | 1442 | { |
1386 | int error = 0; | | 1443 | int error = 0; |
1387 | int unit; | | 1444 | int unit; |
1388 | int number, nmarks, dsty; | | 1445 | int number, nmarks, dsty; |
1389 | int flags; | | 1446 | int flags; |
| @@ -1776,28 +1833,32 @@ st_space(struct st_softc *st, int number | | | @@ -1776,28 +1833,32 @@ st_space(struct st_softc *st, int number |
1776 | /* | | 1833 | /* |
1777 | * write N filemarks | | 1834 | * write N filemarks |
1778 | */ | | 1835 | */ |
1779 | static int | | 1836 | static int |
1780 | st_write_filemarks(struct st_softc *st, int number, int flags) | | 1837 | st_write_filemarks(struct st_softc *st, int number, int flags) |
1781 | { | | 1838 | { |
1782 | int error; | | 1839 | int error; |
1783 | struct scsi_write_filemarks cmd; | | 1840 | struct scsi_write_filemarks cmd; |
1784 | | | 1841 | |
1785 | /* | | 1842 | /* |
1786 | * It's hard to write a negative number of file marks. | | 1843 | * It's hard to write a negative number of file marks. |
1787 | * Don't try. | | 1844 | * Don't try. |
1788 | */ | | 1845 | */ |
1789 | if (number < 0) | | 1846 | if (number < 0) { |
| | | 1847 | SC_DEBUG(st->sc_periph, SCSIPI_DB3, |
| | | 1848 | ("EINVAL: st_write_filemarks not writing %d file marks\n", number)); |
1790 | return EINVAL; | | 1849 | return EINVAL; |
| | | 1850 | } |
| | | 1851 | |
1791 | switch (number) { | | 1852 | switch (number) { |
1792 | case 0: /* really a command to sync the drive's buffers */ | | 1853 | case 0: /* really a command to sync the drive's buffers */ |
1793 | break; | | 1854 | break; |
1794 | case 1: | | 1855 | case 1: |
1795 | if (st->flags & ST_FM_WRITTEN) /* already have one down */ | | 1856 | if (st->flags & ST_FM_WRITTEN) /* already have one down */ |
1796 | st->flags &= ~ST_WRITTEN; | | 1857 | st->flags &= ~ST_WRITTEN; |
1797 | else | | 1858 | else |
1798 | st->flags |= ST_FM_WRITTEN; | | 1859 | st->flags |= ST_FM_WRITTEN; |
1799 | st->flags &= ~ST_PER_ACTION; | | 1860 | st->flags &= ~ST_PER_ACTION; |
1800 | break; | | 1861 | break; |
1801 | default: | | 1862 | default: |
1802 | st->flags &= ~(ST_PER_ACTION | ST_WRITTEN); | | 1863 | st->flags &= ~(ST_PER_ACTION | ST_WRITTEN); |
1803 | } | | 1864 | } |
| @@ -1972,28 +2033,31 @@ st_rdpos(struct st_softc *st, int hard, | | | @@ -1972,28 +2033,31 @@ st_rdpos(struct st_softc *st, int hard, |
1972 | cmd.byte1 = 1; | | 2033 | cmd.byte1 = 1; |
1973 | | | 2034 | |
1974 | error = scsipi_command(st->sc_periph, (void *)&cmd, sizeof(cmd), | | 2035 | error = scsipi_command(st->sc_periph, (void *)&cmd, sizeof(cmd), |
1975 | (void *)&posdata, sizeof(posdata), ST_RETRIES, ST_CTL_TIME, NULL, | | 2036 | (void *)&posdata, sizeof(posdata), ST_RETRIES, ST_CTL_TIME, NULL, |
1976 | XS_CTL_SILENT | XS_CTL_DATA_IN); | | 2037 | XS_CTL_SILENT | XS_CTL_DATA_IN); |
1977 | | | 2038 | |
1978 | if (error == 0) { | | 2039 | if (error == 0) { |
1979 | #if 0 | | 2040 | #if 0 |
1980 | printf("posdata:"); | | 2041 | printf("posdata:"); |
1981 | for (hard = 0; hard < sizeof(posdata); hard++) | | 2042 | for (hard = 0; hard < sizeof(posdata); hard++) |
1982 | printf("%02x ", posdata[hard] & 0xff); | | 2043 | printf("%02x ", posdata[hard] & 0xff); |
1983 | printf("\n"); | | 2044 | printf("\n"); |
1984 | #endif | | 2045 | #endif |
1985 | if (posdata[0] & 0x4) /* Block Position Unknown */ | | 2046 | if (posdata[0] & 0x4) { /* Block Position Unknown */ |
| | | 2047 | SC_DEBUG(st->sc_periph, SCSIPI_DB3, |
| | | 2048 | ("EINVAL: strdpos block position unknown\n")); |
1986 | error = EINVAL; | | 2049 | error = EINVAL; |
| | | 2050 | } |
1987 | else | | 2051 | else |
1988 | *blkptr = _4btol(&posdata[4]); | | 2052 | *blkptr = _4btol(&posdata[4]); |
1989 | } | | 2053 | } |
1990 | return error; | | 2054 | return error; |
1991 | } | | 2055 | } |
1992 | | | 2056 | |
1993 | static int | | 2057 | static int |
1994 | st_setpos(struct st_softc *st, int hard, uint32_t *blkptr) | | 2058 | st_setpos(struct st_softc *st, int hard, uint32_t *blkptr) |
1995 | { | | 2059 | { |
1996 | int error; | | 2060 | int error; |
1997 | struct scsi_tape_locate cmd; | | 2061 | struct scsi_tape_locate cmd; |
1998 | | | 2062 | |
1999 | /* | | 2063 | /* |