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