scsi_command() really return error code in case of error...
[emile:mainline.git] / libscsi / scsi_command.c
1 /*
2  *
3  * (c) 2004, 2005 Laurent Vivier <Laurent@Vivier.EU>
4  *
5  */
6
7 #include <stdio.h>
8 #include <sys/types.h>
9
10 #include <scsi/scsi.h>
11
12 #include <macos/types.h>
13 #include <macos/errors.h>
14 #include <macos/scsi.h>
15 #include <macos/lowmem.h>
16
17 #include "libscsi.h"
18
19 #define COMPLETION_TIMEOUT      (30*60)         /* 30 seconds */
20
21 #define SCSI_BUSY               (1 << 6)
22 #define SCSI_SEL                (1 << 1)
23
24 static inline int scsi_busy(void)
25 {
26         return (SCSIStat() & (SCSI_BUSY | SCSI_SEL)) != 0;
27 }
28
29 static inline int scsi_wait_bus()
30 {
31         int timeout;
32
33         timeout = Ticks + 300;
34
35         while (scsi_busy())
36                 if (Ticks > timeout)
37                         return scsiBusy;
38         return noErr;
39 }
40
41 int scsi_command(int target, unsigned char* cdb, int count, TIB_t* tib)
42 {
43         int err;
44         short stat;
45         short message;
46
47         err = scsi_wait_bus();
48         if (err != noErr)
49         {
50                 printf("SCSI bus is busy\n");
51                 return err;
52         }
53
54         err = SCSIGet();
55         if (err != noErr) 
56         {
57                 printf("Cannot get SCSI bus (%d)\n", err);
58                 return err;
59         }
60
61         err = SCSISelect(target);
62         if (err != noErr) 
63         {
64                 printf("Cannot select target %d (%d)\n", target, err);
65                 return err;
66         }
67
68         err = SCSICmd(cdb, count);
69         if (err != noErr) 
70         {
71                 printf("Cannot send command (%d)\n", err);
72                 goto complete;
73         }
74
75         if (tib != NULL)
76         {
77                 err = SCSIRead(tib);
78                 if ((err != scPhaseErr) && (err != noErr))
79                 {
80                         printf("Cannot read data (%d)\n", err);
81                         goto complete;
82                 }
83         }
84
85         err = SCSIComplete(&stat, &message, COMPLETION_TIMEOUT);
86         if (err != noErr) 
87                 return err;
88
89         return noErr;
90 complete:
91         SCSIComplete(&stat, &message, COMPLETION_TIMEOUT);
92         return err;
93 }