cam_xpt.c (e91896117bba50d067048e99659fd015b35322e9) cam_xpt.c (5a526431f84768cc809e654ae2f3e9b66d0066bd)
1/*
2 * Implementation of the Common Access Method Transport (XPT) layer.
3 *
4 * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs.
5 * Copyright (c) 1997, 1998, 1999 Kenneth D. Merry.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

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

21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
1/*
2 * Implementation of the Common Access Method Transport (XPT) layer.
3 *
4 * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs.
5 * Copyright (c) 1997, 1998, 1999 Kenneth D. Merry.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

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

21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $Id: cam_xpt.c,v 1.50 1999/04/07 22:57:48 gibbs Exp $
29 * $Id: cam_xpt.c,v 1.51 1999/04/17 08:36:03 peter Exp $
30 */
31#include <sys/param.h>
32#include <sys/systm.h>
33#include <sys/types.h>
34#include <sys/malloc.h>
35#include <sys/device.h>
36#include <sys/kernel.h>
37#include <sys/conf.h>

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

750
751 if (dev->ccbq.devq_openings > 0) {
752 if ((dev->flags & CAM_DEV_RESIZE_QUEUE_NEEDED) != 0) {
753 cam_ccbq_resize(&dev->ccbq,
754 dev->ccbq.dev_openings
755 + dev->ccbq.dev_active);
756 dev->flags &= ~CAM_DEV_RESIZE_QUEUE_NEEDED;
757 }
30 */
31#include <sys/param.h>
32#include <sys/systm.h>
33#include <sys/types.h>
34#include <sys/malloc.h>
35#include <sys/device.h>
36#include <sys/kernel.h>
37#include <sys/conf.h>

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

750
751 if (dev->ccbq.devq_openings > 0) {
752 if ((dev->flags & CAM_DEV_RESIZE_QUEUE_NEEDED) != 0) {
753 cam_ccbq_resize(&dev->ccbq,
754 dev->ccbq.dev_openings
755 + dev->ccbq.dev_active);
756 dev->flags &= ~CAM_DEV_RESIZE_QUEUE_NEEDED;
757 }
758 /*
759 * The priority of a device waiting for CCB resources
760 * is that of the the highest priority peripheral driver
761 * enqueued.
762 */
758 retval = xpt_schedule_dev(&bus->sim->devq->alloc_queue,
759 &dev->alloc_ccb_entry.pinfo,
763 retval = xpt_schedule_dev(&bus->sim->devq->alloc_queue,
764 &dev->alloc_ccb_entry.pinfo,
760 dev->drvq.queue_array[0]->priority);
765 CAMQ_GET_HEAD(&dev->drvq)->priority);
761 } else {
762 retval = 0;
763 }
764
765 return (retval);
766}
767
768static __inline int
769xpt_schedule_dev_sendq(struct cam_eb *bus, struct cam_ed *dev)
770{
771 int retval;
772
773 if (dev->ccbq.dev_openings > 0) {
766 } else {
767 retval = 0;
768 }
769
770 return (retval);
771}
772
773static __inline int
774xpt_schedule_dev_sendq(struct cam_eb *bus, struct cam_ed *dev)
775{
776 int retval;
777
778 if (dev->ccbq.dev_openings > 0) {
774 retval = xpt_schedule_dev(&bus->sim->devq->send_queue,
775 &dev->send_ccb_entry.pinfo,
776 dev->ccbq.queue.queue_array[0]->priority);
779 /*
780 * The priority of a device waiting for controller
781 * resources is that of the the highest priority CCB
782 * enqueued.
783 */
784 retval =
785 xpt_schedule_dev(&bus->sim->devq->send_queue,
786 &dev->send_ccb_entry.pinfo,
787 CAMQ_GET_HEAD(&dev->ccbq.queue)->priority);
777 } else {
778 retval = 0;
779 }
780 return (retval);
781}
782
783static __inline int
784periph_is_queued(struct cam_periph *periph)

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

