1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _GHD_WAITQ_H 28 #define _GHD_WAITQ_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 37 /* 38 * there's a waitq_t per target device and one per HBA 39 */ 40 41 typedef struct ghd_q { 42 struct ghd_q *Q_nextp; /* ptr to next level of queuing */ 43 L2el_t Q_qhead; /* Q of waiting gcmds */ 44 long Q_nactive; /* current # of outstanding gcmds */ 45 long Q_maxactive; /* max gcmds to release concurrently */ 46 } Q_t; 47 48 #define GHD_WAITQ_INIT(qp, nxtp, maxactive) \ 49 (L2_INIT(&(qp)->Q_qhead), \ 50 (qp)->Q_nextp = (nxtp), \ 51 (qp)->Q_nactive = 0, \ 52 (qp)->Q_maxactive = (maxactive)) 53 /* 54 * one per target device 55 */ 56 typedef struct ghd_device { 57 Q_t gd_waitq; /* the queue structure for this device */ 58 L1el_t gd_devlist; /* all gdevs for a HBA are linked together */ 59 ulong_t gd_target; /* ... and are located by searching for */ 60 ulong_t gd_lun; /* ... a match on the (target,lun) values */ 61 62 L1_t gd_ilist; /* linked list of instances for this device */ 63 ulong_t gd_ninstances; /* # of instances for this device */ 64 } gdev_t; 65 66 #define GDEV_QHEAD(gdevp) ((gdevp)->gd_waitq.Q_qhead) 67 #define GDEV_NACTIVE(gdevp) ((gdevp)->gd_waitq.Q_nactive) 68 #define GDEV_MAXACTIVE(gdevp) ((gdevp)->gd_waitq.Q_maxactive) 69 70 /* 71 * Be careful, this macro assumes there's a least one 72 * target instance attached to this dev structure, Otherwise, l1_headp 73 * is NULL. 74 */ 75 #define GDEVP2GTGTP(gdevp) \ 76 (gtgt_t *)((gdevp)->gd_ilist.l1_headp->le_datap) 77 78 #define GDEV_NEXTP(gdevp) \ 79 ((gdevp)->gd_devlist.le_nextp \ 80 ? (gdev_t *)((gdevp)->gd_devlist.le_nextp->le_datap) \ 81 : (gdev_t *)NULL) 82 83 #define GDEV_QATTACH(gdevp, cccp, max) { \ 84 GHD_WAITQ_INIT(&(gdevp)->gd_waitq, &(cccp)->ccc_waitq, (max)); \ 85 L1EL_INIT(&gdevp->gd_devlist); \ 86 L1HEADER_INIT(&gdevp->gd_ilist); \ 87 /* add the per device structure to the HBA's device list */ \ 88 L1_add(&(cccp)->ccc_devs, &(gdevp)->gd_devlist, (gdevp)); \ 89 } 90 91 #define GDEV_QDETACH(gdevp, cccp) \ 92 L1_delete(&(cccp)->ccc_devs, &(gdevp)->gd_devlist) 93 94 /* 95 * GHD target structure, one per attached target driver instance 96 */ 97 typedef struct ghd_target_instance { 98 L1el_t gt_ilist; /* list of other instances for this device */ 99 gdev_t *gt_gdevp; /* ptr to info shared by all instances */ 100 101 /* this would be ccc_t, but is circular with ghd.h. sigh. */ 102 struct cmd_ctl *gt_ccc; /* ptr to HBA per-instance struct */ 103 104 ulong_t gt_maxactive; /* max gcmds to release concurrently */ 105 void *gt_hba_private; /* ptr to soft state of this HBA instance */ 106 void *gt_tgt_private; /* ptr to soft state of this target instance */ 107 size_t gt_size; /* size including tgt_private */ 108 ushort_t gt_target; /* target number of this instance */ 109 uchar_t gt_lun; /* LUN of this instance */ 110 } gtgt_t; 111 112 #define GTGTP2TARGET(gtgtp) ((gtgtp)->gt_tgt_private) 113 #define GTGTP2HBA(gtgtp) ((gtgtp)->gt_hba_private) 114 #define GTGTP2GDEVP(gtgtp) ((gtgtp)->gt_gdevp) 115 116 #define GTGT_INIT(gtgtp) L1EL_INIT(&(gtgtp)->gt_ilist) 117 118 /* Add the per instance structure to the per device list */ 119 #define GTGT_ATTACH(gtgtp, gdevp) { \ 120 (gdevp)->gd_ninstances++; \ 121 L1_add(&(gdevp)->gd_ilist, &(gtgtp)->gt_ilist, (gtgtp)); \ 122 } 123 124 125 /* remove this per-instance-structure from the device list */ 126 #define GTGT_DEATTACH(gtgtp, gdevp) { \ 127 (gdevp)->gd_ninstances--; \ 128 L1_delete(&(gdevp)->gd_ilist, &(gtgtp)->gt_ilist); \ 129 } 130 131 #ifdef __cplusplus 132 } 133 #endif 134 #endif /* _GHD_QUEUE_H */ 135