2 * Copyright (c) 1998,1999,2000
3 * Traakan, Inc., Los Altos, CA
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR 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
42 * NAME[,[CNUM,]SID[,LUN]
44 * The foregoing pattern is ambiguous. Here's the disambiguating rules:
45 * 1) If just a name is given, controller, sid, and lun are all
47 * 2) If one number comes after the device name (,sid) it is the
48 * SID; controller is set to -1, lun is set to 0
49 * 3) If two numbers come after the device name (,sid,lun), they are
50 * the SID and LUN; controller is set to -1
51 * 4) Three numbers after the device name are all three number fields.
56 ndmscsi_target_from_str (struct ndmscsi_target *targ, char *str)
61 NDMOS_MACRO_ZEROFILL (targ);
63 p = strchr (str, ',');
68 if (strlen (str) >= PATH_MAX) {
73 strcpy (targ->dev_name, str);
76 targ->controller = -1;
85 if (*p < '0' || '9' < *p) {
88 n1 = strtol (p, &p, 0);
89 if (*p != 0 && *p != ',') {
93 targ->controller = -1;
102 if (*p < '0' || '9' < *p) {
105 n2 = strtol (p, &p, 0);
109 targ->controller = -1;
118 if (*p < '0' || '9' < *p) {
121 n3 = strtol (p, &p, 0);
127 targ->controller = n1;
137 ndmscsi_open (struct ndmconn *conn, char *dev_name)
141 NDMC_WITH(ndmp9_scsi_open, NDMP9VER)
142 request->device = dev_name;
143 rc = NDMC_CALL(conn);
150 ndmscsi_close (struct ndmconn *conn)
154 NDMC_WITH_VOID_REQUEST(ndmp9_scsi_close, NDMP9VER)
155 rc = NDMC_CALL(conn);
162 ndmscsi_get_state (struct ndmconn *conn, struct ndmscsi_target *targ)
166 NDMOS_MACRO_ZEROFILL (targ);
168 NDMC_WITH_VOID_REQUEST(ndmp9_scsi_get_state, NDMP9VER)
169 rc = NDMC_CALL(conn);
170 targ->controller = reply->target_controller;
171 targ->sid = reply->target_id;
172 targ->lun = reply->target_lun;
179 ndmscsi_set_target (struct ndmconn *conn, struct ndmscsi_target *targ)
183 NDMC_WITH(ndmp9_scsi_set_target, NDMP9VER)
184 request->device = targ->dev_name;
185 request->target_controller = targ->controller;
186 request->target_id = targ->sid;
187 request->target_lun = targ->lun;
188 rc = NDMC_CALL(conn);
195 ndmscsi_use (struct ndmconn *conn, struct ndmscsi_target *targ)
200 rc = ndmscsi_close (conn);
204 rc = ndmscsi_open (conn, targ->dev_name);
207 if (targ->controller != -1 || targ->sid != -1 || targ->lun != -1) {
208 #ifndef NDMOS_OPTION_NO_NDMP4
209 if (conn->protocol_version == NDMP4VER) {
210 return -1; /* can't set target */
212 #endif /* !NDMOS_OPTION_NO_NDMP4 */
214 rc = ndmscsi_set_target (conn, targ);
216 ndmscsi_close (conn); /* best effort */
225 ndmscsi_execute (struct ndmconn *conn,
226 struct ndmscsi_request *req,
227 struct ndmscsi_target *targ)
232 rc = ndmscsi_use (conn, targ);
236 NDMC_WITH(ndmp9_scsi_execute_cdb, NDMP9VER)
237 request->cdb.cdb_len = req->n_cmd;
238 request->cdb.cdb_val = (char*)req->cmd;
240 switch (req->data_dir) {
241 case NDMSCSI_DD_NONE:
242 request->data_dir = NDMP9_SCSI_DATA_DIR_NONE;
246 request->data_dir = NDMP9_SCSI_DATA_DIR_IN;
247 request->datain_len = req->n_data_avail;
251 request->data_dir = NDMP9_SCSI_DATA_DIR_OUT;
252 request->dataout.dataout_len = req->n_data_avail;
253 request->dataout.dataout_val = (char*)req->data;
256 request->timeout = 300000; /* five minutes */
258 rc = NDMC_CALL (conn);
260 req->completion_status = NDMSCSI_CS_FAIL;
264 req->status_byte = reply->status;
265 req->n_data_done = 0;
266 req->n_sense_data = 0;
268 rc = reply->ext_sense.ext_sense_len;
270 if (rc > NDMSCSI_MAX_SENSE_DATA)
271 rc = NDMSCSI_MAX_SENSE_DATA;
273 req->n_sense_data = rc;
274 NDMOS_API_BCOPY (reply->ext_sense.ext_sense_val,
275 req->sense_data, rc);
278 switch (req->data_dir) {
280 req->n_data_done = reply->datain.datain_len;
281 if (req->n_data_done > 0) {
282 NDMOS_API_BCOPY (reply->datain.datain_val,
283 req->data, req->n_data_done);
288 req->n_data_done = reply->dataout_len;
291 req->completion_status = NDMSCSI_CS_GOOD;