2329 * don't have to worry about new peripheral driver types coming or
2330 * going; they're in a linker set, and therefore can't change
2331 * without a recompile.
2332 */
2333
2334 if ((cdm->pos.position_type & CAM_DEV_POS_PDPTR)
2335 && (cdm->pos.cookie.pdrv != NULL))
2336 ret = xptpdrvtraverse(
788 } else {
789 retval = 0;
790 }
791 return (retval);
792}
793
794static __inline int
795periph_is_queued(struct cam_periph *periph)

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

2340 * don't have to worry about new peripheral driver types coming or
2341 * going; they're in a linker set, and therefore can't change
2342 * without a recompile.
2343 */
2344
2345 if ((cdm->pos.position_type & CAM_DEV_POS_PDPTR)
2346 && (cdm->pos.cookie.pdrv != NULL))
2347 ret = xptpdrvtraverse(
2337 (struct periph_driver **)cdm->pos.cookie.pdrv,
2348 (struct periph_driver **)cdm->pos.cookie.pdrv,
2338 xptplistpdrvfunc, cdm);
2339 else
2340 ret = xptpdrvtraverse(NULL, xptplistpdrvfunc, cdm);
2341
2342 /*
2343 * If we get back 0, that means that we had to stop before fully
2344 * traversing the peripheral driver tree. It also means that one of
2345 * the subroutines has set the status field to the proper value. If

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

3377 && (devq->alloc_queue.qfrozen_cnt <= 1)) {
3378 struct cam_ed_qinfo *qinfo;
3379 struct cam_ed *device;
3380 union ccb *work_ccb;
3381 struct cam_periph *drv;
3382 struct camq *drvq;
3383
3384 qinfo = (struct cam_ed_qinfo *)camq_remove(&devq->alloc_queue,
2349 xptplistpdrvfunc, cdm);
2350 else
2351 ret = xptpdrvtraverse(NULL, xptplistpdrvfunc, cdm);
2352
2353 /*
2354 * If we get back 0, that means that we had to stop before fully
2355 * traversing the peripheral driver tree. It also means that one of
2356 * the subroutines has set the status field to the proper value. If

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

3388 && (devq->alloc_queue.qfrozen_cnt <= 1)) {
3389 struct cam_ed_qinfo *qinfo;
3390 struct cam_ed *device;
3391 union ccb *work_ccb;
3392 struct cam_periph *drv;
3393 struct camq *drvq;
3394
3395 qinfo = (struct cam_ed_qinfo *)camq_remove(&devq->alloc_queue,
3385 /*position*/0);
3396 CAMQ_HEAD);
3386 device = qinfo->device;
3387
3388 CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
3389 ("running device %p\n", device));
3390
3391 drvq = &device->drvq;
3392
3393#ifdef CAMDEBUG
3394 if (drvq->entries <= 0) {
3395 panic("xpt_run_dev_allocq: "
3396 "Device on queue without any work to do");
3397 }
3398#endif
3399 if ((work_ccb = xpt_get_ccb(device)) != NULL) {
3400 devq->alloc_openings--;
3401 devq->alloc_active++;
3397 device = qinfo->device;
3398
3399 CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
3400 ("running device %p\n", device));
3401
3402 drvq = &device->drvq;
3403
3404#ifdef CAMDEBUG
3405 if (drvq->entries <= 0) {
3406 panic("xpt_run_dev_allocq: "
3407 "Device on queue without any work to do");
3408 }
3409#endif
3410 if ((work_ccb = xpt_get_ccb(device)) != NULL) {
3411 devq->alloc_openings--;
3412 devq->alloc_active++;
3402 drv = (struct cam_periph*)camq_remove(drvq,
3403 /*pos*/0);
3404 /* Update priority */
3405 if (drvq->entries > 0) {
3406 qinfo->pinfo.priority = drvq->queue_array[0]->priority;
3407 } else {
3408 qinfo->pinfo.priority = CAM_PRIORITY_NONE;
3409 }
3413 drv = (struct cam_periph*)camq_remove(drvq, CAMQ_HEAD);
3410 splx(s);
3411 xpt_setup_ccb(&work_ccb->ccb_h, drv->path,
3412 drv->pinfo.priority);
3413 CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
3414 ("calling periph start\n"));
3415 drv->periph_start(drv, work_ccb);
3416 } else {
3417 /*

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

3462
3463 ospl = splcam();
3464 if (devq->send_queue.qfrozen_cnt > 1) {
3465 splx(ospl);
3466 break;
3467 }
3468
3469 qinfo = (struct cam_ed_qinfo *)camq_remove(&devq->send_queue,
3414 splx(s);
3415 xpt_setup_ccb(&work_ccb->ccb_h, drv->path,
3416 drv->pinfo.priority);
3417 CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
3418 ("calling periph start\n"));
3419 drv->periph_start(drv, work_ccb);
3420 } else {
3421 /*

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

3466
3467 ospl = splcam();
3468 if (devq->send_queue.qfrozen_cnt > 1) {
3469 splx(ospl);
3470 break;
3471 }
3472
3473 qinfo = (struct cam_ed_qinfo *)camq_remove(&devq->send_queue,
3470 /*position*/0);
3474 CAMQ_HEAD);
3471 device = qinfo->device;
3472
3473 /*
3474 * If the device has been "frozen", don't attempt
3475 * to run it.
3476 */
3477 if (device->qfrozen_cnt > 0) {
3478 splx(ospl);
3479 continue;
3480 }
3481
3482 CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
3483 ("running device %p\n", device));
3484
3475 device = qinfo->device;
3476
3477 /*
3478 * If the device has been "frozen", don't attempt
3479 * to run it.
3480 */
3481 if (device->qfrozen_cnt > 0) {
3482 splx(ospl);
3483 continue;
3484 }
3485
3486 CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
3487 ("running device %p\n", device));
3488
3485 work_ccb = cam_ccbq_peek_ccb(&device->ccbq, 0);
3489 work_ccb = cam_ccbq_peek_ccb(&device->ccbq, CAMQ_HEAD);
3486 if (work_ccb == NULL) {
3487 printf("device on run queue with no ccbs???");
3488 splx(ospl);
3489 continue;
3490 }
3491
3492 if ((work_ccb->ccb_h.flags & CAM_HIGH_POWER) != 0) {
3493

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

3517 cam_ccbq_remove_ccb(&device->ccbq, work_ccb);
3518
3519 cam_ccbq_send_ccb(&device->ccbq, work_ccb);
3520 splx(ospl);
3521
3522 devq->send_openings--;
3523 devq->send_active++;
3524
3490 if (work_ccb == NULL) {
3491 printf("device on run queue with no ccbs???");
3492 splx(ospl);
3493 continue;
3494 }
3495
3496 if ((work_ccb->ccb_h.flags & CAM_HIGH_POWER) != 0) {
3497

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

3521 cam_ccbq_remove_ccb(&device->ccbq, work_ccb);
3522
3523 cam_ccbq_send_ccb(&device->ccbq, work_ccb);
3524 splx(ospl);
3525
3526 devq->send_openings--;
3527 devq->send_active++;
3528
3525 if (device->ccbq.queue.entries > 0) {
3526 qinfo->pinfo.priority =
3527 device->ccbq.queue.queue_array[0]->priority;
3529 if (device->ccbq.queue.entries > 0)
3528 xpt_schedule_dev_sendq(bus, device);
3530 xpt_schedule_dev_sendq(bus, device);
3529 } else {
3530 qinfo->pinfo.priority = CAM_PRIORITY_NONE;
3531 }
3532
3533 if (work_ccb && (work_ccb->ccb_h.flags & CAM_DEV_QFREEZE) != 0){
3534 /*
3535 * The client wants to freeze the queue
3536 * after this CCB is sent.
3537 */
3538 ospl = splcam();
3539 device->qfrozen_cnt++;

--- 2496 unchanged lines hidden ---
3531
3532 if (work_ccb && (work_ccb->ccb_h.flags & CAM_DEV_QFREEZE) != 0){
3533 /*
3534 * The client wants to freeze the queue
3535 * after this CCB is sent.
3536 */
3537 ospl = splcam();
3538 device->qfrozen_cnt++;

--- 2496 unchanged lines hidden ---