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 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 35 /* 36 * there's a waitq_t per target device and one per HBA 37 */ 38 39 typedef struct ghd_q { 40 struct ghd_q *Q_nextp; /* ptr to next level of queuing */ 41 L2el_t Q_qhead; /* Q of waiting gcmds */ 42 long Q_nactive; /* current # of outstanding gcmds */ 43 long Q_maxactive; /* max gcmds to release concurrently */ 44 } Q_t; 45 46 #define GHD_WAITQ_INIT(qp, nxtp, maxactive) \ 47 (L2_INIT(&(qp)->Q_qhead), \ 48 (qp)->Q_nextp = (nxtp), \ 49 (qp)->Q_nactive = 0, \ 50 (qp)->Q_maxactive = (maxactive)) 51 /* 52 * one per target device 53 */ 54 typedef struct ghd_device { 55 Q_t gd_waitq; /* the queue structure for this device */ 56 L1el_t gd_devlist; /* all gdevs for a HBA are linked together */ 57 ulong_t gd_target; /* ... and are located by searching for */ 58 ulong_t gd_lun; /* ... a match on the (target,lun) values */ 59 60 L1_t gd_ilist; /* linked list of instances for this device */ 61 ulong_t gd_ninstances; /* # of instances for this device */ 62 } gdev_t; 63 64 #define GDEV_QHEAD(gdevp) ((gdevp)->gd_waitq.Q_qhead) 65 #define GDEV_NACTIVE(gdevp) ((gdevp)->gd_waitq.Q_nactive) 66 #define GDEV_MAXACTIVE(gdevp) ((gdevp)->gd_waitq.Q_maxactive) 67 68 /* 69 * Be careful, this macro assumes there's a least one 70 * target instance attached to this dev structure, Otherwise, l1_headp 71 * is NULL. 72 */ 73 #define GDEVP2GTGTP(gdevp) \ 74 (gtgt_t *)((gdevp)->gd_ilist.l1_headp->le_datap) 75 76 #define GDEV_NEXTP(gdevp) \ 77 ((gdevp)->gd_devlist.le_nextp \ 78 ? (gdev_t *)((gdevp)->gd_devlist.le_nextp->le_datap) \ 79 : (gdev_t *)NULL) 80 81 #define GDEV_QATTACH(gdevp, cccp, max) { \ 82 GHD_WAITQ_INIT(&(gdevp)->gd_waitq, &(cccp)->ccc_waitq, (max)); \ 83 L1EL_INIT(&gdevp->gd_devlist); \ 84 L1HEADER_INIT(&gdevp->gd_ilist); \ 85 /* add the per device structure to the HBA's device list */ \ 86 L1_add(&(cccp)->ccc_devs, &(gdevp)->gd_devlist, (gdevp)); \ 87 } 88 89 #define GDEV_QDETACH(gdevp, cccp) \ 90 L1_delete(&(cccp)->ccc_devs, &(gdevp)->gd_devlist) 91 92 /* 93 * GHD target structure, one per attached target driver instance 94 */ 95 typedef struct ghd_target_instance { 96 L1el_t gt_ilist; /* list of other instances for this device */ 97 gdev_t *gt_gdevp; /* ptr to info shared by all instances */ 98 99 /* this would be ccc_t, but is circular with ghd.h. sigh. */ 100 struct cmd_ctl *gt_ccc; /* ptr to HBA per-instance struct */ 101 102 ulong_t gt_maxactive; /* max gcmds to release concurrently */ 103 void *gt_hba_private; /* ptr to soft state of this HBA instance */ 104 void *gt_tgt_private; /* ptr to soft state of this target instance */ 105 size_t gt_size; /* size including tgt_private */ 106 ushort_t gt_target; /* target number of this instance */ 107 uchar_t gt_lun; /* LUN of this instance */ 108 } gtgt_t; 109 110 #define GTGTP2TARGET(gtgtp) ((gtgtp)->gt_tgt_private) 111 #define GTGTP2HBA(gtgtp) ((gtgtp)->gt_hba_private) 112 #define GTGTP2GDEVP(gtgtp) ((gtgtp)->gt_gdevp) 113 114 #define GTGT_INIT(gtgtp) L1EL_INIT(&(gtgtp)->gt_ilist) 115 116 /* Add the per instance structure to the per device list */ 117 #define GTGT_ATTACH(gtgtp, gdevp) { \ 118 (gdevp)->gd_ninstances++; \ 119 L1_add(&(gdevp)->gd_ilist, &(gtgtp)->gt_ilist, (gtgtp)); \ 120 } 121 122 123 /* remove this per-instance-structure from the device list */ 124 #define GTGT_DEATTACH(gtgtp, gdevp) { \ 125 (gdevp)->gd_ninstances--; \ 126 L1_delete(&(gdevp)->gd_ilist, &(gtgtp)->gt_ilist); \ 127 } 128 129 #ifdef __cplusplus 130 } 131 #endif 132 #endif /* _GHD_QUEUE_H */ 133