scsi_pt.c (58934) | scsi_pt.c (59249) |
---|---|
1/* 2 * Implementation of SCSI Processor Target Peripheral driver for CAM. 3 * 4 * Copyright (c) 1998 Justin T. Gibbs. 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 --- 11 unchanged lines hidden (view full) --- 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * | 1/* 2 * Implementation of SCSI Processor Target Peripheral driver for CAM. 3 * 4 * Copyright (c) 1998 Justin T. Gibbs. 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 --- 11 unchanged lines hidden (view full) --- 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * $FreeBSD: head/sys/cam/scsi/scsi_pt.c 58934 2000-04-02 15:24:56Z phk $ | 28 * $FreeBSD: head/sys/cam/scsi/scsi_pt.c 59249 2000-04-15 05:54:02Z phk $ |
29 */ 30 31#include <sys/param.h> 32#include <sys/queue.h> 33#include <sys/systm.h> 34#include <sys/kernel.h> 35#include <sys/types.h> 36#include <sys/buf.h> --- 34 unchanged lines hidden (view full) --- 71 PT_CCB_BUFFER_IO_UA = PT_CCB_BUFFER_IO|PT_CCB_RETRY_UA 72} pt_ccb_state; 73 74/* Offsets into our private area for storing information */ 75#define ccb_state ppriv_field0 76#define ccb_bp ppriv_ptr1 77 78struct pt_softc { | 29 */ 30 31#include <sys/param.h> 32#include <sys/queue.h> 33#include <sys/systm.h> 34#include <sys/kernel.h> 35#include <sys/types.h> 36#include <sys/buf.h> --- 34 unchanged lines hidden (view full) --- 71 PT_CCB_BUFFER_IO_UA = PT_CCB_BUFFER_IO|PT_CCB_RETRY_UA 72} pt_ccb_state; 73 74/* Offsets into our private area for storing information */ 75#define ccb_state ppriv_field0 76#define ccb_bp ppriv_ptr1 77 78struct pt_softc { |
79 struct buf_queue_head buf_queue; | 79 struct bio_queue_head bio_queue; |
80 struct devstat device_stats; 81 LIST_HEAD(, ccb_hdr) pending_ccbs; 82 pt_state state; 83 pt_flags flags; 84 union ccb saved_ccb; 85 int io_timeout; 86 dev_t dev; 87}; --- 122 unchanged lines hidden (view full) --- 210} 211 212/* 213 * Actually translate the requested transfer into one the physical driver 214 * can understand. The transfer is described by a buf and will include 215 * only one physical transfer. 216 */ 217static void | 80 struct devstat device_stats; 81 LIST_HEAD(, ccb_hdr) pending_ccbs; 82 pt_state state; 83 pt_flags flags; 84 union ccb saved_ccb; 85 int io_timeout; 86 dev_t dev; 87}; --- 122 unchanged lines hidden (view full) --- 210} 211 212/* 213 * Actually translate the requested transfer into one the physical driver 214 * can understand. The transfer is described by a buf and will include 215 * only one physical transfer. 216 */ 217static void |
218ptstrategy(struct buf *bp) | 218ptstrategy(struct bio *bp) |
219{ 220 struct cam_periph *periph; 221 struct pt_softc *softc; 222 u_int unit; 223 int s; 224 | 219{ 220 struct cam_periph *periph; 221 struct pt_softc *softc; 222 u_int unit; 223 int s; 224 |
225 unit = minor(bp->b_dev); | 225 unit = minor(bp->bio_dev); |
226 periph = cam_extend_get(ptperiphs, unit); 227 if (periph == NULL) { | 226 periph = cam_extend_get(ptperiphs, unit); 227 if (periph == NULL) { |
228 bp->b_error = ENXIO; | 228 bp->bio_error = ENXIO; |
229 goto bad; 230 } 231 softc = (struct pt_softc *)periph->softc; 232 233 /* 234 * Mask interrupts so that the pack cannot be invalidated until 235 * after we are in the queue. Otherwise, we might not properly 236 * clean up one of the buffers. 237 */ 238 s = splbio(); 239 240 /* 241 * If the device has been made invalid, error out 242 */ 243 if ((softc->flags & PT_FLAG_DEVICE_INVALID)) { 244 splx(s); | 229 goto bad; 230 } 231 softc = (struct pt_softc *)periph->softc; 232 233 /* 234 * Mask interrupts so that the pack cannot be invalidated until 235 * after we are in the queue. Otherwise, we might not properly 236 * clean up one of the buffers. 237 */ 238 s = splbio(); 239 240 /* 241 * If the device has been made invalid, error out 242 */ 243 if ((softc->flags & PT_FLAG_DEVICE_INVALID)) { 244 splx(s); |
245 bp->b_error = ENXIO; | 245 bp->bio_error = ENXIO; |
246 goto bad; 247 } 248 249 /* 250 * Place it in the queue of disk activities for this disk 251 */ | 246 goto bad; 247 } 248 249 /* 250 * Place it in the queue of disk activities for this disk 251 */ |
252 bufq_insert_tail(&softc->buf_queue, bp); | 252 bioq_insert_tail(&softc->bio_queue, bp); |
253 254 splx(s); 255 256 /* 257 * Schedule ourselves for performing the work. 258 */ 259 xpt_schedule(periph, /* XXX priority */1); 260 261 return; 262bad: | 253 254 splx(s); 255 256 /* 257 * Schedule ourselves for performing the work. 258 */ 259 xpt_schedule(periph, /* XXX priority */1); 260 261 return; 262bad: |
263 bp->b_ioflags |= BIO_ERROR; | 263 bp->bio_flags |= BIO_ERROR; |
264 265 /* 266 * Correctly set the buf to indicate a completed xfer 267 */ | 264 265 /* 266 * Correctly set the buf to indicate a completed xfer 267 */ |
268 bp->b_resid = bp->b_bcount; | 268 bp->bio_resid = bp->bio_bcount; |
269 biodone(bp); 270} 271 272static void 273ptinit(void) 274{ 275 cam_status status; 276 struct cam_path *path; --- 57 unchanged lines hidden (view full) --- 334 printf("daregister: Unable to probe new device. " 335 "Unable to allocate softc\n"); 336 return(CAM_REQ_CMP_ERR); 337 } 338 339 bzero(softc, sizeof(*softc)); 340 LIST_INIT(&softc->pending_ccbs); 341 softc->state = PT_STATE_NORMAL; | 269 biodone(bp); 270} 271 272static void 273ptinit(void) 274{ 275 cam_status status; 276 struct cam_path *path; --- 57 unchanged lines hidden (view full) --- 334 printf("daregister: Unable to probe new device. " 335 "Unable to allocate softc\n"); 336 return(CAM_REQ_CMP_ERR); 337 } 338 339 bzero(softc, sizeof(*softc)); 340 LIST_INIT(&softc->pending_ccbs); 341 softc->state = PT_STATE_NORMAL; |
342 bufq_init(&softc->buf_queue); | 342 bioq_init(&softc->bio_queue); |
343 344 softc->io_timeout = SCSI_PT_DEFAULT_TIMEOUT * 1000; 345 346 periph->softc = softc; 347 348 cam_extend_set(ptperiphs, periph->unit_number, periph); 349 350 devstat_add_entry(&softc->device_stats, "pt", --- 26 unchanged lines hidden (view full) --- 377 return(CAM_REQ_CMP); 378} 379 380static void 381ptoninvalidate(struct cam_periph *periph) 382{ 383 int s; 384 struct pt_softc *softc; | 343 344 softc->io_timeout = SCSI_PT_DEFAULT_TIMEOUT * 1000; 345 346 periph->softc = softc; 347 348 cam_extend_set(ptperiphs, periph->unit_number, periph); 349 350 devstat_add_entry(&softc->device_stats, "pt", --- 26 unchanged lines hidden (view full) --- 377 return(CAM_REQ_CMP); 378} 379 380static void 381ptoninvalidate(struct cam_periph *periph) 382{ 383 int s; 384 struct pt_softc *softc; |
385 struct buf *q_bp; | 385 struct bio *q_bp; |
386 struct ccb_setasync csa; 387 388 softc = (struct pt_softc *)periph->softc; 389 390 /* 391 * De-register any async callbacks. 392 */ 393 xpt_setup_ccb(&csa.ccb_h, periph->path, --- 13 unchanged lines hidden (view full) --- 407 */ 408 s = splbio(); 409 410 /* 411 * Return all queued I/O with ENXIO. 412 * XXX Handle any transactions queued to the card 413 * with XPT_ABORT_CCB. 414 */ | 386 struct ccb_setasync csa; 387 388 softc = (struct pt_softc *)periph->softc; 389 390 /* 391 * De-register any async callbacks. 392 */ 393 xpt_setup_ccb(&csa.ccb_h, periph->path, --- 13 unchanged lines hidden (view full) --- 407 */ 408 s = splbio(); 409 410 /* 411 * Return all queued I/O with ENXIO. 412 * XXX Handle any transactions queued to the card 413 * with XPT_ABORT_CCB. 414 */ |
415 while ((q_bp = bufq_first(&softc->buf_queue)) != NULL){ 416 bufq_remove(&softc->buf_queue, q_bp); 417 q_bp->b_resid = q_bp->b_bcount; 418 q_bp->b_error = ENXIO; 419 q_bp->b_ioflags |= BIO_ERROR; | 415 while ((q_bp = bioq_first(&softc->bio_queue)) != NULL){ 416 bioq_remove(&softc->bio_queue, q_bp); 417 q_bp->bio_resid = q_bp->bio_bcount; 418 q_bp->bio_error = ENXIO; 419 q_bp->bio_flags |= BIO_ERROR; |
420 biodone(q_bp); 421 } 422 423 splx(s); 424 425 xpt_print_path(periph->path); 426 printf("lost device\n"); 427} --- 73 unchanged lines hidden (view full) --- 501 break; 502 } 503} 504 505static void 506ptstart(struct cam_periph *periph, union ccb *start_ccb) 507{ 508 struct pt_softc *softc; | 420 biodone(q_bp); 421 } 422 423 splx(s); 424 425 xpt_print_path(periph->path); 426 printf("lost device\n"); 427} --- 73 unchanged lines hidden (view full) --- 501 break; 502 } 503} 504 505static void 506ptstart(struct cam_periph *periph, union ccb *start_ccb) 507{ 508 struct pt_softc *softc; |
509 struct buf *bp; | 509 struct bio *bp; |
510 int s; 511 512 softc = (struct pt_softc *)periph->softc; 513 514 /* 515 * See if there is a buf with work for us to do.. 516 */ 517 s = splbio(); | 510 int s; 511 512 softc = (struct pt_softc *)periph->softc; 513 514 /* 515 * See if there is a buf with work for us to do.. 516 */ 517 s = splbio(); |
518 bp = bufq_first(&softc->buf_queue); | 518 bp = bioq_first(&softc->bio_queue); |
519 if (periph->immediate_priority <= periph->pinfo.priority) { 520 CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE, 521 ("queuing for immediate ccb\n")); 522 start_ccb->ccb_h.ccb_state = PT_CCB_WAITING; 523 SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h, 524 periph_links.sle); 525 periph->immediate_priority = CAM_PRIORITY_NONE; 526 splx(s); 527 wakeup(&periph->ccb_list); 528 } else if (bp == NULL) { 529 splx(s); 530 xpt_release_ccb(start_ccb); 531 } else { 532 int oldspl; 533 | 519 if (periph->immediate_priority <= periph->pinfo.priority) { 520 CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE, 521 ("queuing for immediate ccb\n")); 522 start_ccb->ccb_h.ccb_state = PT_CCB_WAITING; 523 SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h, 524 periph_links.sle); 525 periph->immediate_priority = CAM_PRIORITY_NONE; 526 splx(s); 527 wakeup(&periph->ccb_list); 528 } else if (bp == NULL) { 529 splx(s); 530 xpt_release_ccb(start_ccb); 531 } else { 532 int oldspl; 533 |
534 bufq_remove(&softc->buf_queue, bp); | 534 bioq_remove(&softc->bio_queue, bp); |
535 536 devstat_start_transaction(&softc->device_stats); 537 538 scsi_send_receive(&start_ccb->csio, 539 /*retries*/4, 540 ptdone, 541 MSG_SIMPLE_Q_TAG, | 535 536 devstat_start_transaction(&softc->device_stats); 537 538 scsi_send_receive(&start_ccb->csio, 539 /*retries*/4, 540 ptdone, 541 MSG_SIMPLE_Q_TAG, |
542 bp->b_iocmd == BIO_READ, | 542 bp->bio_cmd == BIO_READ, |
543 /*byte2*/0, | 543 /*byte2*/0, |
544 bp->b_bcount, 545 bp->b_data, | 544 bp->bio_bcount, 545 bp->bio_data, |
546 /*sense_len*/SSD_FULL_SIZE, 547 /*timeout*/softc->io_timeout); 548 549 start_ccb->ccb_h.ccb_state = PT_CCB_BUFFER_IO; 550 551 /* 552 * Block out any asyncronous callbacks 553 * while we touch the pending ccb list. 554 */ 555 oldspl = splcam(); 556 LIST_INSERT_HEAD(&softc->pending_ccbs, &start_ccb->ccb_h, 557 periph_links.le); 558 splx(oldspl); 559 560 start_ccb->ccb_h.ccb_bp = bp; | 546 /*sense_len*/SSD_FULL_SIZE, 547 /*timeout*/softc->io_timeout); 548 549 start_ccb->ccb_h.ccb_state = PT_CCB_BUFFER_IO; 550 551 /* 552 * Block out any asyncronous callbacks 553 * while we touch the pending ccb list. 554 */ 555 oldspl = splcam(); 556 LIST_INSERT_HEAD(&softc->pending_ccbs, &start_ccb->ccb_h, 557 periph_links.le); 558 splx(oldspl); 559 560 start_ccb->ccb_h.ccb_bp = bp; |
561 bp = bufq_first(&softc->buf_queue); | 561 bp = bioq_first(&softc->bio_queue); |
562 splx(s); 563 564 xpt_action(start_ccb); 565 566 if (bp != NULL) { 567 /* Have more work to do, so ensure we stay scheduled */ 568 xpt_schedule(periph, /* XXX priority */1); 569 } --- 7 unchanged lines hidden (view full) --- 577 struct ccb_scsiio *csio; 578 579 softc = (struct pt_softc *)periph->softc; 580 csio = &done_ccb->csio; 581 switch (csio->ccb_h.ccb_state) { 582 case PT_CCB_BUFFER_IO: 583 case PT_CCB_BUFFER_IO_UA: 584 { | 562 splx(s); 563 564 xpt_action(start_ccb); 565 566 if (bp != NULL) { 567 /* Have more work to do, so ensure we stay scheduled */ 568 xpt_schedule(periph, /* XXX priority */1); 569 } --- 7 unchanged lines hidden (view full) --- 577 struct ccb_scsiio *csio; 578 579 softc = (struct pt_softc *)periph->softc; 580 csio = &done_ccb->csio; 581 switch (csio->ccb_h.ccb_state) { 582 case PT_CCB_BUFFER_IO: 583 case PT_CCB_BUFFER_IO_UA: 584 { |
585 struct buf *bp; | 585 struct bio *bp; |
586 int oldspl; 587 | 586 int oldspl; 587 |
588 bp = (struct buf *)done_ccb->ccb_h.ccb_bp; | 588 bp = (struct bio *)done_ccb->ccb_h.ccb_bp; |
589 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 590 int error; 591 int s; 592 int sf; 593 594 if ((csio->ccb_h.ccb_state & PT_CCB_RETRY_UA) != 0) 595 sf = SF_RETRY_UA; 596 else --- 4 unchanged lines hidden (view full) --- 601 if ((error = pterror(done_ccb, 0, sf)) == ERESTART) { 602 /* 603 * A retry was scheuled, so 604 * just return. 605 */ 606 return; 607 } 608 if (error != 0) { | 589 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 590 int error; 591 int s; 592 int sf; 593 594 if ((csio->ccb_h.ccb_state & PT_CCB_RETRY_UA) != 0) 595 sf = SF_RETRY_UA; 596 else --- 4 unchanged lines hidden (view full) --- 601 if ((error = pterror(done_ccb, 0, sf)) == ERESTART) { 602 /* 603 * A retry was scheuled, so 604 * just return. 605 */ 606 return; 607 } 608 if (error != 0) { |
609 struct buf *q_bp; | 609 struct bio *q_bp; |
610 611 s = splbio(); 612 613 if (error == ENXIO) { 614 /* 615 * Catastrophic error. Mark our device 616 * as invalid. 617 */ 618 xpt_print_path(periph->path); 619 printf("Invalidating device\n"); 620 softc->flags |= PT_FLAG_DEVICE_INVALID; 621 } 622 623 /* 624 * return all queued I/O with EIO, so that 625 * the client can retry these I/Os in the 626 * proper order should it attempt to recover. 627 */ | 610 611 s = splbio(); 612 613 if (error == ENXIO) { 614 /* 615 * Catastrophic error. Mark our device 616 * as invalid. 617 */ 618 xpt_print_path(periph->path); 619 printf("Invalidating device\n"); 620 softc->flags |= PT_FLAG_DEVICE_INVALID; 621 } 622 623 /* 624 * return all queued I/O with EIO, so that 625 * the client can retry these I/Os in the 626 * proper order should it attempt to recover. 627 */ |
628 while ((q_bp = bufq_first(&softc->buf_queue)) | 628 while ((q_bp = bioq_first(&softc->bio_queue)) |
629 != NULL) { | 629 != NULL) { |
630 bufq_remove(&softc->buf_queue, q_bp); 631 q_bp->b_resid = q_bp->b_bcount; 632 q_bp->b_error = EIO; 633 q_bp->b_ioflags |= BIO_ERROR; | 630 bioq_remove(&softc->bio_queue, q_bp); 631 q_bp->bio_resid = q_bp->bio_bcount; 632 q_bp->bio_error = EIO; 633 q_bp->bio_flags |= BIO_ERROR; |
634 biodone(q_bp); 635 } 636 splx(s); | 634 biodone(q_bp); 635 } 636 splx(s); |
637 bp->b_error = error; 638 bp->b_resid = bp->b_bcount; 639 bp->b_ioflags |= BIO_ERROR; | 637 bp->bio_error = error; 638 bp->bio_resid = bp->bio_bcount; 639 bp->bio_flags |= BIO_ERROR; |
640 } else { | 640 } else { |
641 bp->b_resid = csio->resid; 642 bp->b_error = 0; 643 if (bp->b_resid != 0) { | 641 bp->bio_resid = csio->resid; 642 bp->bio_error = 0; 643 if (bp->bio_resid != 0) { |
644 /* Short transfer ??? */ | 644 /* Short transfer ??? */ |
645 bp->b_ioflags |= BIO_ERROR; | 645 bp->bio_flags |= BIO_ERROR; |
646 } 647 } 648 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) 649 cam_release_devq(done_ccb->ccb_h.path, 650 /*relsim_flags*/0, 651 /*reduction*/0, 652 /*timeout*/0, 653 /*getcount_only*/0); 654 } else { | 646 } 647 } 648 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) 649 cam_release_devq(done_ccb->ccb_h.path, 650 /*relsim_flags*/0, 651 /*reduction*/0, 652 /*timeout*/0, 653 /*getcount_only*/0); 654 } else { |
655 bp->b_resid = csio->resid; 656 if (bp->b_resid != 0) 657 bp->b_ioflags |= BIO_ERROR; | 655 bp->bio_resid = csio->resid; 656 if (bp->bio_resid != 0) 657 bp->bio_flags |= BIO_ERROR; |
658 } 659 660 /* 661 * Block out any asyncronous callbacks 662 * while we touch the pending ccb list. 663 */ 664 oldspl = splcam(); 665 LIST_REMOVE(&done_ccb->ccb_h, periph_links.le); 666 splx(oldspl); 667 | 658 } 659 660 /* 661 * Block out any asyncronous callbacks 662 * while we touch the pending ccb list. 663 */ 664 oldspl = splcam(); 665 LIST_REMOVE(&done_ccb->ccb_h, periph_links.le); 666 splx(oldspl); 667 |
668 devstat_end_transaction_buf(&softc->device_stats, bp); | 668 devstat_end_transaction_bio(&softc->device_stats, bp); |
669 biodone(bp); 670 break; 671 } 672 case PT_CCB_WAITING: 673 /* Caller will release the CCB */ 674 wakeup(&done_ccb->ccb_h.cbfcnp); 675 return; 676 } --- 94 unchanged lines hidden --- | 669 biodone(bp); 670 break; 671 } 672 case PT_CCB_WAITING: 673 /* Caller will release the CCB */ 674 wakeup(&done_ccb->ccb_h.cbfcnp); 675 return; 676 } --- 94 unchanged lines hidden --- |