summaryrefslogtreecommitdiff
path: root/audio/cdparanoia/patches/patch-cg
blob: 5d05e619c730b92bf6b44f28cd64e179a0ec78a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
$NetBSD: patch-cg,v 1.10 2009/08/09 16:00:53 drochner Exp $

--- interface/scsi_interface.c.orig	2008-09-11 22:33:30.000000000 +0200
+++ interface/scsi_interface.c
@@ -12,6 +12,11 @@
 #include "common_interface.h"
 #include "utils.h"
 #include <time.h>
+
+#ifdef __NetBSD__
+#define SG_MAX_SENSE SENSEBUFLEN
+#endif
+
 static int timed_ioctl(cdrom_drive *d, int fd, int command, void *arg){
   struct timespec tv1;
   struct timespec tv2;
@@ -36,6 +41,7 @@ static void tweak_SG_buffer(cdrom_drive 
   int table, reserved, cur, err;
   char buffer[256];
 
+#ifdef __linux__
   /* SG_SET_RESERVED_SIZE doesn't actually allocate or reserve anything.
    * what it _does_ do is give you an error if you ask for a value
    * larger than q->max_sectors (the length of the device's bio request
@@ -54,6 +60,10 @@ static void tweak_SG_buffer(cdrom_drive 
      implement working sg lists with SG_IO devices, so who knows... */
   if (ioctl(d->cdda_fd, SG_GET_SG_TABLESIZE, &table) < 0)
     table=1;
+#else
+  reserved = 32*1024;   /* ? */
+  table = 1;
+#endif
 
   sprintf(buffer,"\tDMA scatter/gather table entries: %d\n\t"
 	  "table entry size: %d bytes\n\t"
@@ -93,6 +103,7 @@ static void tweak_SG_buffer(cdrom_drive 
   cdmessage(d,buffer);
 }
 
+#ifdef __linux__
 static void clear_garbage(cdrom_drive *d){
   fd_set fdset;
   struct timeval tv;
@@ -123,6 +134,7 @@ static void clear_garbage(cdrom_drive *d
     flag=1;
   }
 }
+#endif
 
 static int check_sbp_error(const unsigned char status,
 			   const unsigned char *sbp) {
@@ -172,6 +184,7 @@ static int check_sbp_error(const unsigne
   return 0;
 }
 
+#ifdef __linux__
 /* process a complete scsi command. */
 static int sg2_handle_scsi_cmd(cdrom_drive *d,
 			       unsigned char *cmd,
@@ -417,6 +430,71 @@ static int sgio_handle_scsi_cmd(cdrom_dr
   errno = 0;
   return 0;
 }
+#endif /* __linux__ */
+
+#ifdef __NetBSD__
+static int nb_handle_scsi_cmd(cdrom_drive *d,
+			       unsigned char *cmd,
+			       unsigned int cmd_len, 
+			       unsigned int in_size, 
+			       unsigned int out_size,       
+			       unsigned char bytefill,
+			       int bytecheck,
+			       unsigned char *sense_buffer){
+  int status = 0;
+  scsireq_t *sreq = (scsireq_t *)d->private->sg_hd;
+
+  memset(sense_buffer,0,SENSEBUFLEN);
+  memcpy(d->private->sg_buffer,cmd+cmd_len,in_size);
+
+  if (in_size && out_size) {
+    warnx("handle_scsi_cmd: in and out is not supported");
+    abort();
+  }
+  memset(sreq, 0, sizeof(scsireq_t));
+  sreq->cmdlen = cmd_len;
+  memcpy(sreq->cmd, cmd, cmd_len);
+  if (in_size) {
+    sreq->flags = SCCMD_WRITE;
+    sreq->databuf = d->private->sg_buffer;
+    sreq->datalen = in_size;
+  }
+  if (out_size) {
+    sreq->flags = SCCMD_READ;
+    sreq->databuf = d->private->sg_buffer;
+    sreq->datalen = out_size;
+    if(bytecheck)
+      memset(d->private->sg_buffer, bytefill, out_size); 
+  }
+  sreq->senselen = SENSEBUFLEN;
+  sreq->timeout = 60000;        /* 60s */
+
+  status = timed_ioctl(d, d->cdda_fd, SCIOCCOMMAND, (void *) sreq);
+  if (status < 0)
+    return(TR_ILLEGAL);
+  memcpy(sense_buffer,sreq->sense,SENSEBUFLEN);
+  status = check_sbp_error(sreq->status,sense_buffer);
+  if (status)
+    return status;
+
+  if(bytecheck && out_size){
+    long i,flag=0;
+    for(i=0;i<out_size;i++)
+      if(d->private->sg_buffer[i]!=bytefill){
+	flag=1;
+	break;
+      }
+    
+    if(!flag){
+      errno=EINVAL;
+      return(TR_ILLEGAL);
+    }
+  }
+
+  errno=0;
+  return 0;
+}
+#endif /* __NetBSD__ */
 
 static int handle_scsi_cmd(cdrom_drive *d,
 			   unsigned char *cmd,
@@ -427,9 +505,14 @@ static int handle_scsi_cmd(cdrom_drive *
 			   int bytecheck,
 			   unsigned char *sense){
 
+#ifdef __linux__
   if(d->interface == SGIO_SCSI || d->interface == SGIO_SCSI_BUGGY1)
     return sgio_handle_scsi_cmd(d,cmd,cmd_len,in_size,out_size,bytefill,bytecheck,sense);
   return sg2_handle_scsi_cmd(d,cmd,cmd_len,in_size,out_size,bytefill,bytecheck,sense);
+#endif
+#ifdef __NetBSD__
+  return nb_handle_scsi_cmd(d,cmd,cmd_len,in_size,out_size,bytefill,bytecheck,sense);
+#endif
 
 }
 
@@ -453,6 +536,7 @@ static int test_unit_ready(cdrom_drive *
   return 1;
 }
 
+#ifdef __linux__
 static void reset_scsi(cdrom_drive *d){
   int arg,tries=0;
   d->enable_cdda(d,0);
@@ -471,6 +555,22 @@ static void reset_scsi(cdrom_drive *d){
   
   d->enable_cdda(d,1);
 }
+#endif
+
+#ifdef __NetBSD__
+static void reset_scsi(cdrom_drive *d){
+  int arg;
+  d->enable_cdda(d,0);
+
+  cdmessage(d,"sending SCSI reset... ");
+  if(ioctl(d->cdda_fd,CDIOCRESET,&arg))
+    cdmessage(d,"FAILED: EBUSY\n");
+  else
+    cdmessage(d,"OK\n");
+  
+  d->enable_cdda(d,1);
+}
+#endif
 
 static int mode_sense_atapi(cdrom_drive *d,int size,int page){ 
   unsigned char sense[SG_MAX_SENSE];
@@ -1587,6 +1687,7 @@ static void check_cache(cdrom_drive *d){
   }
 }
 
+#ifdef __linux__
 static int check_atapi(cdrom_drive *d){
   int atapiret=-1;
   int fd = d->cdda_fd; /* check the device we'll actually be using to read */
@@ -1616,7 +1717,32 @@ static int check_atapi(cdrom_drive *d){
 
     return(d->is_atapi);
   }
-}  
+} 
+#endif
+
+#ifdef __NetBSD__
+static int check_atapi(cdrom_drive *d){
+  struct scsi_addr scaddr;
+  int fd = d->cdda_fd; /* check the device we'll actually be using to read */
+			  
+  cdmessage(d,"\nChecking for SCSI emulation...\n");
+
+  if (ioctl(fd,SCIOCIDENTIFY,&scaddr)){
+    cderror(d,"\tSG_EMULATED_HOST ioctl() failed!\n");
+    return(-1);
+  } else {
+    if(scaddr.type == TYPE_ATAPI){
+      cdmessage(d,"\tDrive is ATAPI\n");
+      d->is_atapi=1;
+    }else{
+      cdmessage(d,"\tDrive is SCSI\n");
+      d->is_atapi=0;
+    }
+
+    return(d->is_atapi);
+  }
+}
+#endif 
 
 static int check_mmc(cdrom_drive *d){
   unsigned char *b;