Deleted Added
full compact
scsi_sa.c (220644) scsi_sa.c (225950)
1/*-
2 * Implementation of SCSI Sequential Access Peripheral driver for CAM.
3 *
4 * Copyright (c) 1999, 2000 Matthew Jacob
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

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

22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
1/*-
2 * Implementation of SCSI Sequential Access Peripheral driver for CAM.
3 *
4 * Copyright (c) 1999, 2000 Matthew Jacob
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

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

22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_sa.c 220644 2011-04-14 21:25:32Z mav $");
30__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_sa.c 225950 2011-10-03 20:32:55Z ken $");
31
32#include <sys/param.h>
33#include <sys/queue.h>
34#ifdef _KERNEL
35#include <sys/systm.h>
36#include <sys/kernel.h>
37#endif
38#include <sys/types.h>

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

230 daddr_t fileno;
231 daddr_t blkno;
232
233 /*
234 * Latched Error Info
235 */
236 struct {
237 struct scsi_sense_data _last_io_sense;
31
32#include <sys/param.h>
33#include <sys/queue.h>
34#ifdef _KERNEL
35#include <sys/systm.h>
36#include <sys/kernel.h>
37#endif
38#include <sys/types.h>

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

230 daddr_t fileno;
231 daddr_t blkno;
232
233 /*
234 * Latched Error Info
235 */
236 struct {
237 struct scsi_sense_data _last_io_sense;
238 u_int32_t _last_io_resid;
238 u_int64_t _last_io_resid;
239 u_int8_t _last_io_cdb[CAM_MAX_CDBLEN];
240 struct scsi_sense_data _last_ctl_sense;
239 u_int8_t _last_io_cdb[CAM_MAX_CDBLEN];
240 struct scsi_sense_data _last_ctl_sense;
241 u_int32_t _last_ctl_resid;
241 u_int64_t _last_ctl_resid;
242 u_int8_t _last_ctl_cdb[CAM_MAX_CDBLEN];
243#define last_io_sense errinfo._last_io_sense
244#define last_io_resid errinfo._last_io_resid
245#define last_io_cdb errinfo._last_io_cdb
246#define last_ctl_sense errinfo._last_ctl_sense
247#define last_ctl_resid errinfo._last_ctl_resid
248#define last_ctl_cdb errinfo._last_ctl_cdb
249 } errinfo;

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

844 *
845 * If the periph is already locked, skip it because
846 * we're just getting status and it'll be up to the
847 * other thread that has this device open to do
848 * an MTIOCERRSTAT that would clear latched status.
849 */
850 if ((periph->flags & CAM_PERIPH_LOCKED) == 0) {
851 error = cam_periph_hold(periph, PRIBIO|PCATCH);
242 u_int8_t _last_ctl_cdb[CAM_MAX_CDBLEN];
243#define last_io_sense errinfo._last_io_sense
244#define last_io_resid errinfo._last_io_resid
245#define last_io_cdb errinfo._last_io_cdb
246#define last_ctl_sense errinfo._last_ctl_sense
247#define last_ctl_resid errinfo._last_ctl_resid
248#define last_ctl_cdb errinfo._last_ctl_cdb
249 } errinfo;

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

844 *
845 * If the periph is already locked, skip it because
846 * we're just getting status and it'll be up to the
847 * other thread that has this device open to do
848 * an MTIOCERRSTAT that would clear latched status.
849 */
850 if ((periph->flags & CAM_PERIPH_LOCKED) == 0) {
851 error = cam_periph_hold(periph, PRIBIO|PCATCH);
852 if (error != 0)
852 if (error != 0) {
853 cam_periph_unlock(periph);
853 return (error);
854 return (error);
855 }
854 didlockperiph = 1;
855 }
856 break;
857
858 case MTIOCTOP:
859 {
860 struct mtop *mt = (struct mtop *) arg;
861

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

879 }
880 case MTIOCSETEOTMODEL:
881 /*
882 * We need to acquire the peripheral here rather
883 * than at open time because we are sharing writable
884 * access to data structures.
885 */
886 error = cam_periph_hold(periph, PRIBIO|PCATCH);
856 didlockperiph = 1;
857 }
858 break;
859
860 case MTIOCTOP:
861 {
862 struct mtop *mt = (struct mtop *) arg;
863

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

881 }
882 case MTIOCSETEOTMODEL:
883 /*
884 * We need to acquire the peripheral here rather
885 * than at open time because we are sharing writable
886 * access to data structures.
887 */
888 error = cam_periph_hold(periph, PRIBIO|PCATCH);
887 if (error != 0)
889 if (error != 0) {
890 cam_periph_unlock(periph);
888 return (error);
891 return (error);
892 }
889 didlockperiph = 1;
890 break;
891
892 default:
893 didlockperiph = 1;
894 break;
895
896 default:
897 cam_periph_unlock(periph);
893 return (EINVAL);
894 }
895 }
896
897 /*
898 * Find the device that the user is talking about
899 */
900 switch (cmd) {

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

2317saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs)
2318{
2319 static const char *toobig =
2320 "%d-byte tape record bigger than supplied buffer\n";
2321 struct cam_periph *periph;
2322 struct sa_softc *softc;
2323 struct ccb_scsiio *csio;
2324 struct scsi_sense_data *sense;
898 return (EINVAL);
899 }
900 }
901
902 /*
903 * Find the device that the user is talking about
904 */
905 switch (cmd) {

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

2322saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs)
2323{
2324 static const char *toobig =
2325 "%d-byte tape record bigger than supplied buffer\n";
2326 struct cam_periph *periph;
2327 struct sa_softc *softc;
2328 struct ccb_scsiio *csio;
2329 struct scsi_sense_data *sense;
2325 u_int32_t resid = 0;
2326 int32_t info = 0;
2330 uint64_t resid = 0;
2331 int64_t info = 0;
2327 cam_status status;
2332 cam_status status;
2328 int error_code, sense_key, asc, ascq, error, aqvalid;
2333 int error_code, sense_key, asc, ascq, error, aqvalid, stream_valid;
2334 int sense_len;
2335 uint8_t stream_bits;
2329
2330 periph = xpt_path_periph(ccb->ccb_h.path);
2331 softc = (struct sa_softc *)periph->softc;
2332 csio = &ccb->csio;
2333 sense = &csio->sense_data;
2336
2337 periph = xpt_path_periph(ccb->ccb_h.path);
2338 softc = (struct sa_softc *)periph->softc;
2339 csio = &ccb->csio;
2340 sense = &csio->sense_data;
2334 scsi_extract_sense(sense, &error_code, &sense_key, &asc, &ascq);
2335 aqvalid = sense->extra_len >= 6;
2341 sense_len = csio->sense_len - csio->sense_resid;
2342 scsi_extract_sense_len(sense, sense_len, &error_code, &sense_key,
2343 &asc, &ascq, /*show_errors*/ 1);
2344 if (asc != -1 && ascq != -1)
2345 aqvalid = 1;
2346 else
2347 aqvalid = 0;
2348 if (scsi_get_stream_info(sense, sense_len, NULL, &stream_bits) == 0)
2349 stream_valid = 1;
2350 else
2351 stream_valid = 0;
2336 error = 0;
2337
2338 status = csio->ccb_h.status & CAM_STATUS_MASK;
2339
2340 /*
2341 * Calculate/latch up, any residuals... We do this in a funny 2-step
2342 * so we can print stuff here if we have CAM_DEBUG enabled for this
2343 * unit.
2344 */
2345 if (status == CAM_SCSI_STATUS_ERROR) {
2352 error = 0;
2353
2354 status = csio->ccb_h.status & CAM_STATUS_MASK;
2355
2356 /*
2357 * Calculate/latch up, any residuals... We do this in a funny 2-step
2358 * so we can print stuff here if we have CAM_DEBUG enabled for this
2359 * unit.
2360 */
2361 if (status == CAM_SCSI_STATUS_ERROR) {
2346 if ((sense->error_code & SSD_ERRCODE_VALID) != 0) {
2347 info = (int32_t) scsi_4btoul(sense->info);
2348 resid = info;
2362 if (scsi_get_sense_info(sense, sense_len, SSD_DESC_INFO, &resid,
2363 &info) == 0) {
2349 if ((softc->flags & SA_FLAG_FIXED) != 0)
2350 resid *= softc->media_blksize;
2351 } else {
2352 resid = csio->dxfer_len;
2353 info = resid;
2354 if ((softc->flags & SA_FLAG_FIXED) != 0) {
2355 if (softc->media_blksize)
2356 info /= softc->media_blksize;

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

2367 bcopy((caddr_t) sense, (caddr_t) &softc->last_ctl_sense,
2368 sizeof (struct scsi_sense_data));
2369 bcopy(csio->cdb_io.cdb_bytes, softc->last_ctl_cdb,
2370 (int) csio->cdb_len);
2371 softc->last_ctl_resid = resid;
2372 softc->last_resid_was_io = 0;
2373 }
2374 CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("CDB[0]=0x%x Key 0x%x "
2364 if ((softc->flags & SA_FLAG_FIXED) != 0)
2365 resid *= softc->media_blksize;
2366 } else {
2367 resid = csio->dxfer_len;
2368 info = resid;
2369 if ((softc->flags & SA_FLAG_FIXED) != 0) {
2370 if (softc->media_blksize)
2371 info /= softc->media_blksize;

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

2382 bcopy((caddr_t) sense, (caddr_t) &softc->last_ctl_sense,
2383 sizeof (struct scsi_sense_data));
2384 bcopy(csio->cdb_io.cdb_bytes, softc->last_ctl_cdb,
2385 (int) csio->cdb_len);
2386 softc->last_ctl_resid = resid;
2387 softc->last_resid_was_io = 0;
2388 }
2389 CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("CDB[0]=0x%x Key 0x%x "
2375 "ASC/ASCQ 0x%x/0x%x CAM STATUS 0x%x flags 0x%x resid %d "
2390 "ASC/ASCQ 0x%x/0x%x CAM STATUS 0x%x flags 0x%x resid %jd "
2376 "dxfer_len %d\n", csio->cdb_io.cdb_bytes[0] & 0xff,
2377 sense_key, asc, ascq, status,
2391 "dxfer_len %d\n", csio->cdb_io.cdb_bytes[0] & 0xff,
2392 sense_key, asc, ascq, status,
2378 sense->flags & ~SSD_KEY_RESERVED, resid, csio->dxfer_len));
2393 (stream_valid) ? stream_bits : 0, (intmax_t)resid,
2394 csio->dxfer_len));
2379 } else {
2380 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
2381 ("Cam Status 0x%x\n", status));
2382 }
2383
2384 switch (status) {
2385 case CAM_REQ_CMP:
2386 return (0);

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

2426 * From this point out, we're only handling read/write cases.
2427 * Handle writes && reads differently.
2428 */
2429
2430 if (csio->cdb_io.cdb_bytes[0] == SA_WRITE) {
2431 if (sense_key == SSD_KEY_VOLUME_OVERFLOW) {
2432 csio->resid = resid;
2433 error = ENOSPC;
2395 } else {
2396 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
2397 ("Cam Status 0x%x\n", status));
2398 }
2399
2400 switch (status) {
2401 case CAM_REQ_CMP:
2402 return (0);

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

2442 * From this point out, we're only handling read/write cases.
2443 * Handle writes && reads differently.
2444 */
2445
2446 if (csio->cdb_io.cdb_bytes[0] == SA_WRITE) {
2447 if (sense_key == SSD_KEY_VOLUME_OVERFLOW) {
2448 csio->resid = resid;
2449 error = ENOSPC;
2434 } else if (sense->flags & SSD_EOM) {
2450 } else if ((stream_valid != 0) && (stream_bits & SSD_EOM)) {
2435 softc->flags |= SA_FLAG_EOM_PENDING;
2436 /*
2437 * Grotesque as it seems, the few times
2438 * I've actually seen a non-zero resid,
2439 * the tape drive actually lied and had
2440 * written all the data!.
2441 */
2442 csio->resid = 0;
2443 }
2444 } else {
2445 csio->resid = resid;
2446 if (sense_key == SSD_KEY_BLANK_CHECK) {
2447 if (softc->quirks & SA_QUIRK_1FM) {
2448 error = 0;
2449 softc->flags |= SA_FLAG_EOM_PENDING;
2450 } else {
2451 error = EIO;
2452 }
2451 softc->flags |= SA_FLAG_EOM_PENDING;
2452 /*
2453 * Grotesque as it seems, the few times
2454 * I've actually seen a non-zero resid,
2455 * the tape drive actually lied and had
2456 * written all the data!.
2457 */
2458 csio->resid = 0;
2459 }
2460 } else {
2461 csio->resid = resid;
2462 if (sense_key == SSD_KEY_BLANK_CHECK) {
2463 if (softc->quirks & SA_QUIRK_1FM) {
2464 error = 0;
2465 softc->flags |= SA_FLAG_EOM_PENDING;
2466 } else {
2467 error = EIO;
2468 }
2453 } else if (sense->flags & SSD_FILEMARK) {
2469 } else if ((stream_valid != 0) && (stream_bits & SSD_FILEMARK)){
2454 if (softc->flags & SA_FLAG_FIXED) {
2455 error = -1;
2456 softc->flags |= SA_FLAG_EOF_PENDING;
2457 }
2458 /*
2459 * Unconditionally, if we detected a filemark on a read,
2460 * mark that we've run moved a file ahead.
2461 */
2462 if (softc->fileno != (daddr_t) -1) {
2463 softc->fileno++;
2464 softc->blkno = 0;
2465 csio->ccb_h.ccb_pflags |= SA_POSITION_UPDATED;
2466 }
2467 }
2468 }
2469
2470 /*
2471 * Incorrect Length usually applies to read, but can apply to writes.
2472 */
2470 if (softc->flags & SA_FLAG_FIXED) {
2471 error = -1;
2472 softc->flags |= SA_FLAG_EOF_PENDING;
2473 }
2474 /*
2475 * Unconditionally, if we detected a filemark on a read,
2476 * mark that we've run moved a file ahead.
2477 */
2478 if (softc->fileno != (daddr_t) -1) {
2479 softc->fileno++;
2480 softc->blkno = 0;
2481 csio->ccb_h.ccb_pflags |= SA_POSITION_UPDATED;
2482 }
2483 }
2484 }
2485
2486 /*
2487 * Incorrect Length usually applies to read, but can apply to writes.
2488 */
2473 if (error == 0 && (sense->flags & SSD_ILI)) {
2489 if (error == 0 && (stream_valid != 0) && (stream_bits & SSD_ILI)) {
2474 if (info < 0) {
2475 xpt_print(csio->ccb_h.path, toobig,
2476 csio->dxfer_len - info);
2477 csio->resid = csio->dxfer_len;
2478 error = EIO;
2479 } else {
2480 csio->resid = resid;
2481 if (softc->flags & SA_FLAG_FIXED) {
2482 softc->flags |= SA_FLAG_EIO_PENDING;
2483 }
2484 /*
2485 * Bump the block number if we hadn't seen a filemark.
2486 * Do this independent of errors (we've moved anyway).
2487 */
2490 if (info < 0) {
2491 xpt_print(csio->ccb_h.path, toobig,
2492 csio->dxfer_len - info);
2493 csio->resid = csio->dxfer_len;
2494 error = EIO;
2495 } else {
2496 csio->resid = resid;
2497 if (softc->flags & SA_FLAG_FIXED) {
2498 softc->flags |= SA_FLAG_EIO_PENDING;
2499 }
2500 /*
2501 * Bump the block number if we hadn't seen a filemark.
2502 * Do this independent of errors (we've moved anyway).
2503 */
2488 if ((sense->flags & SSD_FILEMARK) == 0) {
2504 if ((stream_valid == 0) ||
2505 (stream_bits & SSD_FILEMARK) == 0) {
2489 if (softc->blkno != (daddr_t) -1) {
2490 softc->blkno++;
2491 csio->ccb_h.ccb_pflags |=
2492 SA_POSITION_UPDATED;
2493 }
2494 }
2495 }
2496 }

--- 1140 unchanged lines hidden ---
2506 if (softc->blkno != (daddr_t) -1) {
2507 softc->blkno++;
2508 csio->ccb_h.ccb_pflags |=
2509 SA_POSITION_UPDATED;
2510 }
2511 }
2512 }
2513 }

--- 1140 unchanged lines hidden ---