8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / uts / sun / io / dada / conf / dcd_confsubr.c
blob901003d05670064a0df8e4bc484bbd266d199225
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * Utility DCD configuration routines.
33 #include <sys/dada/dada.h>
34 #include <sys/modctl.h>
36 extern struct mod_ops mod_miscops;
38 static struct modlmisc modlmisc = {
39 &mod_miscops, /* Type of module */
40 " ATA Bus Utility Routines"
43 static struct modlinkage modlinkage = {
44 MODREV_1, (void *)&modlmisc, NULL
49 static int dcd_test(struct dcd_pkt *);
50 void makecommand(struct dcd_pkt *, int, uchar_t, uint32_t,
51 uchar_t, uint32_t, uchar_t, uchar_t);
53 int
54 _init()
57 (void) dcd_initialize_hba_interface();
59 return (mod_install(&modlinkage));
64 * There is no _fini() routine because this module is never unloaded.
66 int
67 _info(modinfop)
68 struct modinfo *modinfop;
71 return (mod_info(&modlinkage, modinfop));
75 * The implementation of dcd_probe allows a particular HBA to intercept the call
76 * for any post or pre-processing it may need. The default, if the HBA does not
77 * override it, is to call dcd_hba_probe.
79 int
80 dcd_probe(struct dcd_device *devp, int (*callback)())
82 dcd_hba_tran_t *hba_tran = devp->dcd_address->a_hba_tran;
84 if (hba_tran->tran_tgt_probe != NULL) {
85 return ((*hba_tran->tran_tgt_probe)(devp, callback));
86 } else {
87 return (dcd_hba_probe(devp, callback));
92 * Undo the dcd_probe
94 void
95 dcd_unprobe(struct dcd_device *devp)
97 if (devp->dcd_ident) {
98 kmem_free((caddr_t)devp->dcd_ident, SUN_IDENTSIZE);
99 devp->dcd_ident = (struct dcd_identify *)NULL;
103 #define ROUTE (devp->dcd_address)
106 dcd_hba_probe(struct dcd_device *devp, int (*callback)())
109 struct dcd_pkt *ident_pkt = NULL;
110 int rval = DCDPROBE_NOMEM;
111 struct buf *ident_bp = NULL;
112 int (*cb_flag)();
114 if (devp->dcd_ident == NULL) {
115 #ifdef DEBUG1
116 printf("Dcd_ident is NULL\n");
117 #endif
119 devp->dcd_ident = (struct dcd_identify *)
120 kmem_alloc(SUN_IDENTSIZE, ((callback == SLEEP_FUNC)?
121 KM_SLEEP : KM_NOSLEEP));
122 if (devp->dcd_ident == NULL) {
123 goto out;
127 if (callback != SLEEP_FUNC && callback != NULL_FUNC) {
128 cb_flag = NULL_FUNC;
129 } else {
130 cb_flag = callback;
133 ident_bp = dcd_alloc_consistent_buf(ROUTE, (struct buf *)NULL,
134 (uint_t)SUN_IDENTSIZE, B_READ, cb_flag, NULL);
135 if (ident_bp == NULL) {
136 goto out;
139 ident_pkt = dcd_init_pkt(ROUTE, (struct dcd_pkt *)NULL,
140 ident_bp, sizeof (struct dcd_cmd), 2, 0,
141 PKT_CONSISTENT,
142 callback, NULL);
144 if (ident_pkt == NULL) {
145 if (ident_bp->b_error == 0)
146 rval = DCDPROBE_NOMEM_CB;
147 goto out;
150 bp_mapin(ident_bp);
152 bzero((caddr_t)devp->dcd_ident, SUN_IDENTSIZE);
154 makecommand(ident_pkt, FLAG_NOINTR, IDENTIFY, 0, ADD_LBA_MODE,
155 SUN_IDENTSIZE, DATA_READ, 0);
158 * The first identify will tell us whether the target responded
159 * or not.
162 if (dcd_test(ident_pkt) < 0) {
163 #ifdef DEBUG1
164 printf("dcd_test: failed\n");
165 #endif
166 if (ident_pkt->pkt_reason == CMD_INCOMPLETE) {
167 rval = DCDPROBE_NORESP;
168 goto out;
169 } else {
171 * retry one more time
173 if (dcd_test(ident_pkt) < 0) {
174 rval = DCDPROBE_FAILURE;
175 goto out;
180 #ifdef DEBUG1
181 printf("Pkt reason %x, scsbp %x\n", ident_pkt->pkt_reason,
182 *ident_pkt->pkt_scbp);
183 #endif
185 * If we are lucky, this identify succeeded
187 if ((ident_pkt->pkt_reason == CMD_CMPLT) &&
188 (((*ident_pkt->pkt_scbp) & STATUS_ATA_MASK) == 0)) {
189 goto done;
193 * the second inquiry, allows the host adapters to try again.
195 if (dcd_test(ident_pkt) < 0) {
196 if (ident_pkt->pkt_reason == CMD_INCOMPLETE)
197 rval = DCDPROBE_NORESP;
198 else
199 rval = DCDPROBE_FAILURE;
200 goto out;
204 * At this point we are guarenteed that something responded
205 * to this target. We don't know yest what kind of device it is.
208 if (dcd_test(ident_pkt) < 0) {
209 rval = DCDPROBE_FAILURE;
210 goto out;
213 done:
215 * If we got no error then receive the indentify data,
217 if ((ident_pkt->pkt_state & STATE_XFERRED_DATA) == 0 &&
218 ident_pkt->pkt_resid > 0) {
219 rval = DCDPROBE_NONCCS;
220 } else {
221 bcopy((caddr_t)ident_bp->b_un.b_addr,
222 (caddr_t)devp->dcd_ident, SUN_IDENTSIZE);
223 rval = DCDPROBE_EXISTS;
226 out:
227 if (ident_pkt) {
228 dcd_destroy_pkt(ident_pkt);
230 if (ident_bp) {
231 dcd_free_consistent_buf(ident_bp);
233 return (rval);
237 static int
238 dcd_test(struct dcd_pkt *pkt)
241 int rval = -1;
243 pkt->pkt_flags |= FLAG_NOINTR;
244 pkt->pkt_time = DCD_POLL_TIMEOUT;
246 #ifdef DEBUG1
247 printf("flags %x: timeout %x\n", pkt->pkt_flags, pkt->pkt_time);
248 #endif
250 if (dcd_transport(pkt) != TRAN_ACCEPT) {
251 goto error;
252 } else if (pkt->pkt_reason == CMD_INCOMPLETE &&
253 pkt->pkt_state == 0) {
254 goto error;
255 } else if (pkt->pkt_reason != CMD_CMPLT) {
256 goto error;
257 } else if (((*pkt->pkt_scbp) & STATUS_ATA_MASK) == STATUS_ATA_BUSY) {
258 rval = 0;
259 } else {
260 rval = 0;
262 error:
263 #ifdef DEBUG1
264 printf("dcd_test: rval is %x\n", rval);
265 #endif
267 return (rval);
270 void
271 makecommand(struct dcd_pkt *pkt,
272 int flags,
273 uchar_t command,
274 uint32_t block,
275 uchar_t address_mode,
276 uint32_t size,
277 uchar_t direction,
278 uchar_t features)
281 struct dcd_cmd *cdbp = (struct dcd_cmd *)pkt->pkt_cdbp;
283 cdbp->cmd = command;
284 cdbp->sector_num.lba_num = block;
285 cdbp->address_mode = address_mode;
286 cdbp->direction = direction;
287 cdbp->size = size; /* Size in bytes */
288 cdbp->features = features;
290 pkt->pkt_flags = flags;
291 #ifdef DEBUG1
292 printf("pkt flags set in dada %x\n", pkt->pkt_flags);
294 printf("command %x, flags %x, block %x, address_mode %x, size %x\n",
295 command, flags, block, address_mode, size);
296 #endif