1 /* $Id: scsi-device.c,v 1.8 2009/11/08 17:17:42 fredette Exp $ */
2 
3 /* scsi/scsi-device.c - implementation of generic SCSI device support: */
4 
5 /*
6  * Copyright (c) 2003 Matt Fredette
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed by Matt Fredette.
20  * 4. The name of the author may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
27  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #include <tme/common.h>
37 _TME_RCSID("$Id: scsi-device.c,v 1.8 2009/11/08 17:17:42 fredette Exp $");
38 
39 /* includes: */
40 #include <tme/scsi/scsi-device.h>
41 #include <tme/scsi/scsi-msg.h>
42 #include <tme/scsi/scsi-cdb.h>
43 
44 /* macros: */
45 
46 /* the callout flags: */
47 #define TME_SCSI_DEVICE_CALLOUT_CHECK		(0)
48 #define TME_SCSI_DEVICE_CALLOUT_RUNNING		TME_BIT(0)
49 #define TME_SCSI_DEVICE_CALLOUTS_MASK		(-2)
50 #define  TME_SCSI_DEVICE_CALLOUT_CYCLE		TME_BIT(1)
51 
52 /* the SCSI device callout function.  it must be called with the mutex locked: */
53 static void
_tme_scsi_device_callout(struct tme_scsi_device * scsi_device,int new_callouts)54 _tme_scsi_device_callout(struct tme_scsi_device *scsi_device,
55 			 int new_callouts)
56 {
57   struct tme_scsi_connection *conn_scsi;
58   int callouts, later_callouts;
59   int rc;
60   tme_uint32_t events;
61   tme_uint32_t actions;
62   const struct tme_scsi_dma *dma;
63   struct tme_scsi_dma dma_buffer;
64 
65   /* add in any new callouts: */
66   scsi_device->tme_scsi_device_callout_flags |= new_callouts;
67 
68   /* if this function is already running in another thread, simply
69      return now.  the other thread will do our work: */
70   if (scsi_device->tme_scsi_device_callout_flags
71       & TME_SCSI_DEVICE_CALLOUT_RUNNING) {
72     return;
73   }
74 
75   /* callouts are now running: */
76   scsi_device->tme_scsi_device_callout_flags
77     |= TME_SCSI_DEVICE_CALLOUT_RUNNING;
78 
79   /* assume that we won't need any later callouts: */
80   later_callouts = 0;
81 
82   /* loop while callouts are needed: */
83   for (; ((callouts
84 	   = scsi_device->tme_scsi_device_callout_flags)
85 	  & TME_SCSI_DEVICE_CALLOUTS_MASK); ) {
86 
87     /* clear the needed callouts: */
88     scsi_device->tme_scsi_device_callout_flags
89       = (callouts
90 	 & ~TME_SCSI_DEVICE_CALLOUTS_MASK);
91     callouts
92       &= TME_SCSI_DEVICE_CALLOUTS_MASK;
93 
94     /* get this card's SCSI connection: */
95     conn_scsi = scsi_device->tme_scsi_device_connection;
96 
97     /* if we need to call out a SCSI bus cycle: */
98     if (callouts & TME_SCSI_DEVICE_CALLOUT_CYCLE) {
99 
100       /* if the bus is busy: */
101       if (scsi_device->tme_scsi_device_control
102 	  & TME_SCSI_SIGNAL_BSY) {
103 
104 	/* run a target information transfer phase DMA sequence: */
105 	events = TME_SCSI_EVENT_NONE;
106 	actions = TME_SCSI_ACTION_DMA_TARGET;
107 	dma_buffer = scsi_device->tme_scsi_device_dma;
108 	dma = &dma_buffer;
109       }
110 
111       /* otherwise, the bus is not busy: */
112       else {
113 
114 	/* wait to be selected: */
115 	events = TME_SCSI_EVENT_SELECTED | TME_SCSI_EVENT_IDS_SELF(TME_BIT(scsi_device->tme_scsi_device_id));
116 	actions = TME_SCSI_ACTION_RESPOND_SELECTED;
117 	dma = NULL;
118       }
119 
120       /* unlock the mutex: */
121       tme_mutex_unlock(&scsi_device->tme_scsi_device_mutex);
122 
123       /* do the callout: */
124       rc = (conn_scsi != NULL
125 	    ? ((*conn_scsi->tme_scsi_connection_cycle)
126 	       (conn_scsi,
127 		scsi_device->tme_scsi_device_control,
128 		0,
129 		events,
130 		actions,
131 		dma))
132 	    : TME_OK);
133 
134       /* lock the mutex: */
135       tme_mutex_lock(&scsi_device->tme_scsi_device_mutex);
136 
137       /* if the callout was unsuccessful, remember that at some later
138 	 time this callout should be attempted again: */
139       if (rc != TME_OK) {
140 	later_callouts |= TME_SCSI_DEVICE_CALLOUT_CYCLE;
141       }
142     }
143 
144   }
145 
146   /* put in any later callouts, and clear that callouts are running: */
147   scsi_device->tme_scsi_device_callout_flags = later_callouts;
148 }
149 
150 /* when a device is the target, this enters a new bus phase: */
151 void
tme_scsi_device_target_phase(struct tme_scsi_device * scsi_device,tme_scsi_control_t control)152 tme_scsi_device_target_phase(struct tme_scsi_device *scsi_device,
153 			     tme_scsi_control_t control)
154 {
155   const char *info_type;
156 
157   /* set the phase: */
158   scsi_device->tme_scsi_device_control = control;
159 
160   /* if we are not freeing the bus: */
161   if (control & TME_SCSI_SIGNAL_BSY) {
162 
163     /* assume that we will not dump the information transferred: */
164     info_type = NULL;
165 
166     /* XXX parity? */
167 
168     /* dispatch on the phase: */
169     switch (TME_SCSI_PHASE(control)) {
170 
171       /* for the DATA_OUT and DATA_IN phases, we assume that
172 	 the caller has already set up the DMA structure: */
173     case TME_SCSI_PHASE_DATA_IN:
174       info_type = "DATA_IN";
175       /* FALLTHROUGH */
176     case TME_SCSI_PHASE_DATA_OUT:
177       break;
178 
179       /* for the COMMAND phase, begin by transferring the
180 	 first byte of the CDB: */
181     case TME_SCSI_PHASE_COMMAND:
182       assert ((scsi_device->tme_scsi_device_dma.tme_scsi_dma_flags
183 	       & TME_SCSI_DMA_WIDTH)
184 	      == TME_SCSI_DMA_8BIT);
185       scsi_device->tme_scsi_device_dma.tme_scsi_dma_in
186 	= &scsi_device->tme_scsi_device_cdb[0];
187       scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid
188 	= 1;
189       break;
190 
191       /* for the STATUS phase, transfer the status byte: */
192     case TME_SCSI_PHASE_STATUS:
193       assert ((scsi_device->tme_scsi_device_dma.tme_scsi_dma_flags
194 	       & TME_SCSI_DMA_WIDTH)
195 	      == TME_SCSI_DMA_8BIT);
196       scsi_device->tme_scsi_device_dma.tme_scsi_dma_out
197 	= &scsi_device->tme_scsi_device_status;
198       scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid
199 	= 1;
200       info_type = "STATUS";
201       break;
202 
203       /* for the MESSAGE_OUT phase, begin by transferring the
204 	 first byte of the message: */
205     case TME_SCSI_PHASE_MESSAGE_OUT:
206       assert ((scsi_device->tme_scsi_device_dma.tme_scsi_dma_flags
207 	       & TME_SCSI_DMA_WIDTH)
208 	      == TME_SCSI_DMA_8BIT);
209       scsi_device->tme_scsi_device_dma.tme_scsi_dma_in
210 	= &scsi_device->tme_scsi_device_msg[0];
211       scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid
212 	= 1;
213       break;
214 
215       /* for the MESSAGE_IN phase, transfer the entire message: */
216     case TME_SCSI_PHASE_MESSAGE_IN:
217       assert ((scsi_device->tme_scsi_device_dma.tme_scsi_dma_flags
218 	       & TME_SCSI_DMA_WIDTH)
219 	      == TME_SCSI_DMA_8BIT);
220       scsi_device->tme_scsi_device_dma.tme_scsi_dma_out
221 	= &scsi_device->tme_scsi_device_msg[0];
222 
223       /* the total message length depends on the message type: */
224 
225       /* "The extended message length specifies the length in bytes of
226 	 the extended message code plus the extended message arguments
227 	 to follow.  Therefore, the total length of the message is
228 	 equal to the extended message length plus two.  A value of
229 	 zero for the extended message length indicates 256 bytes
230 	 follow." */
231       if (scsi_device->tme_scsi_device_msg[0]
232 	  == TME_SCSI_MSG_EXTENDED) {
233 	scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid
234 	  = ((scsi_device->tme_scsi_device_msg[1]
235 	      == 0)
236 	     ? (2 + 256)
237 	     : (2 + scsi_device->tme_scsi_device_msg[1]));
238       }
239 
240       else if (TME_SCSI_MSG_IS_2(scsi_device->tme_scsi_device_msg[0])) {
241 	scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid
242 	  = 2;
243       }
244 
245       else {
246 	assert (TME_SCSI_MSG_IS_1(scsi_device->tme_scsi_device_msg[0]));
247 	scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid
248 	  = 1;
249       }
250       info_type = "MESSAGE_IN";
251       break;
252 
253     default:
254       abort();
255     }
256 
257     /* if we can, dump up to 128 bytes of information: */
258     if (info_type != NULL) {
259       tme_log_start(&scsi_device->tme_scsi_device_element->tme_element_log_handle,
260 		    2000, TME_OK) {
261 	unsigned int byte_i, count;
262 	count = TME_MIN(scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid,
263 			128);
264 	tme_log_part(&scsi_device->tme_scsi_device_element->tme_element_log_handle,
265 		     "%s:", info_type);
266 	for (byte_i = 0; byte_i < count ; byte_i++) {
267 	  tme_log_part(&scsi_device->tme_scsi_device_element->tme_element_log_handle,
268 		       " 0x%02x",
269 		       scsi_device->tme_scsi_device_dma.tme_scsi_dma_out[byte_i]);
270 	}
271 	if (count < scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid) {
272 	  tme_log_part(&scsi_device->tme_scsi_device_element->tme_element_log_handle,
273 		       " ...");
274 	}
275       } tme_log_finish(&scsi_device->tme_scsi_device_element->tme_element_log_handle);
276     }
277   }
278 }
279 
280 /* this handles a SCSI bus cycle: */
281 static int
_tme_scsi_device_cycle(struct tme_scsi_connection * conn_scsi,tme_scsi_control_t control_new,tme_scsi_data_t data,tme_uint32_t events,tme_uint32_t actions,const struct tme_scsi_dma * dma)282 _tme_scsi_device_cycle(struct tme_scsi_connection *conn_scsi,
283 		       tme_scsi_control_t control_new,
284 		       tme_scsi_data_t data,
285 		       tme_uint32_t events,
286 		       tme_uint32_t actions,
287 		       const struct tme_scsi_dma *dma)
288 {
289   struct tme_scsi_device *scsi_device;
290   int new_callouts;
291   tme_scsi_control_t control_old;
292   unsigned long count;
293   void (*do_cdb) _TME_P((struct tme_scsi_device *,
294 			 tme_scsi_control_t,
295 			 tme_scsi_control_t));
296 
297   /* recover our device: */
298   scsi_device = conn_scsi->tme_scsi_connection.tme_connection_element->tme_element_private;
299 
300   /* assume that we won't need any new callouts: */
301   new_callouts = 0;
302 
303   /* lock the mutex: */
304   tme_mutex_lock(&scsi_device->tme_scsi_device_mutex);
305 
306   /* get the last bus state: */
307   control_old = scsi_device->tme_scsi_device_control;
308 
309   /* if we last knew the bus to be free, we must now be selected: */
310   if (!(control_old
311 	& TME_SCSI_SIGNAL_BSY)) {
312 
313     /* "SCSI devices indicate their ability to accommodate more than
314        the COMMAND COMPLETE message by asserting or responding to the
315        ATN signal.  The initiator indicates this in the SELECTION
316        phase by asserting ATN prior to the SCSI bus condition of SEL
317        true, and BSY false.  The target indicates its ability to
318        accommodate more messages by responding to the ATTENTION
319        condition with the MESSAGE OUT phase after going through the
320        SELECTION phase." */
321 
322     /* XXX parity? */
323     scsi_device->tme_scsi_device_dma.tme_scsi_dma_flags
324       = TME_SCSI_DMA_8BIT;
325     tme_scsi_device_target_phase(scsi_device,
326 				 TME_SCSI_SIGNAL_BSY
327 				 | ((control_new
328 				     & TME_SCSI_SIGNAL_ATN)
329 				    ? TME_SCSI_PHASE_MESSAGE_OUT
330 				    : TME_SCSI_PHASE_COMMAND));
331 
332     /* no LUN has been addressed yet: */
333     scsi_device->tme_scsi_device_addressed_lun
334       = -1;
335   }
336 
337   /* otherwise, we had the bus in some phase: */
338   else {
339 
340     /* if we didn't transfer all of the bytes we wanted, something
341        went wrong with the initiator - probably the bus was reset: */
342     assert (dma != NULL);
343     scsi_device->tme_scsi_device_dma = *dma;
344     if (scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid > 0) {
345 
346       /* return to the bus-free phase: */
347       scsi_device->tme_scsi_device_control
348 	= 0;
349 
350       /* log the forced bus free: */
351       tme_log(&scsi_device->tme_scsi_device_element->tme_element_log_handle,
352 	      1000, TME_OK,
353 	      (&scsi_device->tme_scsi_device_element->tme_element_log_handle,
354 	       _("short transfer, control now 0x%04x, forced bus free"),
355 		 control_new));
356 
357       /* XXX callback? */
358     }
359 
360     /* otherwise, we did transfer all of the bytes we wanted: */
361     else {
362 
363       /* dispatch on the previous bus phase: */
364       switch (TME_SCSI_PHASE(control_old)) {
365       case TME_SCSI_PHASE_MESSAGE_OUT:
366 
367 	/* calculate how many message bytes we have transferred: */
368 	count = (scsi_device->tme_scsi_device_dma.tme_scsi_dma_in
369 		 - &scsi_device->tme_scsi_device_msg[0]);
370 
371 	/* dispatch on the first byte of the message: */
372 
373 	/* if this is an extended message: */
374 	if (scsi_device->tme_scsi_device_msg[0]
375 	    == TME_SCSI_MSG_EXTENDED) {
376 
377 	  /* if we have only received the first message byte, receive
378 	     the next byte, which will give us the total length of the
379 	     message: */
380 	  if (count == 1) {
381 	    scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid
382 	      = 1;
383 	  }
384 
385 	  /* if we have received the second message byte, we now know
386 	     the total length of the message: */
387 	  else if (count == 2) {
388 	    scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid
389 	      = ((scsi_device->tme_scsi_device_msg[1]
390 		  == 0)
391 		 ? 256
392 		 : scsi_device->tme_scsi_device_msg[1]);
393 	  }
394 
395 	  /* otherwise, we must have received all of the message: */
396 	}
397 
398 	/* if this is a two-byte message: */
399 	else if (TME_SCSI_MSG_IS_2(scsi_device->tme_scsi_device_msg[0])) {
400 
401 	  /* if we have only received the first message byte,
402 	     receive the second message byte: */
403 	  if (count == 1) {
404 	    scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid
405 	      = 1;
406 	  }
407 
408 	  /* otherwise, we must have received all of the message: */
409 	}
410 
411 	/* otherwise, this must be a one-byte message, and we have
412 	   received all of it: */
413 	else {
414 	  assert (TME_SCSI_MSG_IS_1(scsi_device->tme_scsi_device_msg[0]));
415 	}
416 
417 	/* if we have received all of the message: */
418 	if (scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid == 0) {
419 
420 	  /* log the message: */
421 	  tme_log_start(&scsi_device->tme_scsi_device_element->tme_element_log_handle,
422 			1000, TME_OK) {
423 	    unsigned int byte_i;
424 	    tme_log_part(&scsi_device->tme_scsi_device_element->tme_element_log_handle,
425 	                 _("MESSAGE_OUT:"));
426 	    for (byte_i = 0; byte_i < count ; byte_i++) {
427 	      tme_log_part(&scsi_device->tme_scsi_device_element->tme_element_log_handle,
428 			   " 0x%02x",
429 			   scsi_device->tme_scsi_device_msg[byte_i]);
430 	    }
431 	  } tme_log_finish(&scsi_device->tme_scsi_device_element->tme_element_log_handle);
432 
433 	  /* "Normally, the initiator negates ATN while REQ is true
434 	     and ACK is false during the last REQ/ACK handshake of the
435 	     MESSAGE OUT phase." */
436 	  tme_scsi_device_target_phase(scsi_device,
437 				       TME_SCSI_SIGNAL_BSY
438 				       | ((control_new
439 					   & TME_SCSI_SIGNAL_ATN)
440 					  ? TME_SCSI_PHASE_MESSAGE_OUT
441 					  : TME_SCSI_PHASE_COMMAND));
442 
443 	  /* call out for the message: */
444 	  (*((scsi_device->tme_scsi_device_msg[0]
445 	      == TME_SCSI_MSG_EXTENDED)
446 	     ? (scsi_device->tme_scsi_device_do_msg_ext
447 		[scsi_device->tme_scsi_device_msg[2]])
448 	     : (scsi_device->tme_scsi_device_do_msg
449 		[TME_MIN(scsi_device->tme_scsi_device_msg[0],
450 			 TME_SCSI_MSG_IDENTIFY)])))
451 	    (scsi_device,
452 	     control_old,
453 	     control_new);
454 	}
455 
456 	break;
457 
458       case TME_SCSI_PHASE_COMMAND:
459 
460 	/* calculate how many message bytes we have transferred: */
461 	count = (scsi_device->tme_scsi_device_dma.tme_scsi_dma_in
462 		 - &scsi_device->tme_scsi_device_cdb[0]);
463 
464 	/* if we have only transferred the first byte: */
465 	if (count == 1) {
466 
467 	  /* dispatch on the CDB group: */
468 	  switch (scsi_device->tme_scsi_device_cdb[0]
469 		  & TME_SCSI_CDB_GROUP_MASK) {
470 
471 	  case TME_SCSI_CDB_GROUP_0:
472 	    scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid
473 	      = TME_SCSI_CDB_GROUP_0_LEN;
474 	    break;
475 	  case TME_SCSI_CDB_GROUP_1:
476 	    scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid
477 	      = TME_SCSI_CDB_GROUP_1_LEN;
478 	    break;
479 	  case TME_SCSI_CDB_GROUP_2:
480 	    scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid
481 	      = TME_SCSI_CDB_GROUP_2_LEN;
482 	    break;
483 	  case TME_SCSI_CDB_GROUP_4:
484 	    scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid
485 	      = TME_SCSI_CDB_GROUP_4_LEN;
486 	    break;
487 	  case TME_SCSI_CDB_GROUP_5:
488 	    scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid
489 	      = TME_SCSI_CDB_GROUP_5_LEN;
490 	    break;
491 
492 	  case TME_SCSI_CDB_GROUP_3:
493 	  case TME_SCSI_CDB_GROUP_6:
494 	  case TME_SCSI_CDB_GROUP_7:
495 	  default:
496 	    abort();
497 	  }
498 
499 	  /* we have already transferred the first byte of the CDB: */
500 	  scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid--;
501 	  break;
502 	}
503 
504 	/* otherwise, we must have transferred all of the command: */
505 	else {
506 
507 	  /* log the CDB: */
508 	  tme_log_start(&scsi_device->tme_scsi_device_element->tme_element_log_handle,
509 			1000, TME_OK) {
510 	    unsigned int byte_i;
511 	    tme_log_part(&scsi_device->tme_scsi_device_element->tme_element_log_handle,
512 	                 _("CDB:"));
513 	    for (byte_i = 0; byte_i < count ; byte_i++) {
514 	      tme_log_part(&scsi_device->tme_scsi_device_element->tme_element_log_handle,
515 			   " 0x%02x",
516 			   scsi_device->tme_scsi_device_cdb[byte_i]);
517 	    }
518 	  } tme_log_finish(&scsi_device->tme_scsi_device_element->tme_element_log_handle);
519 
520 	  /* if the addressed LUN is valid: */
521 	  if (((*scsi_device->tme_scsi_device_address_lun)
522 	       (scsi_device))
523 	      == TME_OK) {
524 
525 	    /* if this command is illegal: */
526 	    do_cdb
527 	      = (scsi_device->tme_scsi_device_do_cdb
528 		 [scsi_device->tme_scsi_device_cdb[0]]);
529 	    if (__tme_predict_false(do_cdb == NULL)) {
530 
531 	      /* use the illegal command handler: */
532 	      do_cdb = tme_scsi_device_cdb_illegal;
533 	    }
534 
535 	    /* call out for the CDB: */
536 	    (*do_cdb)
537 	      (scsi_device,
538 	       control_old,
539 	       control_new);
540 	  }
541 	}
542 
543 	break;
544 
545 	/* all of these phases just cause phase callbacks: */
546       case TME_SCSI_PHASE_STATUS:
547       case TME_SCSI_PHASE_MESSAGE_IN:
548       case TME_SCSI_PHASE_DATA_OUT:
549       case TME_SCSI_PHASE_DATA_IN:
550 	(*scsi_device->tme_scsi_device_phase)
551 	  (scsi_device,
552 	   control_old,
553 	   control_new);
554 	break;
555 
556       default: abort();
557       }
558     }
559   }
560 
561   /* call out a new SCSI cycle: */
562   new_callouts |= TME_SCSI_DEVICE_CALLOUT_CYCLE;
563 
564   /* make any needed callouts: */
565   _tme_scsi_device_callout(scsi_device, new_callouts);
566 
567   /* unlock the mutex: */
568   tme_mutex_unlock(&scsi_device->tme_scsi_device_mutex);
569 
570   return (TME_OK);
571 }
572 
573 /* when a device is the target, this frees the bus: */
_TME_SCSI_DEVICE_PHASE_DECL(tme_scsi_device_target_f)574 _TME_SCSI_DEVICE_PHASE_DECL(tme_scsi_device_target_f)
575 {
576   /* enter the BUS FREE phase: */
577   tme_scsi_device_target_phase(scsi_device,
578 			       0);
579 
580   /* there is no next phase we will enter: */
581   scsi_device->tme_scsi_device_phase
582     = NULL;
583 }
584 
585 /* when a device is the target, this runs the MESSAGE IN phase,
586    followed by the BUS FREE phase.  the transmitted message must be
587    preset: */
_TME_SCSI_DEVICE_PHASE_DECL(tme_scsi_device_target_mf)588 _TME_SCSI_DEVICE_PHASE_DECL(tme_scsi_device_target_mf)
589 {
590   /* enter the MESSAGE IN phase: */
591   tme_scsi_device_target_phase(scsi_device,
592 			       TME_SCSI_SIGNAL_BSY
593 			       | TME_SCSI_PHASE_MESSAGE_IN);
594 
595   /* the next phase we enter will be the BUS FREE phase: */
596   scsi_device->tme_scsi_device_phase
597     = tme_scsi_device_target_f;
598 }
599 
600 /* when a device is the target, this runs the STATUS phase, followed
601    by the MESSAGE IN phase, followed by the BUS FREE phase.  the
602    transmitted status and message must be preset: */
_TME_SCSI_DEVICE_PHASE_DECL(tme_scsi_device_target_smf)603 _TME_SCSI_DEVICE_PHASE_DECL(tme_scsi_device_target_smf)
604 {
605   /* enter the STATUS phase: */
606   tme_scsi_device_target_phase(scsi_device,
607 			       TME_SCSI_SIGNAL_BSY
608 			       | TME_SCSI_PHASE_STATUS);
609 
610   /* the next phase we enter will be the MESSAGE IN phase: */
611   scsi_device->tme_scsi_device_phase
612     = tme_scsi_device_target_mf;
613 }
614 
615 /* when a device is the target, this runs the DATA IN or DATA OUT
616    phase, followed by the STATUS phase, followed by the MESSAGE IN
617    phase, followed by the BUS FREE phase.  the transmitted data,
618    status and message must be preset: */
_TME_SCSI_DEVICE_PHASE_DECL(tme_scsi_device_target_dsmf)619 _TME_SCSI_DEVICE_PHASE_DECL(tme_scsi_device_target_dsmf)
620 {
621   /* enter the DATA IN or DATA OUT phase, depending on how
622      DMA was set up: */
623   tme_scsi_device_target_phase(scsi_device,
624 			       TME_SCSI_SIGNAL_BSY
625 			       | ((scsi_device->tme_scsi_device_dma.tme_scsi_dma_in
626 				   != NULL)
627 				  ? TME_SCSI_PHASE_DATA_OUT
628 				  : TME_SCSI_PHASE_DATA_IN));
629 
630   /* the next phase we enter will be the STATUS phase: */
631   scsi_device->tme_scsi_device_phase
632     = tme_scsi_device_target_smf;
633 }
634 
635 /* when a device is the target, this runs a MESSAGE IN phase, followed
636    usually by a COMMAND phase (but possibly a MESSAGE OUT phase): */
_TME_SCSI_DEVICE_PHASE_DECL(tme_scsi_device_target_mc)637 _TME_SCSI_DEVICE_PHASE_DECL(tme_scsi_device_target_mc)
638 {
639 
640   /* enter either the MESSAGE OUT phase or the COMMAND phase: */
641   tme_scsi_device_target_phase(scsi_device,
642 			       TME_SCSI_SIGNAL_BSY
643 			       | ((control_new
644 				   & TME_SCSI_SIGNAL_ATN)
645 				  ? TME_SCSI_PHASE_MESSAGE_OUT
646 				  : TME_SCSI_PHASE_COMMAND));
647 
648 #ifndef NDEBUG
649   /* both the MESSAGE OUT and COMMAND phases have specific
650      dispatchers: */
651   scsi_device->tme_scsi_device_phase = NULL;
652 #endif /* !NDEBUG */
653 }
654 
655 /* when a device is the target, this builds a simple extended sense
656    and returns an immediate CHECK CONDITION status to the initiator: */
657 void
tme_scsi_device_check_condition(struct tme_scsi_device * scsi_device,tme_uint8_t sense_key,tme_uint16_t sense_asc_ascq)658 tme_scsi_device_check_condition(struct tme_scsi_device *scsi_device,
659 				tme_uint8_t sense_key,
660 				tme_uint16_t sense_asc_ascq)
661 {
662   struct tme_scsi_device_sense *sense;
663   int lun;
664 
665   /* get the addressed LUN: */
666   lun = scsi_device->tme_scsi_device_addressed_lun;
667 
668   /* this target must support extended sense: */
669   assert (!scsi_device->tme_scsi_device_sense_no_extended);
670 
671   /* form the sense: */
672   sense = &scsi_device->tme_scsi_device_sense[lun];
673 
674   /* the error class and error code: */
675   sense->tme_scsi_device_sense_data[0]
676     = 0x70;
677 
678   /* the sense key: */
679   sense->tme_scsi_device_sense_data[2]
680     = sense_key;
681 
682   /* if there is no additional sense: */
683   if (sense_asc_ascq == TME_SCSI_SENSE_EXT_ASC_ASCQ_NONE) {
684 
685     /* there is no additional sense length: */
686     sense->tme_scsi_device_sense_data[7] = 0x00;
687   }
688 
689   /* otherwise, there is additional sense: */
690   else {
691 
692     /* the additional sense length: */
693     sense->tme_scsi_device_sense_data[7]
694       = 0x06;
695 
696     /* the additional sense code and additional sense code qualifier: */
697     sense->tme_scsi_device_sense_data[12] = (sense_asc_ascq >> 8);
698     sense->tme_scsi_device_sense_data[13] = sense_asc_ascq;
699   }
700 
701   /* this sense is valid: */
702   sense->tme_scsi_device_sense_valid
703     = TRUE;
704 
705   /* return the CHECK CONDITION status: */
706   tme_scsi_device_target_do_smf(scsi_device,
707 				TME_SCSI_STATUS_CHECK_CONDITION,
708 				TME_SCSI_MSG_CMD_COMPLETE);
709 }
710 
711 /* this is the LUN addresser for LUN-aware devices: */
712 int
tme_scsi_device_address_lun_aware(struct tme_scsi_device * scsi_device)713 tme_scsi_device_address_lun_aware(struct tme_scsi_device *scsi_device)
714 {
715   struct tme_scsi_device_sense *sense;
716   int lun;
717 
718   /* if an IDENTIFY message was sent, use that LUN: */
719   lun = scsi_device->tme_scsi_device_addressed_lun;
720 
721   /* otherwise, get the LUN from bits 5-7 of the second
722      CDB byte: */
723   if (lun < 0) {
724     lun = (scsi_device->tme_scsi_device_cdb[1] >> 5);
725     scsi_device->tme_scsi_device_addressed_lun = lun;
726   }
727 
728   /* if this LUN is not defined, and this isn't a REQUEST SENSE
729      or INQUIRY command: */
730   if (!(scsi_device->tme_scsi_device_luns
731 	& TME_BIT(lun))
732       && (scsi_device->tme_scsi_device_cdb[0]
733 	  != TME_SCSI_CDB_REQUEST_SENSE)
734       && (scsi_device->tme_scsi_device_cdb[0]
735 	  != TME_SCSI_CDB_INQUIRY)) {
736 
737     /* this target must support extended sense: */
738     assert (!scsi_device->tme_scsi_device_sense_no_extended);
739 
740     /* form the ILLEGAL REQUEST sense: */
741     sense = &scsi_device->tme_scsi_device_sense[lun];
742 
743     /* the error class and error code: */
744     sense->tme_scsi_device_sense_data[0]
745       = 0x70;
746 
747     /* the ILLEGAL REQUEST sense key: */
748     sense->tme_scsi_device_sense_data[2]
749 	= 0x05;
750 
751     /* the additional sense length: */
752     sense->tme_scsi_device_sense_data[7]
753       = 0x00;
754 
755     sense->tme_scsi_device_sense_valid
756       = TRUE;
757 
758     /* return the CHECK CONDITION status: */
759     tme_scsi_device_target_do_smf(scsi_device,
760 				  TME_SCSI_STATUS_CHECK_CONDITION,
761 				  TME_SCSI_MSG_CMD_COMPLETE);
762     return (EINVAL);
763   }
764 
765   return (TME_OK);
766 }
767 
768 /* this is the LUN addresser for LUN-unaware devices: */
769 int
tme_scsi_device_address_lun_unaware(struct tme_scsi_device * scsi_device)770 tme_scsi_device_address_lun_unaware(struct tme_scsi_device *scsi_device)
771 {
772 
773   /* we always force a LUN of zero: */
774   scsi_device->tme_scsi_device_addressed_lun = 0;
775 
776   return (tme_scsi_device_address_lun_aware(scsi_device));
777 }
778 
779 /* this makes a new connection: */
780 int
tme_scsi_device_connection_make(struct tme_connection * conn,unsigned int state)781 tme_scsi_device_connection_make(struct tme_connection *conn,
782 				unsigned int state)
783 {
784   struct tme_scsi_device *scsi_device;
785   struct tme_scsi_connection *conn_scsi;
786 
787   /* recover our device: */
788   scsi_device = conn->tme_connection_element->tme_element_private;
789 
790   /* both sides must be SCSI connections: */
791   assert (conn->tme_connection_type
792 	  == TME_CONNECTION_SCSI);
793   assert (conn->tme_connection_other->tme_connection_type
794 	  == TME_CONNECTION_SCSI);
795 
796   /* simple SCSI devices are always set up to answer calls across the
797      connection, so we only have to do work when the connection has
798      gone full, namely taking the other side of the connection: */
799   if (state == TME_CONNECTION_FULL) {
800 
801     /* lock the mutex: */
802     tme_mutex_lock(&scsi_device->tme_scsi_device_mutex);
803 
804     /* save our connection: */
805     conn_scsi
806       = ((struct tme_scsi_connection *)
807 	 conn->tme_connection_other);
808     scsi_device->tme_scsi_device_connection
809       = conn_scsi;
810 
811     /* call out a SCSI bus cycle: */
812     scsi_device->tme_scsi_device_control = 0;
813     _tme_scsi_device_callout(scsi_device,
814 			     TME_SCSI_DEVICE_CALLOUT_CYCLE);
815 
816     /* unlock the mutex: */
817     tme_mutex_unlock(&scsi_device->tme_scsi_device_mutex);
818   }
819 
820   return (TME_OK);
821 }
822 
823 /* this breaks a connection: */
824 int
tme_scsi_device_connection_break(struct tme_connection * conn,unsigned int state)825 tme_scsi_device_connection_break(struct tme_connection *conn, unsigned int state)
826 {
827   abort();
828 }
829 
830 /* this makes a new connection side for a SCSI device: */
831 int
tme_scsi_device_connections_new(struct tme_element * element,const char * const * args,struct tme_connection ** _conns,char ** _output)832 tme_scsi_device_connections_new(struct tme_element *element,
833 				const char * const *args,
834 				struct tme_connection **_conns,
835 				char **_output)
836 {
837   struct tme_scsi_device *scsi_device;
838   struct tme_scsi_connection *conn_scsi;
839   struct tme_connection *conn;
840 
841   /* recover our device: */
842   scsi_device = (struct tme_scsi_device *) element->tme_element_private;
843 
844   /* if this device isn't connected to a SCSI bus, make the new
845      connection side: */
846   if (scsi_device->tme_scsi_device_connection == NULL) {
847 
848     /* create our side of a SCSI connection: */
849     conn_scsi = tme_new0(struct tme_scsi_connection, 1);
850     conn = &conn_scsi->tme_scsi_connection;
851 
852     /* fill in the generic connection: */
853     conn->tme_connection_next = *_conns;
854     conn->tme_connection_type = TME_CONNECTION_SCSI;
855     conn->tme_connection_score = tme_scsi_connection_score;
856     conn->tme_connection_make = tme_scsi_device_connection_make;
857     conn->tme_connection_break = tme_scsi_device_connection_break;
858 
859     /* fill in the SCSI connection: */
860     conn_scsi->tme_scsi_connection_cycle
861       = _tme_scsi_device_cycle;
862 
863     /* return the connection side possibility: */
864     *_conns = conn;
865   }
866 
867   return (TME_OK);
868 }
869 
870 /* this initializes a new SCSI device: */
871 int
tme_scsi_device_new(struct tme_scsi_device * scsi_device,int id)872 tme_scsi_device_new(struct tme_scsi_device *scsi_device,
873 		    int id)
874 {
875   int i;
876 
877   /* initialize the mutex: */
878   tme_mutex_init(&scsi_device->tme_scsi_device_mutex);
879 
880   /* set the SCSI ID: */
881   scsi_device->tme_scsi_device_id = id;
882 
883   /* initialize all of the message and CDB handlers to NULL: */
884   for (i = TME_ARRAY_ELS(scsi_device->tme_scsi_device_do_msg);
885        i-- > 0; ) {
886     scsi_device->tme_scsi_device_do_msg[i] = NULL;
887   }
888   for (i = TME_ARRAY_ELS(scsi_device->tme_scsi_device_do_cdb);
889        i-- > 0; ) {
890     scsi_device->tme_scsi_device_do_cdb[i] = NULL;
891   }
892 
893   /* set the message handlers: */
894   TME_SCSI_DEVICE_DO_MSG(scsi_device,
895 			 TME_SCSI_MSG_CMD_COMPLETE,
896 			 tme_scsi_device_msg_cmd_complete);
897   TME_SCSI_DEVICE_DO_MSG(scsi_device,
898 			 TME_SCSI_MSG_SAVE_DATA_POINTER,
899 			 tme_scsi_device_msg_save_data_pointer);
900   TME_SCSI_DEVICE_DO_MSG(scsi_device,
901 			 TME_SCSI_MSG_RESTORE_POINTERS,
902 			 tme_scsi_device_msg_restore_pointers);
903   TME_SCSI_DEVICE_DO_MSG(scsi_device,
904 			 TME_SCSI_MSG_DISCONNECT,
905 			 tme_scsi_device_msg_disconnect);
906   TME_SCSI_DEVICE_DO_MSG(scsi_device,
907 			 TME_SCSI_MSG_INITIATOR_ERROR,
908 			 tme_scsi_device_msg_initiator_error);
909   TME_SCSI_DEVICE_DO_MSG(scsi_device,
910 			 TME_SCSI_MSG_ABORT,
911 			 tme_scsi_device_msg_abort);
912   TME_SCSI_DEVICE_DO_MSG(scsi_device,
913 			 TME_SCSI_MSG_MESSAGE_REJECT,
914 			 tme_scsi_device_msg_message_reject);
915   TME_SCSI_DEVICE_DO_MSG(scsi_device,
916 			 TME_SCSI_MSG_NOP,
917 			 tme_scsi_device_msg_nop);
918   TME_SCSI_DEVICE_DO_MSG(scsi_device,
919 			 TME_SCSI_MSG_PARITY_ERROR,
920 			 tme_scsi_device_msg_parity_error);
921   TME_SCSI_DEVICE_DO_MSG(scsi_device,
922 			 TME_SCSI_MSG_IDENTIFY,
923 			 tme_scsi_device_msg_identify);
924   TME_SCSI_DEVICE_DO_MSG_EXT(scsi_device,
925 			     TME_SCSI_MSG_EXT_SDTR,
926 			     tme_scsi_device_msg_target_reject);
927 
928   /* set the "Group 0 Common Commands for All Device Types": */
929   TME_SCSI_DEVICE_DO_CDB(scsi_device,
930 			 TME_SCSI_CDB_TEST_UNIT_READY,
931 			 tme_scsi_device_cdb_tur);
932   TME_SCSI_DEVICE_DO_CDB(scsi_device,
933 			 TME_SCSI_CDB_REQUEST_SENSE,
934 			 tme_scsi_device_cdb_request_sense);
935   TME_SCSI_DEVICE_DO_CDB(scsi_device,
936 			 TME_SCSI_CDB_INQUIRY,
937 			 NULL);
938 
939   /* assume that this device is LUN-aware: */
940   scsi_device->tme_scsi_device_address_lun
941     = tme_scsi_device_address_lun_aware;
942 
943   return (TME_OK);
944 }
945