diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-09-18 00:12:59 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-09-18 00:14:20 -0400 |
commit | cd915200af6e01a8e923cc5440f72fb288bf2d6b (patch) | |
tree | 102a9880ef70f7e0f5829176760cfe43fd0b7c27 | |
parent | 2d96650139bf6f163970f72ef8aa1abaa6c8b3d1 (diff) |
Staging ced1401: cleanup coding style issues.
A basic Lindent run on the .c files, clean up the .h file by hand.
Cc: Alois Schlögl <alois.schloegl@ist.ac.at>
Cc: Greg P. Smith <greg@ced.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/ced1401/ced_ioc.c | 2055 | ||||
-rw-r--r-- | drivers/staging/ced1401/ced_ioctl.h | 455 | ||||
-rw-r--r-- | drivers/staging/ced1401/usb1401.c | 2360 |
3 files changed, 2539 insertions, 2331 deletions
diff --git a/drivers/staging/ced1401/ced_ioc.c b/drivers/staging/ced1401/ced_ioc.c index 4a13c1072852..bb29c7f6217f 100644 --- a/drivers/staging/ced1401/ced_ioc.c +++ b/drivers/staging/ced1401/ced_ioc.c | |||
@@ -37,17 +37,18 @@ | |||
37 | ** | 37 | ** |
38 | ** Empties the Output buffer and sets int lines. Used from user level only | 38 | ** Empties the Output buffer and sets int lines. Used from user level only |
39 | ****************************************************************************/ | 39 | ****************************************************************************/ |
40 | void FlushOutBuff(DEVICE_EXTENSION *pdx) | 40 | void FlushOutBuff(DEVICE_EXTENSION * pdx) |
41 | { | 41 | { |
42 | dev_dbg(&pdx->interface->dev, "%s currentState=%d", __func__, pdx->sCurrentState); | 42 | dev_dbg(&pdx->interface->dev, "%s currentState=%d", __func__, |
43 | if (pdx->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */ | 43 | pdx->sCurrentState); |
44 | return; | 44 | if (pdx->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */ |
45 | return; | ||
45 | // CharSend_Cancel(pdx); /* Kill off any pending I/O */ | 46 | // CharSend_Cancel(pdx); /* Kill off any pending I/O */ |
46 | spin_lock_irq(&pdx->charOutLock); | 47 | spin_lock_irq(&pdx->charOutLock); |
47 | pdx->dwNumOutput = 0; | 48 | pdx->dwNumOutput = 0; |
48 | pdx->dwOutBuffGet = 0; | 49 | pdx->dwOutBuffGet = 0; |
49 | pdx->dwOutBuffPut = 0; | 50 | pdx->dwOutBuffPut = 0; |
50 | spin_unlock_irq(&pdx->charOutLock); | 51 | spin_unlock_irq(&pdx->charOutLock); |
51 | } | 52 | } |
52 | 53 | ||
53 | /**************************************************************************** | 54 | /**************************************************************************** |
@@ -56,17 +57,18 @@ void FlushOutBuff(DEVICE_EXTENSION *pdx) | |||
56 | ** | 57 | ** |
57 | ** Empties the input buffer and sets int lines | 58 | ** Empties the input buffer and sets int lines |
58 | ****************************************************************************/ | 59 | ****************************************************************************/ |
59 | void FlushInBuff(DEVICE_EXTENSION *pdx) | 60 | void FlushInBuff(DEVICE_EXTENSION * pdx) |
60 | { | 61 | { |
61 | dev_dbg(&pdx->interface->dev, "%s currentState=%d", __func__, pdx->sCurrentState); | 62 | dev_dbg(&pdx->interface->dev, "%s currentState=%d", __func__, |
62 | if (pdx->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */ | 63 | pdx->sCurrentState); |
63 | return; | 64 | if (pdx->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */ |
65 | return; | ||
64 | // CharRead_Cancel(pDevObject); /* Kill off any pending I/O */ | 66 | // CharRead_Cancel(pDevObject); /* Kill off any pending I/O */ |
65 | spin_lock_irq(&pdx->charInLock); | 67 | spin_lock_irq(&pdx->charInLock); |
66 | pdx->dwNumInput = 0; | 68 | pdx->dwNumInput = 0; |
67 | pdx->dwInBuffGet = 0; | 69 | pdx->dwInBuffGet = 0; |
68 | pdx->dwInBuffPut = 0; | 70 | pdx->dwInBuffPut = 0; |
69 | spin_unlock_irq(&pdx->charInLock); | 71 | spin_unlock_irq(&pdx->charInLock); |
70 | } | 72 | } |
71 | 73 | ||
72 | /**************************************************************************** | 74 | /**************************************************************************** |
@@ -75,29 +77,26 @@ void FlushInBuff(DEVICE_EXTENSION *pdx) | |||
75 | ** Utility routine to copy chars into the output buffer and fire them off. | 77 | ** Utility routine to copy chars into the output buffer and fire them off. |
76 | ** called from user mode, holds charOutLock. | 78 | ** called from user mode, holds charOutLock. |
77 | ****************************************************************************/ | 79 | ****************************************************************************/ |
78 | static int PutChars(DEVICE_EXTENSION* pdx, const char* pCh, unsigned int uCount) | 80 | static int PutChars(DEVICE_EXTENSION * pdx, const char *pCh, |
81 | unsigned int uCount) | ||
79 | { | 82 | { |
80 | int iReturn; | 83 | int iReturn; |
81 | spin_lock_irq(&pdx->charOutLock); // get the output spin lock | 84 | spin_lock_irq(&pdx->charOutLock); // get the output spin lock |
82 | if ((OUTBUF_SZ - pdx->dwNumOutput) >= uCount) | 85 | if ((OUTBUF_SZ - pdx->dwNumOutput) >= uCount) { |
83 | { | 86 | unsigned int u; |
84 | unsigned int u; | 87 | for (u = 0; u < uCount; u++) { |
85 | for (u=0; u<uCount; u++) | 88 | pdx->outputBuffer[pdx->dwOutBuffPut++] = pCh[u]; |
86 | { | 89 | if (pdx->dwOutBuffPut >= OUTBUF_SZ) |
87 | pdx->outputBuffer[pdx->dwOutBuffPut++] = pCh[u]; | 90 | pdx->dwOutBuffPut = 0; |
88 | if (pdx->dwOutBuffPut >= OUTBUF_SZ) | 91 | } |
89 | pdx->dwOutBuffPut = 0; | 92 | pdx->dwNumOutput += uCount; |
90 | } | 93 | spin_unlock_irq(&pdx->charOutLock); |
91 | pdx->dwNumOutput += uCount; | 94 | iReturn = SendChars(pdx); // ...give a chance to transmit data |
92 | spin_unlock_irq(&pdx->charOutLock); | 95 | } else { |
93 | iReturn = SendChars(pdx); // ...give a chance to transmit data | 96 | iReturn = U14ERR_NOOUT; // no room at the out (ha-ha) |
94 | } | 97 | spin_unlock_irq(&pdx->charOutLock); |
95 | else | 98 | } |
96 | { | 99 | return iReturn; |
97 | iReturn = U14ERR_NOOUT; // no room at the out (ha-ha) | ||
98 | spin_unlock_irq(&pdx->charOutLock); | ||
99 | } | ||
100 | return iReturn; | ||
101 | } | 100 | } |
102 | 101 | ||
103 | /***************************************************************************** | 102 | /***************************************************************************** |
@@ -105,27 +104,29 @@ static int PutChars(DEVICE_EXTENSION* pdx, const char* pCh, unsigned int uCount) | |||
105 | ** trigger an output transfer if this is appropriate. User mode. | 104 | ** trigger an output transfer if this is appropriate. User mode. |
106 | ** Holds the io_mutex | 105 | ** Holds the io_mutex |
107 | *****************************************************************************/ | 106 | *****************************************************************************/ |
108 | int SendString(DEVICE_EXTENSION* pdx, const char __user* pData, unsigned int n) | 107 | int SendString(DEVICE_EXTENSION * pdx, const char __user * pData, |
108 | unsigned int n) | ||
109 | { | 109 | { |
110 | int iReturn = U14ERR_NOERROR; // assume all will be well | 110 | int iReturn = U14ERR_NOERROR; // assume all will be well |
111 | char buffer[OUTBUF_SZ+1]; // space in our address space for characters | 111 | char buffer[OUTBUF_SZ + 1]; // space in our address space for characters |
112 | if (n > OUTBUF_SZ) // check space in local buffer... | 112 | if (n > OUTBUF_SZ) // check space in local buffer... |
113 | return U14ERR_NOOUT; // ...too many characters | 113 | return U14ERR_NOOUT; // ...too many characters |
114 | if (copy_from_user(buffer, pData, n)) | 114 | if (copy_from_user(buffer, pData, n)) |
115 | return -ENOMEM; // could not copy | 115 | return -ENOMEM; // could not copy |
116 | buffer[n] = 0; // terminate for debug purposes | 116 | buffer[n] = 0; // terminate for debug purposes |
117 | 117 | ||
118 | mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o | 118 | mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o |
119 | if (n > 0) // do nothing if nowt to do! | 119 | if (n > 0) // do nothing if nowt to do! |
120 | { | 120 | { |
121 | dev_dbg(&pdx->interface->dev, "%s n=%d>%s<", __func__, n, buffer); | 121 | dev_dbg(&pdx->interface->dev, "%s n=%d>%s<", __func__, n, |
122 | iReturn = PutChars(pdx, buffer, n); | 122 | buffer); |
123 | } | 123 | iReturn = PutChars(pdx, buffer, n); |
124 | 124 | } | |
125 | Allowi(pdx, false); // make sure we have input int | 125 | |
126 | mutex_unlock(&pdx->io_mutex); | 126 | Allowi(pdx, false); // make sure we have input int |
127 | 127 | mutex_unlock(&pdx->io_mutex); | |
128 | return iReturn; | 128 | |
129 | return iReturn; | ||
129 | } | 130 | } |
130 | 131 | ||
131 | /**************************************************************************** | 132 | /**************************************************************************** |
@@ -133,15 +134,15 @@ int SendString(DEVICE_EXTENSION* pdx, const char __user* pData, unsigned int n) | |||
133 | ** | 134 | ** |
134 | ** Sends a single character to the 1401. User mode, holds io_mutex. | 135 | ** Sends a single character to the 1401. User mode, holds io_mutex. |
135 | ****************************************************************************/ | 136 | ****************************************************************************/ |
136 | int SendChar(DEVICE_EXTENSION *pdx, char c) | 137 | int SendChar(DEVICE_EXTENSION * pdx, char c) |
137 | { | 138 | { |
138 | int iReturn; | 139 | int iReturn; |
139 | mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o | 140 | mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o |
140 | iReturn = PutChars(pdx, &c, 1); | 141 | iReturn = PutChars(pdx, &c, 1); |
141 | dev_dbg(&pdx->interface->dev,"SendChar >%c< (0x%02x)", c, c); | 142 | dev_dbg(&pdx->interface->dev, "SendChar >%c< (0x%02x)", c, c); |
142 | Allowi(pdx, false); // Make sure char reads are running | 143 | Allowi(pdx, false); // Make sure char reads are running |
143 | mutex_unlock(&pdx->io_mutex); | 144 | mutex_unlock(&pdx->io_mutex); |
144 | return iReturn; | 145 | return iReturn; |
145 | } | 146 | } |
146 | 147 | ||
147 | /*************************************************************************** | 148 | /*************************************************************************** |
@@ -170,48 +171,47 @@ int SendChar(DEVICE_EXTENSION *pdx, char c) | |||
170 | ** | 171 | ** |
171 | ** return error code (U14ERR_NOERROR for OK) | 172 | ** return error code (U14ERR_NOERROR for OK) |
172 | */ | 173 | */ |
173 | int Get1401State(DEVICE_EXTENSION* pdx, __u32* state, __u32* error) | 174 | int Get1401State(DEVICE_EXTENSION * pdx, __u32 * state, __u32 * error) |
174 | { | 175 | { |
175 | int nGot; | 176 | int nGot; |
176 | dev_dbg(&pdx->interface->dev, "Get1401State() entry"); | 177 | dev_dbg(&pdx->interface->dev, "Get1401State() entry"); |
177 | 178 | ||
178 | *state = 0xFFFFFFFF; // Start off with invalid state | 179 | *state = 0xFFFFFFFF; // Start off with invalid state |
179 | nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), | 180 | nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), |
180 | GET_STATUS, (D_TO_H|VENDOR|DEVREQ), 0,0, | 181 | GET_STATUS, (D_TO_H | VENDOR | DEVREQ), 0, 0, |
181 | pdx->statBuf, sizeof(pdx->statBuf), HZ); | 182 | pdx->statBuf, sizeof(pdx->statBuf), HZ); |
182 | if (nGot != sizeof(pdx->statBuf)) | 183 | if (nGot != sizeof(pdx->statBuf)) { |
183 | { | 184 | dev_err(&pdx->interface->dev, |
184 | dev_err(&pdx->interface->dev, "Get1401State() FAILED, return code %d", nGot); | 185 | "Get1401State() FAILED, return code %d", nGot); |
185 | pdx->sCurrentState = U14ERR_TIME; // Indicate that things are very wrong indeed | 186 | pdx->sCurrentState = U14ERR_TIME; // Indicate that things are very wrong indeed |
186 | *state = 0; // Force status values to a known state | 187 | *state = 0; // Force status values to a known state |
187 | *error = 0; | 188 | *error = 0; |
188 | } | 189 | } else { |
189 | else | 190 | int nDevice; |
190 | { | 191 | dev_dbg(&pdx->interface->dev, |
191 | int nDevice; | 192 | "Get1401State() Success, state: 0x%x, 0x%x", |
192 | dev_dbg(&pdx->interface->dev, "Get1401State() Success, state: 0x%x, 0x%x", | 193 | pdx->statBuf[0], pdx->statBuf[1]); |
193 | pdx->statBuf[0], pdx->statBuf[1]); | 194 | |
194 | 195 | *state = pdx->statBuf[0]; // Return the state values to the calling code | |
195 | *state = pdx->statBuf[0]; // Return the state values to the calling code | 196 | *error = pdx->statBuf[1]; |
196 | *error = pdx->statBuf[1]; | 197 | |
197 | 198 | nDevice = pdx->udev->descriptor.bcdDevice >> 8; // 1401 type code value | |
198 | nDevice = pdx->udev->descriptor.bcdDevice >> 8; // 1401 type code value | 199 | switch (nDevice) // so we can clean up current state |
199 | switch (nDevice) // so we can clean up current state | 200 | { |
200 | { | 201 | case 0: |
201 | case 0: | 202 | pdx->sCurrentState = U14ERR_U1401; |
202 | pdx->sCurrentState = U14ERR_U1401; | 203 | break; |
203 | break; | 204 | |
204 | 205 | default: // allow lots of device codes for future 1401s | |
205 | default: // allow lots of device codes for future 1401s | 206 | if ((nDevice >= 1) && (nDevice <= 23)) |
206 | if ((nDevice >= 1) && (nDevice <= 23)) | 207 | pdx->sCurrentState = (short)(nDevice + 6); |
207 | pdx->sCurrentState = (short)(nDevice + 6); | 208 | else |
208 | else | 209 | pdx->sCurrentState = U14ERR_ILL; |
209 | pdx->sCurrentState = U14ERR_ILL; | 210 | break; |
210 | break; | 211 | } |
211 | } | 212 | } |
212 | } | 213 | |
213 | 214 | return pdx->sCurrentState >= 0 ? U14ERR_NOERROR : pdx->sCurrentState; | |
214 | return pdx->sCurrentState >= 0 ? U14ERR_NOERROR : pdx->sCurrentState; | ||
215 | } | 215 | } |
216 | 216 | ||
217 | /**************************************************************************** | 217 | /**************************************************************************** |
@@ -219,49 +219,53 @@ int Get1401State(DEVICE_EXTENSION* pdx, __u32* state, __u32* error) | |||
219 | ** | 219 | ** |
220 | ** Kills off staged read\write request from the USB if one is pending. | 220 | ** Kills off staged read\write request from the USB if one is pending. |
221 | ****************************************************************************/ | 221 | ****************************************************************************/ |
222 | int ReadWrite_Cancel(DEVICE_EXTENSION *pdx) | 222 | int ReadWrite_Cancel(DEVICE_EXTENSION * pdx) |
223 | { | 223 | { |
224 | dev_dbg(&pdx->interface->dev, "ReadWrite_Cancel entry %d", pdx->bStagedUrbPending); | 224 | dev_dbg(&pdx->interface->dev, "ReadWrite_Cancel entry %d", |
225 | pdx->bStagedUrbPending); | ||
225 | #ifdef NOT_WRITTEN_YET | 226 | #ifdef NOT_WRITTEN_YET |
226 | int ntStatus = STATUS_SUCCESS; | 227 | int ntStatus = STATUS_SUCCESS; |
227 | bool bResult = false; | 228 | bool bResult = false; |
228 | unsigned int i; | 229 | unsigned int i; |
229 | // We can fill this in when we know how we will implement the staged transfer stuff | 230 | // We can fill this in when we know how we will implement the staged transfer stuff |
230 | spin_lock_irq(&pdx->stagedLock); | 231 | spin_lock_irq(&pdx->stagedLock); |
231 | 232 | ||
232 | if (pdx->bStagedUrbPending) // anything to be cancelled? May need more... | 233 | if (pdx->bStagedUrbPending) // anything to be cancelled? May need more... |
233 | { | 234 | { |
234 | dev_info(&pdx->interface-dev, "ReadWrite_Cancel about to cancel Urb"); | 235 | dev_info(&pdx->interface - dev, |
235 | 236 | "ReadWrite_Cancel about to cancel Urb"); | |
236 | // KeClearEvent(&pdx->StagingDoneEvent); // Clear the staging done flag | 237 | |
237 | USB_ASSERT(pdx->pStagedIrp != NULL); | 238 | // KeClearEvent(&pdx->StagingDoneEvent); // Clear the staging done flag |
238 | 239 | USB_ASSERT(pdx->pStagedIrp != NULL); | |
239 | // Release the spinlock first otherwise the completion routine may hang | 240 | |
240 | // on the spinlock while this function hands waiting for the event. | 241 | // Release the spinlock first otherwise the completion routine may hang |
241 | spin_unlock_irq(&pdx->stagedLock); | 242 | // on the spinlock while this function hands waiting for the event. |
242 | bResult = IoCancelIrp(pdx->pStagedIrp); // Actually do the cancel | 243 | spin_unlock_irq(&pdx->stagedLock); |
243 | if (bResult) | 244 | bResult = IoCancelIrp(pdx->pStagedIrp); // Actually do the cancel |
244 | { | 245 | if (bResult) { |
245 | LARGE_INTEGER timeout; | 246 | LARGE_INTEGER timeout; |
246 | timeout.QuadPart = -10000000; // Use a timeout of 1 second | 247 | timeout.QuadPart = -10000000; // Use a timeout of 1 second |
247 | dev_info(&pdx->interface-dev, "ReadWrite_Cancel about to wait till done"); | 248 | dev_info(&pdx->interface - dev, |
248 | ntStatus = KeWaitForSingleObject(&pdx->StagingDoneEvent, Executive, | 249 | "ReadWrite_Cancel about to wait till done"); |
249 | KernelMode, FALSE, &timeout); | 250 | ntStatus = |
250 | } | 251 | KeWaitForSingleObject(&pdx->StagingDoneEvent, |
251 | else | 252 | Executive, KernelMode, FALSE, |
252 | { | 253 | &timeout); |
253 | dev_info(&pdx->interface-dev, "ReadWrite_Cancel, cancellation failed"); | 254 | } else { |
254 | ntStatus = U14ERR_FAIL; | 255 | dev_info(&pdx->interface - dev, |
255 | } | 256 | "ReadWrite_Cancel, cancellation failed"); |
256 | USB_KdPrint(DBGLVL_DEFAULT, ("ReadWrite_Cancel ntStatus = 0x%x decimal %d\n", ntStatus, ntStatus)); | 257 | ntStatus = U14ERR_FAIL; |
257 | } | 258 | } |
258 | else | 259 | USB_KdPrint(DBGLVL_DEFAULT, |
259 | spin_unlock_irq(&pdx->stagedLock); | 260 | ("ReadWrite_Cancel ntStatus = 0x%x decimal %d\n", |
260 | 261 | ntStatus, ntStatus)); | |
261 | dev_info(&pdx->interface-dev, "ReadWrite_Cancel done"); | 262 | } else |
262 | return ntStatus; | 263 | spin_unlock_irq(&pdx->stagedLock); |
264 | |||
265 | dev_info(&pdx->interface - dev, "ReadWrite_Cancel done"); | ||
266 | return ntStatus; | ||
263 | #else | 267 | #else |
264 | return U14ERR_NOERROR; | 268 | return U14ERR_NOERROR; |
265 | #endif | 269 | #endif |
266 | 270 | ||
267 | } | 271 | } |
@@ -270,15 +274,15 @@ int ReadWrite_Cancel(DEVICE_EXTENSION *pdx) | |||
270 | ** InSelfTest - utility to check in self test. Return 1 for ST, 0 for not or | 274 | ** InSelfTest - utility to check in self test. Return 1 for ST, 0 for not or |
271 | ** a -ve error code if we failed for some reason. | 275 | ** a -ve error code if we failed for some reason. |
272 | ***************************************************************************/ | 276 | ***************************************************************************/ |
273 | static int InSelfTest(DEVICE_EXTENSION* pdx, unsigned int* pState) | 277 | static int InSelfTest(DEVICE_EXTENSION * pdx, unsigned int *pState) |
274 | { | 278 | { |
275 | unsigned int state, error; | 279 | unsigned int state, error; |
276 | int iReturn = Get1401State(pdx, &state, &error); // see if in self-test | 280 | int iReturn = Get1401State(pdx, &state, &error); // see if in self-test |
277 | if (iReturn == U14ERR_NOERROR) // if all still OK | 281 | if (iReturn == U14ERR_NOERROR) // if all still OK |
278 | iReturn = (state == (unsigned int)-1) || // TX problem or... | 282 | iReturn = (state == (unsigned int)-1) || // TX problem or... |
279 | ((state & 0xff) == 0x80); // ...self test | 283 | ((state & 0xff) == 0x80); // ...self test |
280 | *pState = state; // return actual state | 284 | *pState = state; // return actual state |
281 | return iReturn; | 285 | return iReturn; |
282 | } | 286 | } |
283 | 287 | ||
284 | /*************************************************************************** | 288 | /*************************************************************************** |
@@ -299,52 +303,50 @@ static int InSelfTest(DEVICE_EXTENSION* pdx, unsigned int* pState) | |||
299 | ** | 303 | ** |
300 | ** Returns TRUE if a 1401 detected and OK, else FALSE | 304 | ** Returns TRUE if a 1401 detected and OK, else FALSE |
301 | ****************************************************************************/ | 305 | ****************************************************************************/ |
302 | bool Is1401(DEVICE_EXTENSION* pdx) | 306 | bool Is1401(DEVICE_EXTENSION * pdx) |
303 | { | 307 | { |
304 | int iReturn; | 308 | int iReturn; |
305 | dev_dbg(&pdx->interface->dev, "%s", __func__); | 309 | dev_dbg(&pdx->interface->dev, "%s", __func__); |
306 | 310 | ||
307 | ced_draw_down(pdx); // wait for, then kill outstanding Urbs | 311 | ced_draw_down(pdx); // wait for, then kill outstanding Urbs |
308 | FlushInBuff(pdx); // Clear out input buffer & pipe | 312 | FlushInBuff(pdx); // Clear out input buffer & pipe |
309 | FlushOutBuff(pdx); // Clear output buffer & pipe | 313 | FlushOutBuff(pdx); // Clear output buffer & pipe |
310 | 314 | ||
311 | // The next call returns 0 if OK, but has returned 1 in the past, meaning that | 315 | // The next call returns 0 if OK, but has returned 1 in the past, meaning that |
312 | // usb_unlock_device() is needed... now it always is | 316 | // usb_unlock_device() is needed... now it always is |
313 | iReturn = usb_lock_device_for_reset(pdx->udev, pdx->interface); | 317 | iReturn = usb_lock_device_for_reset(pdx->udev, pdx->interface); |
314 | 318 | ||
315 | // release the io_mutex because if we don't, we will deadlock due to system | 319 | // release the io_mutex because if we don't, we will deadlock due to system |
316 | // calls back into the driver. | 320 | // calls back into the driver. |
317 | mutex_unlock(&pdx->io_mutex); // locked, so we will not get system calls | 321 | mutex_unlock(&pdx->io_mutex); // locked, so we will not get system calls |
318 | if (iReturn >= 0) // if we failed | 322 | if (iReturn >= 0) // if we failed |
319 | { | 323 | { |
320 | iReturn = usb_reset_device(pdx->udev); // try to do the reset | 324 | iReturn = usb_reset_device(pdx->udev); // try to do the reset |
321 | usb_unlock_device(pdx->udev); // undo the lock | 325 | usb_unlock_device(pdx->udev); // undo the lock |
322 | } | 326 | } |
323 | 327 | ||
324 | mutex_lock(&pdx->io_mutex); // hold stuff off while we wait | 328 | mutex_lock(&pdx->io_mutex); // hold stuff off while we wait |
325 | pdx->dwDMAFlag = MODE_CHAR; // Clear DMA mode flag regardless! | 329 | pdx->dwDMAFlag = MODE_CHAR; // Clear DMA mode flag regardless! |
326 | if (iReturn == 0) // if all is OK still | 330 | if (iReturn == 0) // if all is OK still |
327 | { | 331 | { |
328 | unsigned int state; | 332 | unsigned int state; |
329 | iReturn = InSelfTest(pdx, &state); // see if likely in self test | 333 | iReturn = InSelfTest(pdx, &state); // see if likely in self test |
330 | if (iReturn > 0) // do we need to wait for self-test? | 334 | if (iReturn > 0) // do we need to wait for self-test? |
331 | { | 335 | { |
332 | unsigned long ulTimeOut = jiffies + 30*HZ; // when to give up | 336 | unsigned long ulTimeOut = jiffies + 30 * HZ; // when to give up |
333 | while((iReturn > 0) && time_before(jiffies, ulTimeOut)) | 337 | while ((iReturn > 0) && time_before(jiffies, ulTimeOut)) { |
334 | { | 338 | schedule(); // let other stuff run |
335 | schedule(); // let other stuff run | 339 | iReturn = InSelfTest(pdx, &state); // see if done yet |
336 | iReturn = InSelfTest(pdx, &state); // see if done yet | 340 | } |
337 | } | 341 | } |
338 | } | 342 | |
339 | 343 | if (iReturn == 0) // if all is OK... | |
340 | if (iReturn == 0) // if all is OK... | 344 | iReturn = state == 0; // then sucess is that the state is 0 |
341 | iReturn = state == 0; // then sucess is that the state is 0 | 345 | } else |
342 | } | 346 | iReturn = 0; // we failed |
343 | else | 347 | pdx->bForceReset = false; // Clear forced reset flag now |
344 | iReturn = 0; // we failed | 348 | |
345 | pdx->bForceReset = false; // Clear forced reset flag now | 349 | return iReturn > 0; |
346 | |||
347 | return iReturn > 0; | ||
348 | } | 350 | } |
349 | 351 | ||
350 | /**************************************************************************** | 352 | /**************************************************************************** |
@@ -361,44 +363,48 @@ bool Is1401(DEVICE_EXTENSION* pdx) | |||
361 | ** | 363 | ** |
362 | ** The return value is TRUE if a useable 1401 is found, FALSE if not | 364 | ** The return value is TRUE if a useable 1401 is found, FALSE if not |
363 | */ | 365 | */ |
364 | bool QuickCheck(DEVICE_EXTENSION* pdx, bool bTestBuff, bool bCanReset) | 366 | bool QuickCheck(DEVICE_EXTENSION * pdx, bool bTestBuff, bool bCanReset) |
365 | { | 367 | { |
366 | bool bRet = false; // assume it will fail and we will reset | 368 | bool bRet = false; // assume it will fail and we will reset |
367 | bool bShortTest; | 369 | bool bShortTest; |
368 | 370 | ||
369 | bShortTest = ((pdx->dwDMAFlag == MODE_CHAR) && // no DMA running | 371 | bShortTest = ((pdx->dwDMAFlag == MODE_CHAR) && // no DMA running |
370 | (!pdx->bForceReset) && // Not had a real reset forced | 372 | (!pdx->bForceReset) && // Not had a real reset forced |
371 | (pdx->sCurrentState >= U14ERR_STD)); // No 1401 errors stored | 373 | (pdx->sCurrentState >= U14ERR_STD)); // No 1401 errors stored |
372 | 374 | ||
373 | dev_dbg(&pdx->interface->dev, "%s DMAFlag:%d, state:%d, force:%d, testBuff:%d, short:%d", | 375 | dev_dbg(&pdx->interface->dev, |
374 | __func__, pdx->dwDMAFlag, pdx->sCurrentState, pdx->bForceReset, bTestBuff, bShortTest); | 376 | "%s DMAFlag:%d, state:%d, force:%d, testBuff:%d, short:%d", |
375 | 377 | __func__, pdx->dwDMAFlag, pdx->sCurrentState, pdx->bForceReset, | |
376 | if ((bTestBuff) && // Buffer check requested, and... | 378 | bTestBuff, bShortTest); |
377 | (pdx->dwNumInput || pdx->dwNumOutput)) // ...characters were in the buffer? | 379 | |
378 | { | 380 | if ((bTestBuff) && // Buffer check requested, and... |
379 | bShortTest = false; // Then do the full test | 381 | (pdx->dwNumInput || pdx->dwNumOutput)) // ...characters were in the buffer? |
380 | dev_dbg(&pdx->interface->dev, "%s will reset as buffers not empty", __func__); | 382 | { |
381 | } | 383 | bShortTest = false; // Then do the full test |
382 | 384 | dev_dbg(&pdx->interface->dev, | |
383 | if (bShortTest || !bCanReset) // Still OK to try the short test? | 385 | "%s will reset as buffers not empty", __func__); |
384 | { // Always test if no reset - we want state update | 386 | } |
385 | unsigned int state, error; | 387 | |
386 | dev_dbg(&pdx->interface->dev, "%s->Get1401State", __func__); | 388 | if (bShortTest || !bCanReset) // Still OK to try the short test? |
387 | if (Get1401State(pdx, &state, &error) == U14ERR_NOERROR) // Check on the 1401 state | 389 | { // Always test if no reset - we want state update |
388 | { | 390 | unsigned int state, error; |
389 | if ((state & 0xFF) == 0) // If call worked, check the status value | 391 | dev_dbg(&pdx->interface->dev, "%s->Get1401State", __func__); |
390 | bRet = true; // If that was zero, all is OK, no reset needed | 392 | if (Get1401State(pdx, &state, &error) == U14ERR_NOERROR) // Check on the 1401 state |
391 | } | 393 | { |
392 | } | 394 | if ((state & 0xFF) == 0) // If call worked, check the status value |
393 | 395 | bRet = true; // If that was zero, all is OK, no reset needed | |
394 | if (!bRet && bCanReset) // If all not OK, then | 396 | } |
395 | { | 397 | } |
396 | dev_info(&pdx->interface->dev, "%s->Is1401 %d %d %d %d", | 398 | |
397 | __func__, bShortTest, pdx->sCurrentState, bTestBuff, pdx->bForceReset); | 399 | if (!bRet && bCanReset) // If all not OK, then |
398 | bRet = Is1401(pdx); // do full test | 400 | { |
399 | } | 401 | dev_info(&pdx->interface->dev, "%s->Is1401 %d %d %d %d", |
400 | 402 | __func__, bShortTest, pdx->sCurrentState, bTestBuff, | |
401 | return bRet; | 403 | pdx->bForceReset); |
404 | bRet = Is1401(pdx); // do full test | ||
405 | } | ||
406 | |||
407 | return bRet; | ||
402 | } | 408 | } |
403 | 409 | ||
404 | /**************************************************************************** | 410 | /**************************************************************************** |
@@ -406,13 +412,13 @@ bool QuickCheck(DEVICE_EXTENSION* pdx, bool bTestBuff, bool bCanReset) | |||
406 | ** | 412 | ** |
407 | ** Resets the 1401 and empties the i/o buffers | 413 | ** Resets the 1401 and empties the i/o buffers |
408 | *****************************************************************************/ | 414 | *****************************************************************************/ |
409 | int Reset1401(DEVICE_EXTENSION *pdx) | 415 | int Reset1401(DEVICE_EXTENSION * pdx) |
410 | { | 416 | { |
411 | mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o | 417 | mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o |
412 | dev_dbg(&pdx->interface->dev,"ABout to call QuickCheck"); | 418 | dev_dbg(&pdx->interface->dev, "ABout to call QuickCheck"); |
413 | QuickCheck(pdx, true, true); // Check 1401, reset if not OK | 419 | QuickCheck(pdx, true, true); // Check 1401, reset if not OK |
414 | mutex_unlock(&pdx->io_mutex); | 420 | mutex_unlock(&pdx->io_mutex); |
415 | return U14ERR_NOERROR; | 421 | return U14ERR_NOERROR; |
416 | } | 422 | } |
417 | 423 | ||
418 | /**************************************************************************** | 424 | /**************************************************************************** |
@@ -420,32 +426,31 @@ int Reset1401(DEVICE_EXTENSION *pdx) | |||
420 | ** | 426 | ** |
421 | ** Gets a single character from the 1401 | 427 | ** Gets a single character from the 1401 |
422 | ****************************************************************************/ | 428 | ****************************************************************************/ |
423 | int GetChar(DEVICE_EXTENSION *pdx) | 429 | int GetChar(DEVICE_EXTENSION * pdx) |
424 | { | 430 | { |
425 | int iReturn = U14ERR_NOIN; // assume we will get nothing | 431 | int iReturn = U14ERR_NOIN; // assume we will get nothing |
426 | mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o | 432 | mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o |
427 | 433 | ||
428 | dev_dbg(&pdx->interface->dev, "GetChar"); | 434 | dev_dbg(&pdx->interface->dev, "GetChar"); |
429 | 435 | ||
430 | Allowi(pdx, false); // Make sure char reads are running | 436 | Allowi(pdx, false); // Make sure char reads are running |
431 | SendChars(pdx); // and send any buffered chars | 437 | SendChars(pdx); // and send any buffered chars |
432 | 438 | ||
433 | spin_lock_irq(&pdx->charInLock); | 439 | spin_lock_irq(&pdx->charInLock); |
434 | if (pdx->dwNumInput > 0) // worth looking | 440 | if (pdx->dwNumInput > 0) // worth looking |
435 | { | 441 | { |
436 | iReturn = pdx->inputBuffer[pdx->dwInBuffGet++]; | 442 | iReturn = pdx->inputBuffer[pdx->dwInBuffGet++]; |
437 | if (pdx->dwInBuffGet >= INBUF_SZ) | 443 | if (pdx->dwInBuffGet >= INBUF_SZ) |
438 | pdx->dwInBuffGet = 0; | 444 | pdx->dwInBuffGet = 0; |
439 | pdx->dwNumInput--; | 445 | pdx->dwNumInput--; |
440 | } | 446 | } else |
441 | else | 447 | iReturn = U14ERR_NOIN; // no input data to read |
442 | iReturn = U14ERR_NOIN; // no input data to read | 448 | spin_unlock_irq(&pdx->charInLock); |
443 | spin_unlock_irq(&pdx->charInLock); | 449 | |
444 | 450 | Allowi(pdx, false); // Make sure char reads are running | |
445 | Allowi(pdx, false); // Make sure char reads are running | 451 | |
446 | 452 | mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o | |
447 | mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o | 453 | return iReturn; |
448 | return iReturn; | ||
449 | } | 454 | } |
450 | 455 | ||
451 | /**************************************************************************** | 456 | /**************************************************************************** |
@@ -459,78 +464,77 @@ int GetChar(DEVICE_EXTENSION *pdx) | |||
459 | ** returns the count of characters (including the terminator, or 0 if none | 464 | ** returns the count of characters (including the terminator, or 0 if none |
460 | ** or a negative error code. | 465 | ** or a negative error code. |
461 | ****************************************************************************/ | 466 | ****************************************************************************/ |
462 | int GetString(DEVICE_EXTENSION *pdx, char __user* pUser, int n) | 467 | int GetString(DEVICE_EXTENSION * pdx, char __user * pUser, int n) |
463 | { | 468 | { |
464 | int nAvailable; // character in the buffer | 469 | int nAvailable; // character in the buffer |
465 | int iReturn = U14ERR_NOIN; | 470 | int iReturn = U14ERR_NOIN; |
466 | if (n <= 0) | 471 | if (n <= 0) |
467 | return -ENOMEM; | 472 | return -ENOMEM; |
468 | 473 | ||
469 | mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o | 474 | mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o |
470 | Allowi(pdx, false); // Make sure char reads are running | 475 | Allowi(pdx, false); // Make sure char reads are running |
471 | SendChars(pdx); // and send any buffered chars | 476 | SendChars(pdx); // and send any buffered chars |
472 | 477 | ||
473 | spin_lock_irq(&pdx->charInLock); | 478 | spin_lock_irq(&pdx->charInLock); |
474 | nAvailable = pdx->dwNumInput; // characters available now | 479 | nAvailable = pdx->dwNumInput; // characters available now |
475 | if (nAvailable > n) // read max of space in pUser... | 480 | if (nAvailable > n) // read max of space in pUser... |
476 | nAvailable = n; // ...or input characters | 481 | nAvailable = n; // ...or input characters |
477 | 482 | ||
478 | if (nAvailable > 0) // worth looking? | 483 | if (nAvailable > 0) // worth looking? |
479 | { | 484 | { |
480 | char buffer[INBUF_SZ+1]; // space for a linear copy of data | 485 | char buffer[INBUF_SZ + 1]; // space for a linear copy of data |
481 | int nGot = 0; | 486 | int nGot = 0; |
482 | int nCopyToUser; // number to copy to user | 487 | int nCopyToUser; // number to copy to user |
483 | char cData; | 488 | char cData; |
484 | do | 489 | do { |
485 | { | 490 | cData = pdx->inputBuffer[pdx->dwInBuffGet++]; |
486 | cData = pdx->inputBuffer[pdx->dwInBuffGet++]; | 491 | if (cData == CR_CHAR) // replace CR with zero |
487 | if (cData == CR_CHAR) // replace CR with zero | 492 | cData = (char)0; |
488 | cData = (char)0; | 493 | |
489 | 494 | if (pdx->dwInBuffGet >= INBUF_SZ) | |
490 | if (pdx->dwInBuffGet >= INBUF_SZ) | 495 | pdx->dwInBuffGet = 0; // wrap buffer pointer |
491 | pdx->dwInBuffGet = 0; // wrap buffer pointer | 496 | |
492 | 497 | buffer[nGot++] = cData; // save the output | |
493 | buffer[nGot++] = cData; // save the output | 498 | } |
494 | } | 499 | while ((nGot < nAvailable) && cData); |
495 | while((nGot < nAvailable) && cData); | 500 | |
496 | 501 | nCopyToUser = nGot; // what to copy... | |
497 | nCopyToUser = nGot; // what to copy... | 502 | if (cData) // do we need null |
498 | if (cData) // do we need null | 503 | { |
499 | { | 504 | buffer[nGot] = (char)0; // make it tidy |
500 | buffer[nGot] = (char)0; // make it tidy | 505 | if (nGot < n) // if space in user buffer... |
501 | if (nGot < n) // if space in user buffer... | 506 | ++nCopyToUser; // ...copy the 0 as well. |
502 | ++nCopyToUser; // ...copy the 0 as well. | 507 | } |
503 | } | 508 | |
504 | 509 | pdx->dwNumInput -= nGot; | |
505 | pdx->dwNumInput -= nGot; | 510 | spin_unlock_irq(&pdx->charInLock); |
506 | spin_unlock_irq(&pdx->charInLock); | 511 | |
507 | 512 | dev_dbg(&pdx->interface->dev, | |
508 | dev_dbg(&pdx->interface->dev,"GetString read %d characters >%s<", nGot, buffer); | 513 | "GetString read %d characters >%s<", nGot, buffer); |
509 | copy_to_user(pUser, buffer, nCopyToUser); | 514 | copy_to_user(pUser, buffer, nCopyToUser); |
510 | 515 | ||
511 | iReturn = nGot; // report characters read | 516 | iReturn = nGot; // report characters read |
512 | } | 517 | } else |
513 | else | 518 | spin_unlock_irq(&pdx->charInLock); |
514 | spin_unlock_irq(&pdx->charInLock); | 519 | |
515 | 520 | Allowi(pdx, false); // Make sure char reads are running | |
516 | Allowi(pdx, false); // Make sure char reads are running | 521 | mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o |
517 | mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o | 522 | |
518 | 523 | return iReturn; | |
519 | return iReturn; | ||
520 | } | 524 | } |
521 | 525 | ||
522 | /******************************************************************************* | 526 | /******************************************************************************* |
523 | ** Get count of characters in the inout buffer. | 527 | ** Get count of characters in the inout buffer. |
524 | *******************************************************************************/ | 528 | *******************************************************************************/ |
525 | int Stat1401(DEVICE_EXTENSION *pdx) | 529 | int Stat1401(DEVICE_EXTENSION * pdx) |
526 | { | 530 | { |
527 | int iReturn; | 531 | int iReturn; |
528 | mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o | 532 | mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o |
529 | Allowi(pdx, false); // make sure we allow pending chars | 533 | Allowi(pdx, false); // make sure we allow pending chars |
530 | SendChars(pdx); // in both directions | 534 | SendChars(pdx); // in both directions |
531 | iReturn = pdx->dwNumInput; // no lock as single read | 535 | iReturn = pdx->dwNumInput; // no lock as single read |
532 | mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o | 536 | mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o |
533 | return iReturn; | 537 | return iReturn; |
534 | } | 538 | } |
535 | 539 | ||
536 | /**************************************************************************** | 540 | /**************************************************************************** |
@@ -540,34 +544,33 @@ int Stat1401(DEVICE_EXTENSION *pdx) | |||
540 | ** any fancy interlocks as we only read the interrupt routine data, and the | 544 | ** any fancy interlocks as we only read the interrupt routine data, and the |
541 | ** system is arranged so nothing can be destroyed. | 545 | ** system is arranged so nothing can be destroyed. |
542 | ****************************************************************************/ | 546 | ****************************************************************************/ |
543 | int LineCount(DEVICE_EXTENSION *pdx) | 547 | int LineCount(DEVICE_EXTENSION * pdx) |
544 | { | 548 | { |
545 | int iReturn = 0; // will be count of line ends | 549 | int iReturn = 0; // will be count of line ends |
546 | 550 | ||
547 | mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o | 551 | mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o |
548 | Allowi(pdx, false); // Make sure char reads are running | 552 | Allowi(pdx, false); // Make sure char reads are running |
549 | SendChars(pdx); // and send any buffered chars | 553 | SendChars(pdx); // and send any buffered chars |
550 | spin_lock_irq(&pdx->charInLock); // Get protection | 554 | spin_lock_irq(&pdx->charInLock); // Get protection |
551 | 555 | ||
552 | if (pdx->dwNumInput > 0) // worth looking? | 556 | if (pdx->dwNumInput > 0) // worth looking? |
553 | { | 557 | { |
554 | unsigned int dwIndex = pdx->dwInBuffGet;// start at first available | 558 | unsigned int dwIndex = pdx->dwInBuffGet; // start at first available |
555 | unsigned int dwEnd = pdx->dwInBuffPut; // Position for search end | 559 | unsigned int dwEnd = pdx->dwInBuffPut; // Position for search end |
556 | do | 560 | do { |
557 | { | 561 | if (pdx->inputBuffer[dwIndex++] == CR_CHAR) |
558 | if (pdx->inputBuffer[dwIndex++] == CR_CHAR) | 562 | ++iReturn; // inc count if CR |
559 | ++iReturn; // inc count if CR | 563 | |
560 | 564 | if (dwIndex >= INBUF_SZ) // see if we fall off buff | |
561 | if (dwIndex >= INBUF_SZ) // see if we fall off buff | 565 | dwIndex = 0; |
562 | dwIndex = 0; | 566 | } |
563 | } | 567 | while (dwIndex != dwEnd); // go to last avaliable |
564 | while (dwIndex != dwEnd); // go to last avaliable | 568 | } |
565 | } | 569 | |
566 | 570 | spin_unlock_irq(&pdx->charInLock); | |
567 | spin_unlock_irq(&pdx->charInLock); | 571 | dev_dbg(&pdx->interface->dev, "LineCount returned %d", iReturn); |
568 | dev_dbg(&pdx->interface->dev,"LineCount returned %d", iReturn); | 572 | mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o |
569 | mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o | 573 | return iReturn; |
570 | return iReturn; | ||
571 | } | 574 | } |
572 | 575 | ||
573 | /**************************************************************************** | 576 | /**************************************************************************** |
@@ -575,15 +578,15 @@ int LineCount(DEVICE_EXTENSION *pdx) | |||
575 | ** | 578 | ** |
576 | ** Gets the space in the output buffer. Called from user code. | 579 | ** Gets the space in the output buffer. Called from user code. |
577 | *****************************************************************************/ | 580 | *****************************************************************************/ |
578 | int GetOutBufSpace(DEVICE_EXTENSION *pdx) | 581 | int GetOutBufSpace(DEVICE_EXTENSION * pdx) |
579 | { | 582 | { |
580 | int iReturn; | 583 | int iReturn; |
581 | mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o | 584 | mutex_lock(&pdx->io_mutex); // Protect disconnect from new i/o |
582 | SendChars(pdx); // send any buffered chars | 585 | SendChars(pdx); // send any buffered chars |
583 | iReturn = (int)(OUTBUF_SZ - pdx->dwNumOutput); // no lock needed for single read | 586 | iReturn = (int)(OUTBUF_SZ - pdx->dwNumOutput); // no lock needed for single read |
584 | dev_dbg(&pdx->interface->dev,"OutBufSpace %d", iReturn); | 587 | dev_dbg(&pdx->interface->dev, "OutBufSpace %d", iReturn); |
585 | mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o | 588 | mutex_unlock(&pdx->io_mutex); // Protect disconnect from new i/o |
586 | return iReturn; | 589 | return iReturn; |
587 | } | 590 | } |
588 | 591 | ||
589 | /**************************************************************************** | 592 | /**************************************************************************** |
@@ -593,74 +596,75 @@ int GetOutBufSpace(DEVICE_EXTENSION *pdx) | |||
593 | ** Clears up a transfer area. This is always called in the context of a user | 596 | ** Clears up a transfer area. This is always called in the context of a user |
594 | ** request, never from a call-back. | 597 | ** request, never from a call-back. |
595 | ****************************************************************************/ | 598 | ****************************************************************************/ |
596 | int ClearArea(DEVICE_EXTENSION *pdx, int nArea) | 599 | int ClearArea(DEVICE_EXTENSION * pdx, int nArea) |
597 | { | 600 | { |
598 | int iReturn = U14ERR_NOERROR; | 601 | int iReturn = U14ERR_NOERROR; |
599 | 602 | ||
600 | if ((nArea < 0) || (nArea >= MAX_TRANSAREAS)) | 603 | if ((nArea < 0) || (nArea >= MAX_TRANSAREAS)) { |
601 | { | 604 | iReturn = U14ERR_BADAREA; |
602 | iReturn = U14ERR_BADAREA; | 605 | dev_err(&pdx->interface->dev, "%s Attempt to clear area %d", |
603 | dev_err(&pdx->interface->dev, "%s Attempt to clear area %d", __func__, nArea); | 606 | __func__, nArea); |
604 | } | 607 | } else { |
605 | else | 608 | TRANSAREA *pTA = &pdx->rTransDef[nArea]; // to save typing |
606 | { | 609 | if (!pTA->bUsed) // if not used... |
607 | TRANSAREA *pTA = &pdx->rTransDef[nArea]; // to save typing | 610 | iReturn = U14ERR_NOTSET; // ...nothing to be done |
608 | if (!pTA->bUsed) // if not used... | 611 | else { |
609 | iReturn = U14ERR_NOTSET; // ...nothing to be done | 612 | // We must save the memory we return as we shouldn't mess with memory while |
610 | else | 613 | // holding a spin lock. |
611 | { | 614 | struct page **pPages = 0; // save page address list |
612 | // We must save the memory we return as we shouldn't mess with memory while | 615 | int nPages = 0; // and number of pages |
613 | // holding a spin lock. | 616 | int np; |
614 | struct page **pPages = 0; // save page address list | 617 | |
615 | int nPages = 0; // and number of pages | 618 | dev_dbg(&pdx->interface->dev, "%s area %d", __func__, |
616 | int np; | 619 | nArea); |
617 | 620 | spin_lock_irq(&pdx->stagedLock); | |
618 | dev_dbg(&pdx->interface->dev, "%s area %d", __func__, nArea); | 621 | if ((pdx->StagedId == nArea) |
619 | spin_lock_irq(&pdx->stagedLock); | 622 | && (pdx->dwDMAFlag > MODE_CHAR)) { |
620 | if ((pdx->StagedId == nArea) && (pdx->dwDMAFlag > MODE_CHAR)) | 623 | iReturn = U14ERR_UNLOCKFAIL; // cannot delete as in use |
621 | { | 624 | dev_err(&pdx->interface->dev, |
622 | iReturn = U14ERR_UNLOCKFAIL; // cannot delete as in use | 625 | "%s call on area %d while active", |
623 | dev_err(&pdx->interface->dev, "%s call on area %d while active", __func__, nArea); | 626 | __func__, nArea); |
624 | } | 627 | } else { |
625 | else | 628 | pPages = pTA->pPages; // save page address list |
626 | { | 629 | nPages = pTA->nPages; // and page count |
627 | pPages = pTA->pPages; // save page address list | 630 | if (pTA->dwEventSz) // if events flagging in use |
628 | nPages = pTA->nPages; // and page count | 631 | wake_up_interruptible(&pTA->wqEvent); // release anything that was waiting |
629 | if (pTA->dwEventSz) // if events flagging in use | 632 | |
630 | wake_up_interruptible(&pTA->wqEvent); // release anything that was waiting | 633 | if (pdx->bXFerWaiting |
631 | 634 | && (pdx->rDMAInfo.wIdent == nArea)) | |
632 | if (pdx->bXFerWaiting && (pdx->rDMAInfo.wIdent == nArea)) | 635 | pdx->bXFerWaiting = false; // Cannot have pending xfer if area cleared |
633 | pdx->bXFerWaiting = false; // Cannot have pending xfer if area cleared | 636 | |
634 | 637 | // Clean out the TRANSAREA except for the wait queue, which is at the end | |
635 | // Clean out the TRANSAREA except for the wait queue, which is at the end | 638 | // This sets bUsed to false and dwEventSz to 0 to say area not used and no events. |
636 | // This sets bUsed to false and dwEventSz to 0 to say area not used and no events. | 639 | memset(pTA, 0, |
637 | memset(pTA, 0, sizeof(TRANSAREA)-sizeof(wait_queue_head_t)); | 640 | sizeof(TRANSAREA) - |
638 | } | 641 | sizeof(wait_queue_head_t)); |
639 | spin_unlock_irq(&pdx->stagedLock); | 642 | } |
640 | 643 | spin_unlock_irq(&pdx->stagedLock); | |
641 | if (pPages) // if we decided to release the memory | 644 | |
642 | { | 645 | if (pPages) // if we decided to release the memory |
643 | // Now we must undo the pinning down of the pages. We will assume the worst and mark | 646 | { |
644 | // all the pages as dirty. Don't be tempted to move this up above as you must not be | 647 | // Now we must undo the pinning down of the pages. We will assume the worst and mark |
645 | // holding a spin lock to do this stuff as it is not atomic. | 648 | // all the pages as dirty. Don't be tempted to move this up above as you must not be |
646 | dev_dbg(&pdx->interface->dev, "%s nPages=%d", __func__, nPages); | 649 | // holding a spin lock to do this stuff as it is not atomic. |
647 | 650 | dev_dbg(&pdx->interface->dev, "%s nPages=%d", | |
648 | for (np = 0; np < nPages; ++np) | 651 | __func__, nPages); |
649 | { | 652 | |
650 | if (pPages[np]) | 653 | for (np = 0; np < nPages; ++np) { |
651 | { | 654 | if (pPages[np]) { |
652 | SetPageDirty(pPages[np]); | 655 | SetPageDirty(pPages[np]); |
653 | page_cache_release(pPages[np]); | 656 | page_cache_release(pPages[np]); |
654 | } | 657 | } |
655 | } | 658 | } |
656 | 659 | ||
657 | kfree(pPages); | 660 | kfree(pPages); |
658 | dev_dbg(&pdx->interface->dev, "%s kfree(pPages) done", __func__); | 661 | dev_dbg(&pdx->interface->dev, |
659 | } | 662 | "%s kfree(pPages) done", __func__); |
660 | } | 663 | } |
661 | } | 664 | } |
662 | 665 | } | |
663 | return iReturn; | 666 | |
667 | return iReturn; | ||
664 | } | 668 | } |
665 | 669 | ||
666 | /**************************************************************************** | 670 | /**************************************************************************** |
@@ -669,78 +673,78 @@ int ClearArea(DEVICE_EXTENSION *pdx, int nArea) | |||
669 | ** Sets up a transfer area - the functional part. Called by both | 673 | ** Sets up a transfer area - the functional part. Called by both |
670 | ** SetTransfer and SetCircular. | 674 | ** SetTransfer and SetCircular. |
671 | ****************************************************************************/ | 675 | ****************************************************************************/ |
672 | static int SetArea(DEVICE_EXTENSION *pdx, int nArea, char __user* puBuf, | 676 | static int SetArea(DEVICE_EXTENSION * pdx, int nArea, char __user * puBuf, |
673 | unsigned int dwLength, bool bCircular, bool bCircToHost) | 677 | unsigned int dwLength, bool bCircular, bool bCircToHost) |
674 | { | 678 | { |
675 | // Start by working out the page aligned start of the area and the size | 679 | // Start by working out the page aligned start of the area and the size |
676 | // of the area in pages, allowing for the start not being aligned and the | 680 | // of the area in pages, allowing for the start not being aligned and the |
677 | // end needing to be rounded up to a page boundary. | 681 | // end needing to be rounded up to a page boundary. |
678 | unsigned long ulStart = ((unsigned long)puBuf) & PAGE_MASK; | 682 | unsigned long ulStart = ((unsigned long)puBuf) & PAGE_MASK; |
679 | unsigned int ulOffset = ((unsigned long)puBuf) & (PAGE_SIZE-1); | 683 | unsigned int ulOffset = ((unsigned long)puBuf) & (PAGE_SIZE - 1); |
680 | int len = (dwLength + ulOffset+PAGE_SIZE - 1) >> PAGE_SHIFT; | 684 | int len = (dwLength + ulOffset + PAGE_SIZE - 1) >> PAGE_SHIFT; |
681 | 685 | ||
682 | TRANSAREA *pTA = &pdx->rTransDef[nArea]; // to save typing | 686 | TRANSAREA *pTA = &pdx->rTransDef[nArea]; // to save typing |
683 | struct page **pPages = 0; // space for page tables | 687 | struct page **pPages = 0; // space for page tables |
684 | int nPages = 0; // and number of pages | 688 | int nPages = 0; // and number of pages |
685 | 689 | ||
686 | int iReturn = ClearArea(pdx, nArea); // see if OK to use this area | 690 | int iReturn = ClearArea(pdx, nArea); // see if OK to use this area |
687 | if ((iReturn != U14ERR_NOTSET) && // if not area unused and... | 691 | if ((iReturn != U14ERR_NOTSET) && // if not area unused and... |
688 | (iReturn != U14ERR_NOERROR)) // ...not all OK, then... | 692 | (iReturn != U14ERR_NOERROR)) // ...not all OK, then... |
689 | return iReturn; // ...we cannot use this area | 693 | return iReturn; // ...we cannot use this area |
690 | 694 | ||
691 | if (!access_ok(VERIFY_WRITE, puBuf, dwLength)) // if we cannot access the memory... | 695 | if (!access_ok(VERIFY_WRITE, puBuf, dwLength)) // if we cannot access the memory... |
692 | return -EFAULT; // ...then we are done | 696 | return -EFAULT; // ...then we are done |
693 | 697 | ||
694 | // Now allocate space to hold the page pointer and virtual address pointer tables | 698 | // Now allocate space to hold the page pointer and virtual address pointer tables |
695 | pPages = (struct page **)kmalloc(len*sizeof(struct page *), GFP_KERNEL); | 699 | pPages = |
696 | if (!pPages) | 700 | (struct page **)kmalloc(len * sizeof(struct page *), GFP_KERNEL); |
697 | { | 701 | if (!pPages) { |
698 | iReturn = U14ERR_NOMEMORY; | 702 | iReturn = U14ERR_NOMEMORY; |
699 | goto error; | 703 | goto error; |
700 | } | 704 | } |
701 | dev_dbg(&pdx->interface->dev, "%s %p, length=%06x, circular %d", __func__, puBuf, dwLength, bCircular); | 705 | dev_dbg(&pdx->interface->dev, "%s %p, length=%06x, circular %d", |
702 | 706 | __func__, puBuf, dwLength, bCircular); | |
703 | // To pin down user pages we must first acquire the mapping semaphore. | 707 | |
704 | down_read(¤t->mm->mmap_sem); // get memory map semaphore | 708 | // To pin down user pages we must first acquire the mapping semaphore. |
705 | nPages = get_user_pages(current, current->mm, ulStart, len, 1, 0, pPages, 0); | 709 | down_read(¤t->mm->mmap_sem); // get memory map semaphore |
706 | up_read(¤t->mm->mmap_sem); // release the semaphore | 710 | nPages = |
707 | dev_dbg(&pdx->interface->dev, "%s nPages = %d", __func__, nPages); | 711 | get_user_pages(current, current->mm, ulStart, len, 1, 0, pPages, 0); |
708 | 712 | up_read(¤t->mm->mmap_sem); // release the semaphore | |
709 | if (nPages > 0) // if we succeeded | 713 | dev_dbg(&pdx->interface->dev, "%s nPages = %d", __func__, nPages); |
710 | { | 714 | |
711 | // If you are tempted to use page_address (form LDD3), forget it. You MUST use | 715 | if (nPages > 0) // if we succeeded |
712 | // kmap() or kmap_atomic() to get a virtual address. page_address will give you | 716 | { |
713 | // (null) or at least it does in this context with an x86 machine. | 717 | // If you are tempted to use page_address (form LDD3), forget it. You MUST use |
714 | spin_lock_irq(&pdx->stagedLock); | 718 | // kmap() or kmap_atomic() to get a virtual address. page_address will give you |
715 | pTA->lpvBuff = puBuf; // keep start of region (user address) | 719 | // (null) or at least it does in this context with an x86 machine. |
716 | pTA->dwBaseOffset = ulOffset; // save offset in first page to start of xfer | 720 | spin_lock_irq(&pdx->stagedLock); |
717 | pTA->dwLength = dwLength; // Size if the region in bytes | 721 | pTA->lpvBuff = puBuf; // keep start of region (user address) |
718 | pTA->pPages = pPages; // list of pages that are used by buffer | 722 | pTA->dwBaseOffset = ulOffset; // save offset in first page to start of xfer |
719 | pTA->nPages = nPages; // number of pages | 723 | pTA->dwLength = dwLength; // Size if the region in bytes |
720 | 724 | pTA->pPages = pPages; // list of pages that are used by buffer | |
721 | pTA->bCircular = bCircular; | 725 | pTA->nPages = nPages; // number of pages |
722 | pTA->bCircToHost = bCircToHost; | 726 | |
723 | 727 | pTA->bCircular = bCircular; | |
724 | pTA->aBlocks[0].dwOffset = 0; | 728 | pTA->bCircToHost = bCircToHost; |
725 | pTA->aBlocks[0].dwSize = 0; | 729 | |
726 | pTA->aBlocks[1].dwOffset = 0; | 730 | pTA->aBlocks[0].dwOffset = 0; |
727 | pTA->aBlocks[1].dwSize = 0; | 731 | pTA->aBlocks[0].dwSize = 0; |
728 | pTA->bUsed = true; // This is now a used block | 732 | pTA->aBlocks[1].dwOffset = 0; |
729 | 733 | pTA->aBlocks[1].dwSize = 0; | |
730 | spin_unlock_irq(&pdx->stagedLock); | 734 | pTA->bUsed = true; // This is now a used block |
731 | iReturn = U14ERR_NOERROR; // say all was well | 735 | |
732 | } | 736 | spin_unlock_irq(&pdx->stagedLock); |
733 | else | 737 | iReturn = U14ERR_NOERROR; // say all was well |
734 | { | 738 | } else { |
735 | iReturn = U14ERR_LOCKFAIL; | 739 | iReturn = U14ERR_LOCKFAIL; |
736 | goto error; | 740 | goto error; |
737 | } | 741 | } |
738 | 742 | ||
739 | return iReturn; | 743 | return iReturn; |
740 | 744 | ||
741 | error: | 745 | error: |
742 | kfree(pPages); | 746 | kfree(pPages); |
743 | return iReturn; | 747 | return iReturn; |
744 | } | 748 | } |
745 | 749 | ||
746 | /**************************************************************************** | 750 | /**************************************************************************** |
@@ -750,32 +754,36 @@ error: | |||
750 | ** unset it. Unsetting will fail if the area is booked, and a transfer to that | 754 | ** unset it. Unsetting will fail if the area is booked, and a transfer to that |
751 | ** area is in progress. Otherwise, we will release the area and re-assign it. | 755 | ** area is in progress. Otherwise, we will release the area and re-assign it. |
752 | ****************************************************************************/ | 756 | ****************************************************************************/ |
753 | int SetTransfer(DEVICE_EXTENSION *pdx, TRANSFERDESC __user *pTD) | 757 | int SetTransfer(DEVICE_EXTENSION * pdx, TRANSFERDESC __user * pTD) |
754 | { | 758 | { |
755 | int iReturn; | 759 | int iReturn; |
756 | TRANSFERDESC td; | 760 | TRANSFERDESC td; |
757 | copy_from_user(&td, pTD, sizeof(td)); | 761 | copy_from_user(&td, pTD, sizeof(td)); |
758 | mutex_lock(&pdx->io_mutex); | 762 | mutex_lock(&pdx->io_mutex); |
759 | dev_dbg(&pdx->interface->dev,"%s area:%d, size:%08x", __func__, td.wAreaNum, td.dwLength); | 763 | dev_dbg(&pdx->interface->dev, "%s area:%d, size:%08x", __func__, |
760 | // The strange cast is done so that we don't get warnings in 32-bit linux about the size of the | 764 | td.wAreaNum, td.dwLength); |
761 | // pointer. The pointer is always passed as a 64-bit object so that we don't have problems using | 765 | // The strange cast is done so that we don't get warnings in 32-bit linux about the size of the |
762 | // a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system. | 766 | // pointer. The pointer is always passed as a 64-bit object so that we don't have problems using |
763 | iReturn = SetArea(pdx, td.wAreaNum, (char __user *)((unsigned long)td.lpvBuff), td.dwLength, false, false); | 767 | // a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system. |
764 | mutex_unlock(&pdx->io_mutex); | 768 | iReturn = |
765 | return iReturn; | 769 | SetArea(pdx, td.wAreaNum, |
770 | (char __user *)((unsigned long)td.lpvBuff), td.dwLength, | ||
771 | false, false); | ||
772 | mutex_unlock(&pdx->io_mutex); | ||
773 | return iReturn; | ||
766 | } | 774 | } |
767 | 775 | ||
768 | /**************************************************************************** | 776 | /**************************************************************************** |
769 | ** UnSetTransfer | 777 | ** UnSetTransfer |
770 | ** Erases a transfer area record | 778 | ** Erases a transfer area record |
771 | ****************************************************************************/ | 779 | ****************************************************************************/ |
772 | int UnsetTransfer(DEVICE_EXTENSION *pdx, int nArea) | 780 | int UnsetTransfer(DEVICE_EXTENSION * pdx, int nArea) |
773 | { | 781 | { |
774 | int iReturn; | 782 | int iReturn; |
775 | mutex_lock(&pdx->io_mutex); | 783 | mutex_lock(&pdx->io_mutex); |
776 | iReturn = ClearArea(pdx, nArea); | 784 | iReturn = ClearArea(pdx, nArea); |
777 | mutex_unlock(&pdx->io_mutex); | 785 | mutex_unlock(&pdx->io_mutex); |
778 | return iReturn; | 786 | return iReturn; |
779 | } | 787 | } |
780 | 788 | ||
781 | /**************************************************************************** | 789 | /**************************************************************************** |
@@ -786,31 +794,30 @@ int UnsetTransfer(DEVICE_EXTENSION *pdx, int nArea) | |||
786 | ** pretend that whatever the user asked for was achieved, so we return 1 if | 794 | ** pretend that whatever the user asked for was achieved, so we return 1 if |
787 | ** try to create one, and 0 if they ask to remove (assuming all else was OK). | 795 | ** try to create one, and 0 if they ask to remove (assuming all else was OK). |
788 | ****************************************************************************/ | 796 | ****************************************************************************/ |
789 | int SetEvent(DEVICE_EXTENSION *pdx, TRANSFEREVENT __user*pTE) | 797 | int SetEvent(DEVICE_EXTENSION * pdx, TRANSFEREVENT __user * pTE) |
790 | { | 798 | { |
791 | int iReturn = U14ERR_NOERROR; | 799 | int iReturn = U14ERR_NOERROR; |
792 | TRANSFEREVENT te; | 800 | TRANSFEREVENT te; |
793 | copy_from_user(&te, pTE, sizeof(te)); // get a local copy of the data | 801 | copy_from_user(&te, pTE, sizeof(te)); // get a local copy of the data |
794 | if (te.wAreaNum >= MAX_TRANSAREAS) // the area must exist | 802 | if (te.wAreaNum >= MAX_TRANSAREAS) // the area must exist |
795 | return U14ERR_BADAREA; | 803 | return U14ERR_BADAREA; |
796 | else | 804 | else { |
797 | { | 805 | TRANSAREA *pTA = &pdx->rTransDef[te.wAreaNum]; |
798 | TRANSAREA *pTA = &pdx->rTransDef[te.wAreaNum]; | 806 | mutex_lock(&pdx->io_mutex); // make sure we have no competitor |
799 | mutex_lock(&pdx->io_mutex); // make sure we have no competitor | 807 | spin_lock_irq(&pdx->stagedLock); |
800 | spin_lock_irq(&pdx->stagedLock); | 808 | if (pTA->bUsed) // area must be in use |
801 | if (pTA->bUsed) // area must be in use | 809 | { |
802 | { | 810 | pTA->dwEventSt = te.dwStart; // set area regions |
803 | pTA->dwEventSt = te.dwStart; // set area regions | 811 | pTA->dwEventSz = te.dwLength; // set size (0 cancels it) |
804 | pTA->dwEventSz = te.dwLength; // set size (0 cancels it) | 812 | pTA->bEventToHost = te.wFlags & 1; // set the direction |
805 | pTA->bEventToHost = te.wFlags & 1; // set the direction | 813 | pTA->iWakeUp = 0; // zero the wake up count |
806 | pTA->iWakeUp = 0; // zero the wake up count | 814 | } else |
807 | } | 815 | iReturn = U14ERR_NOTSET; |
808 | else | 816 | spin_unlock_irq(&pdx->stagedLock); |
809 | iReturn = U14ERR_NOTSET; | 817 | mutex_unlock(&pdx->io_mutex); |
810 | spin_unlock_irq(&pdx->stagedLock); | 818 | } |
811 | mutex_unlock(&pdx->io_mutex); | 819 | return iReturn == |
812 | } | 820 | U14ERR_NOERROR ? (te.iSetEvent ? 1 : U14ERR_NOERROR) : iReturn; |
813 | return iReturn == U14ERR_NOERROR ? (te.iSetEvent ? 1 : U14ERR_NOERROR) : iReturn; | ||
814 | } | 821 | } |
815 | 822 | ||
816 | /**************************************************************************** | 823 | /**************************************************************************** |
@@ -819,40 +826,45 @@ int SetEvent(DEVICE_EXTENSION *pdx, TRANSFEREVENT __user*pTE) | |||
819 | ** of times that a block met the event condition since we last cleared it or | 826 | ** of times that a block met the event condition since we last cleared it or |
820 | ** 0 if timed out, or -ve error (bad area or not set, or signal). | 827 | ** 0 if timed out, or -ve error (bad area or not set, or signal). |
821 | ****************************************************************************/ | 828 | ****************************************************************************/ |
822 | int WaitEvent(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut) | 829 | int WaitEvent(DEVICE_EXTENSION * pdx, int nArea, int msTimeOut) |
823 | { | 830 | { |
824 | int iReturn; | 831 | int iReturn; |
825 | if ((unsigned)nArea > MAX_TRANSAREAS) | 832 | if ((unsigned)nArea > MAX_TRANSAREAS) |
826 | return U14ERR_BADAREA; | 833 | return U14ERR_BADAREA; |
827 | else | 834 | else { |
828 | { | 835 | int iWait; |
829 | int iWait; | 836 | TRANSAREA *pTA = &pdx->rTransDef[nArea]; |
830 | TRANSAREA *pTA = &pdx->rTransDef[nArea]; | 837 | msTimeOut = (msTimeOut * HZ + 999) / 1000; // convert timeout to jiffies |
831 | msTimeOut = (msTimeOut * HZ + 999)/1000; // convert timeout to jiffies | 838 | |
832 | 839 | // We cannot wait holding the mutex, but we check the flags while holding | |
833 | // We cannot wait holding the mutex, but we check the flags while holding | 840 | // it. This may well be pointless as another thread could get in between |
834 | // it. This may well be pointless as another thread could get in between | 841 | // releasing it and the wait call. However, this would have to clear the |
835 | // releasing it and the wait call. However, this would have to clear the | 842 | // iWakeUp flag. However, the !pTA-bUsed may help us in this case. |
836 | // iWakeUp flag. However, the !pTA-bUsed may help us in this case. | 843 | mutex_lock(&pdx->io_mutex); // make sure we have no competitor |
837 | mutex_lock(&pdx->io_mutex); // make sure we have no competitor | 844 | if (!pTA->bUsed || !pTA->dwEventSz) // check something to wait for... |
838 | if (!pTA->bUsed || !pTA->dwEventSz) // check something to wait for... | 845 | return U14ERR_NOTSET; // ...else we do nothing |
839 | return U14ERR_NOTSET; // ...else we do nothing | 846 | mutex_unlock(&pdx->io_mutex); |
840 | mutex_unlock(&pdx->io_mutex); | 847 | |
841 | 848 | if (msTimeOut) | |
842 | if (msTimeOut) | 849 | iWait = |
843 | iWait = wait_event_interruptible_timeout(pTA->wqEvent, pTA->iWakeUp || !pTA->bUsed, msTimeOut); | 850 | wait_event_interruptible_timeout(pTA->wqEvent, |
844 | else | 851 | pTA->iWakeUp |
845 | iWait = wait_event_interruptible(pTA->wqEvent, pTA->iWakeUp || !pTA->bUsed); | 852 | || !pTA->bUsed, |
846 | if (iWait) | 853 | msTimeOut); |
847 | iReturn = -ERESTARTSYS; // oops - we have had a SIGNAL | 854 | else |
848 | else | 855 | iWait = |
849 | iReturn = pTA->iWakeUp; // else the wakeup count | 856 | wait_event_interruptible(pTA->wqEvent, pTA->iWakeUp |
850 | 857 | || !pTA->bUsed); | |
851 | spin_lock_irq(&pdx->stagedLock); | 858 | if (iWait) |
852 | pTA->iWakeUp = 0; // clear the flag | 859 | iReturn = -ERESTARTSYS; // oops - we have had a SIGNAL |
853 | spin_unlock_irq(&pdx->stagedLock); | 860 | else |
854 | } | 861 | iReturn = pTA->iWakeUp; // else the wakeup count |
855 | return iReturn; | 862 | |
863 | spin_lock_irq(&pdx->stagedLock); | ||
864 | pTA->iWakeUp = 0; // clear the flag | ||
865 | spin_unlock_irq(&pdx->stagedLock); | ||
866 | } | ||
867 | return iReturn; | ||
856 | } | 868 | } |
857 | 869 | ||
858 | /**************************************************************************** | 870 | /**************************************************************************** |
@@ -861,52 +873,51 @@ int WaitEvent(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut) | |||
861 | ** number of times a block completed since the last call, or 0 if none or a | 873 | ** number of times a block completed since the last call, or 0 if none or a |
862 | ** negative error. | 874 | ** negative error. |
863 | ****************************************************************************/ | 875 | ****************************************************************************/ |
864 | int TestEvent(DEVICE_EXTENSION *pdx, int nArea) | 876 | int TestEvent(DEVICE_EXTENSION * pdx, int nArea) |
865 | { | 877 | { |
866 | int iReturn; | 878 | int iReturn; |
867 | if ((unsigned)nArea > MAX_TRANSAREAS) | 879 | if ((unsigned)nArea > MAX_TRANSAREAS) |
868 | iReturn = U14ERR_BADAREA; | 880 | iReturn = U14ERR_BADAREA; |
869 | else | 881 | else { |
870 | { | 882 | TRANSAREA *pTA = &pdx->rTransDef[nArea]; |
871 | TRANSAREA *pTA = &pdx->rTransDef[nArea]; | 883 | mutex_lock(&pdx->io_mutex); // make sure we have no competitor |
872 | mutex_lock(&pdx->io_mutex); // make sure we have no competitor | 884 | spin_lock_irq(&pdx->stagedLock); |
873 | spin_lock_irq(&pdx->stagedLock); | 885 | iReturn = pTA->iWakeUp; // get wakeup count since last call |
874 | iReturn = pTA->iWakeUp; // get wakeup count since last call | 886 | pTA->iWakeUp = 0; // clear the count |
875 | pTA->iWakeUp = 0; // clear the count | 887 | spin_unlock_irq(&pdx->stagedLock); |
876 | spin_unlock_irq(&pdx->stagedLock); | 888 | mutex_unlock(&pdx->io_mutex); |
877 | mutex_unlock(&pdx->io_mutex); | 889 | } |
878 | } | 890 | return iReturn; |
879 | return iReturn; | ||
880 | } | 891 | } |
881 | 892 | ||
882 | /**************************************************************************** | 893 | /**************************************************************************** |
883 | ** GetTransferInfo | 894 | ** GetTransferInfo |
884 | ** Puts the current state of the 1401 in a TGET_TX_BLOCK. | 895 | ** Puts the current state of the 1401 in a TGET_TX_BLOCK. |
885 | *****************************************************************************/ | 896 | *****************************************************************************/ |
886 | int GetTransfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pTX) | 897 | int GetTransfer(DEVICE_EXTENSION * pdx, TGET_TX_BLOCK __user * pTX) |
887 | { | 898 | { |
888 | int iReturn = U14ERR_NOERROR; | 899 | int iReturn = U14ERR_NOERROR; |
889 | unsigned int dwIdent; | 900 | unsigned int dwIdent; |
890 | 901 | ||
891 | mutex_lock(&pdx->io_mutex); | 902 | mutex_lock(&pdx->io_mutex); |
892 | dwIdent = pdx->StagedId; // area ident for last xfer | 903 | dwIdent = pdx->StagedId; // area ident for last xfer |
893 | if (dwIdent >= MAX_TRANSAREAS) | 904 | if (dwIdent >= MAX_TRANSAREAS) |
894 | iReturn = U14ERR_BADAREA; | 905 | iReturn = U14ERR_BADAREA; |
895 | else | 906 | else { |
896 | { | 907 | // Return the best information we have - we don't have physical addresses |
897 | // Return the best information we have - we don't have physical addresses | 908 | TGET_TX_BLOCK tx; |
898 | TGET_TX_BLOCK tx; | 909 | memset(&tx, 0, sizeof(tx)); // clean out local work structure |
899 | memset(&tx, 0, sizeof(tx)); // clean out local work structure | 910 | tx.size = pdx->rTransDef[dwIdent].dwLength; |
900 | tx.size = pdx->rTransDef[dwIdent].dwLength; | 911 | tx.linear = (long long)((long)pdx->rTransDef[dwIdent].lpvBuff); |
901 | tx.linear = (long long)((long)pdx->rTransDef[dwIdent].lpvBuff); | 912 | tx.avail = GET_TX_MAXENTRIES; // how many blocks we could return |
902 | tx.avail = GET_TX_MAXENTRIES; // how many blocks we could return | 913 | tx.used = 1; // number we actually return |
903 | tx.used = 1; // number we actually return | 914 | tx.entries[0].physical = |
904 | tx.entries[0].physical = (long long)(tx.linear+pdx->StagedOffset); | 915 | (long long)(tx.linear + pdx->StagedOffset); |
905 | tx.entries[0].size = tx.size; | 916 | tx.entries[0].size = tx.size; |
906 | copy_to_user(pTX, &tx, sizeof(tx)); | 917 | copy_to_user(pTX, &tx, sizeof(tx)); |
907 | } | 918 | } |
908 | mutex_unlock(&pdx->io_mutex); | 919 | mutex_unlock(&pdx->io_mutex); |
909 | return iReturn; | 920 | return iReturn; |
910 | } | 921 | } |
911 | 922 | ||
912 | /**************************************************************************** | 923 | /**************************************************************************** |
@@ -914,14 +925,14 @@ int GetTransfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pTX) | |||
914 | ** | 925 | ** |
915 | ** Empties the host i/o buffers | 926 | ** Empties the host i/o buffers |
916 | ****************************************************************************/ | 927 | ****************************************************************************/ |
917 | int KillIO1401(DEVICE_EXTENSION *pdx) | 928 | int KillIO1401(DEVICE_EXTENSION * pdx) |
918 | { | 929 | { |
919 | dev_dbg(&pdx->interface->dev, "%s", __func__); | 930 | dev_dbg(&pdx->interface->dev, "%s", __func__); |
920 | mutex_lock(&pdx->io_mutex); | 931 | mutex_lock(&pdx->io_mutex); |
921 | FlushOutBuff(pdx); | 932 | FlushOutBuff(pdx); |
922 | FlushInBuff(pdx); | 933 | FlushInBuff(pdx); |
923 | mutex_unlock(&pdx->io_mutex); | 934 | mutex_unlock(&pdx->io_mutex); |
924 | return U14ERR_NOERROR; | 935 | return U14ERR_NOERROR; |
925 | } | 936 | } |
926 | 937 | ||
927 | /**************************************************************************** | 938 | /**************************************************************************** |
@@ -929,11 +940,11 @@ int KillIO1401(DEVICE_EXTENSION *pdx) | |||
929 | ** Returns a 0 or a 1 for whether DMA is happening. No point holding a mutex | 940 | ** Returns a 0 or a 1 for whether DMA is happening. No point holding a mutex |
930 | ** for this as it only does one read. | 941 | ** for this as it only does one read. |
931 | *****************************************************************************/ | 942 | *****************************************************************************/ |
932 | int BlkTransState(DEVICE_EXTENSION *pdx) | 943 | int BlkTransState(DEVICE_EXTENSION * pdx) |
933 | { | 944 | { |
934 | int iReturn = pdx->dwDMAFlag != MODE_CHAR; | 945 | int iReturn = pdx->dwDMAFlag != MODE_CHAR; |
935 | dev_dbg(&pdx->interface->dev, "%s = %d", __func__, iReturn); | 946 | dev_dbg(&pdx->interface->dev, "%s = %d", __func__, iReturn); |
936 | return iReturn; | 947 | return iReturn; |
937 | } | 948 | } |
938 | 949 | ||
939 | /**************************************************************************** | 950 | /**************************************************************************** |
@@ -941,121 +952,121 @@ int BlkTransState(DEVICE_EXTENSION *pdx) | |||
941 | ** | 952 | ** |
942 | ** Puts the current state of the 1401 in the Irp return buffer. | 953 | ** Puts the current state of the 1401 in the Irp return buffer. |
943 | *****************************************************************************/ | 954 | *****************************************************************************/ |
944 | int StateOf1401(DEVICE_EXTENSION *pdx) | 955 | int StateOf1401(DEVICE_EXTENSION * pdx) |
945 | { | 956 | { |
946 | int iReturn; | 957 | int iReturn; |
947 | mutex_lock(&pdx->io_mutex); | 958 | mutex_lock(&pdx->io_mutex); |
948 | 959 | ||
949 | QuickCheck(pdx, false, false); // get state up to date, no reset | 960 | QuickCheck(pdx, false, false); // get state up to date, no reset |
950 | iReturn = pdx->sCurrentState; | 961 | iReturn = pdx->sCurrentState; |
951 | 962 | ||
952 | mutex_unlock(&pdx->io_mutex); | 963 | mutex_unlock(&pdx->io_mutex); |
953 | dev_dbg(&pdx->interface->dev, "%s = %d", __func__, iReturn); | 964 | dev_dbg(&pdx->interface->dev, "%s = %d", __func__, iReturn); |
954 | 965 | ||
955 | return iReturn; | 966 | return iReturn; |
956 | } | 967 | } |
968 | |||
957 | /**************************************************************************** | 969 | /**************************************************************************** |
958 | ** StartSelfTest | 970 | ** StartSelfTest |
959 | ** | 971 | ** |
960 | ** Initiates a self-test cycle. The assumption is that we have no interrupts | 972 | ** Initiates a self-test cycle. The assumption is that we have no interrupts |
961 | ** active, so we should make sure that this is the case. | 973 | ** active, so we should make sure that this is the case. |
962 | *****************************************************************************/ | 974 | *****************************************************************************/ |
963 | int StartSelfTest(DEVICE_EXTENSION *pdx) | 975 | int StartSelfTest(DEVICE_EXTENSION * pdx) |
964 | { | 976 | { |
965 | int nGot; | 977 | int nGot; |
966 | mutex_lock(&pdx->io_mutex); | 978 | mutex_lock(&pdx->io_mutex); |
967 | dev_dbg(&pdx->interface->dev, "%s", __func__); | 979 | dev_dbg(&pdx->interface->dev, "%s", __func__); |
968 | 980 | ||
969 | ced_draw_down(pdx); // wait for, then kill outstanding Urbs | 981 | ced_draw_down(pdx); // wait for, then kill outstanding Urbs |
970 | FlushInBuff(pdx); // Clear out input buffer & pipe | 982 | FlushInBuff(pdx); // Clear out input buffer & pipe |
971 | FlushOutBuff(pdx); // Clear output buffer & pipe | 983 | FlushOutBuff(pdx); // Clear output buffer & pipe |
972 | // ReadWrite_Cancel(pDeviceObject); /* so things stay tidy */ | 984 | // ReadWrite_Cancel(pDeviceObject); /* so things stay tidy */ |
973 | pdx->dwDMAFlag = MODE_CHAR; /* Clear DMA mode flags here */ | 985 | pdx->dwDMAFlag = MODE_CHAR; /* Clear DMA mode flags here */ |
974 | 986 | ||
975 | nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), | 987 | nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), DB_SELFTEST, (H_TO_D | VENDOR | DEVREQ), 0, 0, 0, 0, HZ); // allow 1 second timeout |
976 | DB_SELFTEST, (H_TO_D|VENDOR|DEVREQ), 0, 0, | 988 | pdx->ulSelfTestTime = jiffies + HZ * 30; // 30 seconds into the future |
977 | 0, 0, HZ); // allow 1 second timeout | ||
978 | pdx->ulSelfTestTime = jiffies + HZ*30; // 30 seconds into the future | ||
979 | 989 | ||
980 | mutex_unlock(&pdx->io_mutex); | 990 | mutex_unlock(&pdx->io_mutex); |
981 | if (nGot < 0) | 991 | if (nGot < 0) |
982 | dev_err(&pdx->interface->dev, "%s err=%d", __func__, nGot); | 992 | dev_err(&pdx->interface->dev, "%s err=%d", __func__, nGot); |
983 | return nGot < 0 ? U14ERR_FAIL : U14ERR_NOERROR; | 993 | return nGot < 0 ? U14ERR_FAIL : U14ERR_NOERROR; |
984 | } | 994 | } |
985 | 995 | ||
986 | |||
987 | /**************************************************************************** | 996 | /**************************************************************************** |
988 | ** CheckSelfTest | 997 | ** CheckSelfTest |
989 | ** | 998 | ** |
990 | ** Check progress of a self-test cycle | 999 | ** Check progress of a self-test cycle |
991 | ****************************************************************************/ | 1000 | ****************************************************************************/ |
992 | int CheckSelfTest(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST) | 1001 | int CheckSelfTest(DEVICE_EXTENSION * pdx, TGET_SELFTEST __user * pGST) |
993 | { | 1002 | { |
994 | unsigned int state, error; | 1003 | unsigned int state, error; |
995 | int iReturn; | 1004 | int iReturn; |
996 | TGET_SELFTEST gst; // local work space | 1005 | TGET_SELFTEST gst; // local work space |
997 | memset(&gst, 0, sizeof(gst)); // clear out the space (sets code 0) | 1006 | memset(&gst, 0, sizeof(gst)); // clear out the space (sets code 0) |
998 | 1007 | ||
999 | mutex_lock(&pdx->io_mutex); | 1008 | mutex_lock(&pdx->io_mutex); |
1000 | 1009 | ||
1001 | dev_dbg(&pdx->interface->dev, "%s", __func__); | 1010 | dev_dbg(&pdx->interface->dev, "%s", __func__); |
1002 | iReturn = Get1401State(pdx, &state, &error); | 1011 | iReturn = Get1401State(pdx, &state, &error); |
1003 | if (iReturn == U14ERR_NOERROR) // Only accept zero if it happens twice | 1012 | if (iReturn == U14ERR_NOERROR) // Only accept zero if it happens twice |
1004 | iReturn = Get1401State(pdx, &state, &error); | 1013 | iReturn = Get1401State(pdx, &state, &error); |
1005 | 1014 | ||
1006 | if (iReturn != U14ERR_NOERROR) // Self-test can cause comms errors | 1015 | if (iReturn != U14ERR_NOERROR) // Self-test can cause comms errors |
1007 | { // so we assume still testing | 1016 | { // so we assume still testing |
1008 | dev_err(&pdx->interface->dev, "%s Get1401State=%d, assuming still testing", __func__, iReturn); | 1017 | dev_err(&pdx->interface->dev, |
1009 | state = 0x80; // Force still-testing, no error | 1018 | "%s Get1401State=%d, assuming still testing", __func__, |
1010 | error = 0; | 1019 | iReturn); |
1011 | iReturn = U14ERR_NOERROR; | 1020 | state = 0x80; // Force still-testing, no error |
1012 | } | 1021 | error = 0; |
1013 | 1022 | iReturn = U14ERR_NOERROR; | |
1014 | if ((state == -1) && (error == -1)) // If Get1401State had problems | 1023 | } |
1015 | { | 1024 | |
1016 | dev_err(&pdx->interface->dev, "%s Get1401State failed, assuming still testing", __func__); | 1025 | if ((state == -1) && (error == -1)) // If Get1401State had problems |
1017 | state = 0x80; // Force still-testing, no error | 1026 | { |
1018 | error = 0; | 1027 | dev_err(&pdx->interface->dev, |
1019 | } | 1028 | "%s Get1401State failed, assuming still testing", |
1020 | 1029 | __func__); | |
1021 | if ((state & 0xFF) == 0x80) // If we are still in self-test | 1030 | state = 0x80; // Force still-testing, no error |
1022 | { | 1031 | error = 0; |
1023 | if (state & 0x00FF0000) // Have we got an error? | 1032 | } |
1024 | { | 1033 | |
1025 | gst.code = (state & 0x00FF0000) >> 16; // read the error code | 1034 | if ((state & 0xFF) == 0x80) // If we are still in self-test |
1026 | gst.x = error & 0x0000FFFF; // Error data X | 1035 | { |
1027 | gst.y = (error & 0xFFFF0000) >> 16; // and data Y | 1036 | if (state & 0x00FF0000) // Have we got an error? |
1028 | dev_dbg(&pdx->interface->dev,"Self-test error code %d", gst.code); | 1037 | { |
1029 | } | 1038 | gst.code = (state & 0x00FF0000) >> 16; // read the error code |
1030 | else // No error, check for timeout | 1039 | gst.x = error & 0x0000FFFF; // Error data X |
1031 | { | 1040 | gst.y = (error & 0xFFFF0000) >> 16; // and data Y |
1032 | unsigned long ulNow = jiffies; // get current time | 1041 | dev_dbg(&pdx->interface->dev, "Self-test error code %d", |
1033 | if (time_after(ulNow, pdx->ulSelfTestTime)) | 1042 | gst.code); |
1034 | { | 1043 | } else // No error, check for timeout |
1035 | gst.code = -2; // Flag the timeout | 1044 | { |
1036 | dev_dbg(&pdx->interface->dev, "Self-test timed-out"); | 1045 | unsigned long ulNow = jiffies; // get current time |
1037 | } | 1046 | if (time_after(ulNow, pdx->ulSelfTestTime)) { |
1038 | else | 1047 | gst.code = -2; // Flag the timeout |
1039 | dev_dbg(&pdx->interface->dev, "Self-test on-going"); | 1048 | dev_dbg(&pdx->interface->dev, |
1040 | } | 1049 | "Self-test timed-out"); |
1041 | } | 1050 | } else |
1042 | else | 1051 | dev_dbg(&pdx->interface->dev, |
1043 | { | 1052 | "Self-test on-going"); |
1044 | gst.code = -1; // Flag the test is done | 1053 | } |
1045 | dev_dbg(&pdx->interface->dev, "Self-test done"); | 1054 | } else { |
1046 | } | 1055 | gst.code = -1; // Flag the test is done |
1047 | 1056 | dev_dbg(&pdx->interface->dev, "Self-test done"); | |
1048 | if (gst.code < 0) // If we have a problem or finished | 1057 | } |
1049 | { // If using the 2890 we should reset properly | 1058 | |
1050 | if ((pdx->nPipes == 4) && (pdx->s1401Type <= TYPEPOWER)) | 1059 | if (gst.code < 0) // If we have a problem or finished |
1051 | Is1401(pdx); // Get 1401 reset and OK | 1060 | { // If using the 2890 we should reset properly |
1052 | else | 1061 | if ((pdx->nPipes == 4) && (pdx->s1401Type <= TYPEPOWER)) |
1053 | QuickCheck(pdx, true, true); // Otherwise check without reset unless problems | 1062 | Is1401(pdx); // Get 1401 reset and OK |
1054 | } | 1063 | else |
1055 | mutex_unlock(&pdx->io_mutex); | 1064 | QuickCheck(pdx, true, true); // Otherwise check without reset unless problems |
1056 | 1065 | } | |
1057 | copy_to_user(pGST, &gst, sizeof(gst)); // copy result to user space | 1066 | mutex_unlock(&pdx->io_mutex); |
1058 | return iReturn; | 1067 | |
1068 | copy_to_user(pGST, &gst, sizeof(gst)); // copy result to user space | ||
1069 | return iReturn; | ||
1059 | } | 1070 | } |
1060 | 1071 | ||
1061 | /**************************************************************************** | 1072 | /**************************************************************************** |
@@ -1063,28 +1074,32 @@ int CheckSelfTest(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST) | |||
1063 | ** | 1074 | ** |
1064 | ** Returns code for standard, plus, micro1401, power1401 or none | 1075 | ** Returns code for standard, plus, micro1401, power1401 or none |
1065 | ****************************************************************************/ | 1076 | ****************************************************************************/ |
1066 | int TypeOf1401(DEVICE_EXTENSION *pdx) | 1077 | int TypeOf1401(DEVICE_EXTENSION * pdx) |
1067 | { | 1078 | { |
1068 | int iReturn = TYPEUNKNOWN; | 1079 | int iReturn = TYPEUNKNOWN; |
1069 | mutex_lock(&pdx->io_mutex); | 1080 | mutex_lock(&pdx->io_mutex); |
1070 | dev_dbg(&pdx->interface->dev, "%s", __func__); | 1081 | dev_dbg(&pdx->interface->dev, "%s", __func__); |
1071 | 1082 | ||
1072 | switch (pdx->s1401Type) | 1083 | switch (pdx->s1401Type) { |
1073 | { | 1084 | case TYPE1401: |
1074 | case TYPE1401: iReturn = U14ERR_STD; break; // Handle these types directly | 1085 | iReturn = U14ERR_STD; |
1075 | case TYPEPLUS: iReturn = U14ERR_PLUS; break; | 1086 | break; // Handle these types directly |
1076 | case TYPEU1401:iReturn = U14ERR_U1401;break; | 1087 | case TYPEPLUS: |
1077 | default: | 1088 | iReturn = U14ERR_PLUS; |
1078 | if ((pdx->s1401Type >= TYPEPOWER) && | 1089 | break; |
1079 | (pdx->s1401Type <= 25)) | 1090 | case TYPEU1401: |
1080 | iReturn = pdx->s1401Type + 4; // We can calculate types | 1091 | iReturn = U14ERR_U1401; |
1081 | else // for up-coming 1401 designs | 1092 | break; |
1082 | iReturn = TYPEUNKNOWN; // Don't know or not there | 1093 | default: |
1083 | } | 1094 | if ((pdx->s1401Type >= TYPEPOWER) && (pdx->s1401Type <= 25)) |
1084 | dev_dbg(&pdx->interface->dev, "%s %d", __func__, iReturn); | 1095 | iReturn = pdx->s1401Type + 4; // We can calculate types |
1085 | mutex_unlock(&pdx->io_mutex); | 1096 | else // for up-coming 1401 designs |
1086 | 1097 | iReturn = TYPEUNKNOWN; // Don't know or not there | |
1087 | return iReturn; | 1098 | } |
1099 | dev_dbg(&pdx->interface->dev, "%s %d", __func__, iReturn); | ||
1100 | mutex_unlock(&pdx->io_mutex); | ||
1101 | |||
1102 | return iReturn; | ||
1088 | } | 1103 | } |
1089 | 1104 | ||
1090 | /**************************************************************************** | 1105 | /**************************************************************************** |
@@ -1092,17 +1107,17 @@ int TypeOf1401(DEVICE_EXTENSION *pdx) | |||
1092 | ** | 1107 | ** |
1093 | ** Returns flags on block transfer abilities | 1108 | ** Returns flags on block transfer abilities |
1094 | ****************************************************************************/ | 1109 | ****************************************************************************/ |
1095 | int TransferFlags(DEVICE_EXTENSION *pdx) | 1110 | int TransferFlags(DEVICE_EXTENSION * pdx) |
1096 | { | 1111 | { |
1097 | int iReturn = U14TF_MULTIA | U14TF_DIAG | // we always have multiple DMA area | 1112 | int iReturn = U14TF_MULTIA | U14TF_DIAG | // we always have multiple DMA area |
1098 | U14TF_NOTIFY | U14TF_CIRCTH; // diagnostics, notify and circular | 1113 | U14TF_NOTIFY | U14TF_CIRCTH; // diagnostics, notify and circular |
1099 | dev_dbg(&pdx->interface->dev, "%s", __func__); | 1114 | dev_dbg(&pdx->interface->dev, "%s", __func__); |
1100 | mutex_lock(&pdx->io_mutex); | 1115 | mutex_lock(&pdx->io_mutex); |
1101 | if (pdx->bIsUSB2) // Set flag for USB2 if appropriate | 1116 | if (pdx->bIsUSB2) // Set flag for USB2 if appropriate |
1102 | iReturn |= U14TF_USB2; | 1117 | iReturn |= U14TF_USB2; |
1103 | mutex_unlock(&pdx->io_mutex); | 1118 | mutex_unlock(&pdx->io_mutex); |
1104 | 1119 | ||
1105 | return iReturn; | 1120 | return iReturn; |
1106 | } | 1121 | } |
1107 | 1122 | ||
1108 | /*************************************************************************** | 1123 | /*************************************************************************** |
@@ -1110,18 +1125,17 @@ int TransferFlags(DEVICE_EXTENSION *pdx) | |||
1110 | ** Issues a debug\diagnostic command to the 1401 along with a 32-bit datum | 1125 | ** Issues a debug\diagnostic command to the 1401 along with a 32-bit datum |
1111 | ** This is a utility command used for dbg operations. | 1126 | ** This is a utility command used for dbg operations. |
1112 | */ | 1127 | */ |
1113 | static int DbgCmd1401(DEVICE_EXTENSION *pdx, unsigned char cmd, unsigned int data) | 1128 | static int DbgCmd1401(DEVICE_EXTENSION * pdx, unsigned char cmd, |
1129 | unsigned int data) | ||
1114 | { | 1130 | { |
1115 | int iReturn; | 1131 | int iReturn; |
1116 | dev_dbg(&pdx->interface->dev, "%s entry", __func__); | 1132 | dev_dbg(&pdx->interface->dev, "%s entry", __func__); |
1117 | iReturn = usb_control_msg(pdx->udev, usb_sndctrlpipe(pdx->udev, 0), | 1133 | iReturn = usb_control_msg(pdx->udev, usb_sndctrlpipe(pdx->udev, 0), cmd, (H_TO_D | VENDOR | DEVREQ), (unsigned short)data, (unsigned short)(data >> 16), 0, 0, HZ); // allow 1 second timeout |
1118 | cmd, (H_TO_D|VENDOR|DEVREQ), | 1134 | if (iReturn < 0) |
1119 | (unsigned short)data, (unsigned short)(data >> 16), | 1135 | dev_err(&pdx->interface->dev, "%s fail code=%d", __func__, |
1120 | 0, 0, HZ); // allow 1 second timeout | 1136 | iReturn); |
1121 | if (iReturn < 0) | 1137 | |
1122 | dev_err(&pdx->interface->dev, "%s fail code=%d", __func__, iReturn); | 1138 | return iReturn; |
1123 | |||
1124 | return iReturn; | ||
1125 | } | 1139 | } |
1126 | 1140 | ||
1127 | /**************************************************************************** | 1141 | /**************************************************************************** |
@@ -1129,146 +1143,141 @@ static int DbgCmd1401(DEVICE_EXTENSION *pdx, unsigned char cmd, unsigned int dat | |||
1129 | ** | 1143 | ** |
1130 | ** Execute the diagnostic peek operation. Uses address, width and repeats. | 1144 | ** Execute the diagnostic peek operation. Uses address, width and repeats. |
1131 | ****************************************************************************/ | 1145 | ****************************************************************************/ |
1132 | int DbgPeek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user* pDB) | 1146 | int DbgPeek(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB) |
1133 | { | 1147 | { |
1134 | int iReturn; | 1148 | int iReturn; |
1135 | TDBGBLOCK db; | 1149 | TDBGBLOCK db; |
1136 | copy_from_user(&db, pDB, sizeof(db)); // get the data | 1150 | copy_from_user(&db, pDB, sizeof(db)); // get the data |
1137 | 1151 | ||
1138 | mutex_lock(&pdx->io_mutex); | 1152 | mutex_lock(&pdx->io_mutex); |
1139 | dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr); | 1153 | dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr); |
1140 | 1154 | ||
1141 | iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr); | 1155 | iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr); |
1142 | if (iReturn == U14ERR_NOERROR) | 1156 | if (iReturn == U14ERR_NOERROR) |
1143 | iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); | 1157 | iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); |
1144 | if (iReturn == U14ERR_NOERROR) | 1158 | if (iReturn == U14ERR_NOERROR) |
1145 | iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); | 1159 | iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); |
1146 | if (iReturn == U14ERR_NOERROR) | 1160 | if (iReturn == U14ERR_NOERROR) |
1147 | iReturn = DbgCmd1401(pdx, DB_PEEK, 0); | 1161 | iReturn = DbgCmd1401(pdx, DB_PEEK, 0); |
1148 | mutex_unlock(&pdx->io_mutex); | 1162 | mutex_unlock(&pdx->io_mutex); |
1149 | 1163 | ||
1150 | return iReturn; | 1164 | return iReturn; |
1151 | } | 1165 | } |
1152 | 1166 | ||
1153 | |||
1154 | /**************************************************************************** | 1167 | /**************************************************************************** |
1155 | ** DbgPoke | 1168 | ** DbgPoke |
1156 | ** | 1169 | ** |
1157 | ** Execute the diagnostic poke operation. Parameters are in the CSBLOCK struct | 1170 | ** Execute the diagnostic poke operation. Parameters are in the CSBLOCK struct |
1158 | ** in order address, size, repeats and value to poke. | 1171 | ** in order address, size, repeats and value to poke. |
1159 | ****************************************************************************/ | 1172 | ****************************************************************************/ |
1160 | int DbgPoke(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) | 1173 | int DbgPoke(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB) |
1161 | { | 1174 | { |
1162 | int iReturn; | 1175 | int iReturn; |
1163 | TDBGBLOCK db; | 1176 | TDBGBLOCK db; |
1164 | copy_from_user(&db, pDB, sizeof(db)); // get the data | 1177 | copy_from_user(&db, pDB, sizeof(db)); // get the data |
1165 | 1178 | ||
1166 | mutex_lock(&pdx->io_mutex); | 1179 | mutex_lock(&pdx->io_mutex); |
1167 | dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr); | 1180 | dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr); |
1168 | 1181 | ||
1169 | iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr); | 1182 | iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr); |
1170 | if (iReturn == U14ERR_NOERROR) | 1183 | if (iReturn == U14ERR_NOERROR) |
1171 | iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); | 1184 | iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); |
1172 | if (iReturn == U14ERR_NOERROR) | 1185 | if (iReturn == U14ERR_NOERROR) |
1173 | iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); | 1186 | iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); |
1174 | if (iReturn == U14ERR_NOERROR) | 1187 | if (iReturn == U14ERR_NOERROR) |
1175 | iReturn = DbgCmd1401(pdx, DB_POKE, db.iData); | 1188 | iReturn = DbgCmd1401(pdx, DB_POKE, db.iData); |
1176 | mutex_unlock(&pdx->io_mutex); | 1189 | mutex_unlock(&pdx->io_mutex); |
1177 | 1190 | ||
1178 | return iReturn; | 1191 | return iReturn; |
1179 | } | 1192 | } |
1180 | 1193 | ||
1181 | |||
1182 | /**************************************************************************** | 1194 | /**************************************************************************** |
1183 | ** DbgRampData | 1195 | ** DbgRampData |
1184 | ** | 1196 | ** |
1185 | ** Execute the diagnostic ramp data operation. Parameters are in the CSBLOCK struct | 1197 | ** Execute the diagnostic ramp data operation. Parameters are in the CSBLOCK struct |
1186 | ** in order address, default, enable mask, size and repeats. | 1198 | ** in order address, default, enable mask, size and repeats. |
1187 | ****************************************************************************/ | 1199 | ****************************************************************************/ |
1188 | int DbgRampData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) | 1200 | int DbgRampData(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB) |
1189 | { | 1201 | { |
1190 | int iReturn; | 1202 | int iReturn; |
1191 | TDBGBLOCK db; | 1203 | TDBGBLOCK db; |
1192 | copy_from_user(&db, pDB, sizeof(db)); // get the data | 1204 | copy_from_user(&db, pDB, sizeof(db)); // get the data |
1193 | 1205 | ||
1194 | mutex_lock(&pdx->io_mutex); | 1206 | mutex_lock(&pdx->io_mutex); |
1195 | dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr); | 1207 | dev_dbg(&pdx->interface->dev, "%s @ %08x", __func__, db.iAddr); |
1196 | 1208 | ||
1197 | iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr); | 1209 | iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr); |
1198 | if (iReturn == U14ERR_NOERROR) | 1210 | if (iReturn == U14ERR_NOERROR) |
1199 | iReturn = DbgCmd1401(pdx, DB_SETDEF, db.iDefault); | 1211 | iReturn = DbgCmd1401(pdx, DB_SETDEF, db.iDefault); |
1200 | if (iReturn == U14ERR_NOERROR) | 1212 | if (iReturn == U14ERR_NOERROR) |
1201 | iReturn = DbgCmd1401(pdx, DB_SETMASK, db.iMask); | 1213 | iReturn = DbgCmd1401(pdx, DB_SETMASK, db.iMask); |
1202 | if (iReturn == U14ERR_NOERROR) | 1214 | if (iReturn == U14ERR_NOERROR) |
1203 | iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); | 1215 | iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); |
1204 | if (iReturn == U14ERR_NOERROR) | 1216 | if (iReturn == U14ERR_NOERROR) |
1205 | iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); | 1217 | iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); |
1206 | if (iReturn == U14ERR_NOERROR) | 1218 | if (iReturn == U14ERR_NOERROR) |
1207 | iReturn = DbgCmd1401(pdx, DB_RAMPD, 0); | 1219 | iReturn = DbgCmd1401(pdx, DB_RAMPD, 0); |
1208 | mutex_unlock(&pdx->io_mutex); | 1220 | mutex_unlock(&pdx->io_mutex); |
1209 | 1221 | ||
1210 | return iReturn; | 1222 | return iReturn; |
1211 | } | 1223 | } |
1212 | 1224 | ||
1213 | |||
1214 | /**************************************************************************** | 1225 | /**************************************************************************** |
1215 | ** DbgRampAddr | 1226 | ** DbgRampAddr |
1216 | ** | 1227 | ** |
1217 | ** Execute the diagnostic ramp address operation | 1228 | ** Execute the diagnostic ramp address operation |
1218 | ****************************************************************************/ | 1229 | ****************************************************************************/ |
1219 | int DbgRampAddr(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) | 1230 | int DbgRampAddr(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB) |
1220 | { | 1231 | { |
1221 | int iReturn; | 1232 | int iReturn; |
1222 | TDBGBLOCK db; | 1233 | TDBGBLOCK db; |
1223 | copy_from_user(&db, pDB, sizeof(db)); // get the data | 1234 | copy_from_user(&db, pDB, sizeof(db)); // get the data |
1224 | 1235 | ||
1225 | mutex_lock(&pdx->io_mutex); | 1236 | mutex_lock(&pdx->io_mutex); |
1226 | dev_dbg(&pdx->interface->dev, "%s", __func__); | 1237 | dev_dbg(&pdx->interface->dev, "%s", __func__); |
1227 | 1238 | ||
1228 | iReturn = DbgCmd1401(pdx, DB_SETDEF, db.iDefault); | 1239 | iReturn = DbgCmd1401(pdx, DB_SETDEF, db.iDefault); |
1229 | if (iReturn == U14ERR_NOERROR) | 1240 | if (iReturn == U14ERR_NOERROR) |
1230 | iReturn = DbgCmd1401(pdx, DB_SETMASK, db.iMask); | 1241 | iReturn = DbgCmd1401(pdx, DB_SETMASK, db.iMask); |
1231 | if (iReturn == U14ERR_NOERROR) | 1242 | if (iReturn == U14ERR_NOERROR) |
1232 | iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); | 1243 | iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth); |
1233 | if (iReturn == U14ERR_NOERROR) | 1244 | if (iReturn == U14ERR_NOERROR) |
1234 | iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); | 1245 | iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats); |
1235 | if (iReturn == U14ERR_NOERROR) | 1246 | if (iReturn == U14ERR_NOERROR) |
1236 | iReturn = DbgCmd1401(pdx, DB_RAMPA, 0); | 1247 | iReturn = DbgCmd1401(pdx, DB_RAMPA, 0); |
1237 | mutex_unlock(&pdx->io_mutex); | 1248 | mutex_unlock(&pdx->io_mutex); |
1238 | 1249 | ||
1239 | return iReturn; | 1250 | return iReturn; |
1240 | } | 1251 | } |
1241 | 1252 | ||
1242 | |||
1243 | /**************************************************************************** | 1253 | /**************************************************************************** |
1244 | ** DbgGetData | 1254 | ** DbgGetData |
1245 | ** | 1255 | ** |
1246 | ** Retrieve the data resulting from the last debug Peek operation | 1256 | ** Retrieve the data resulting from the last debug Peek operation |
1247 | ****************************************************************************/ | 1257 | ****************************************************************************/ |
1248 | int DbgGetData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) | 1258 | int DbgGetData(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB) |
1249 | { | 1259 | { |
1250 | int iReturn; | 1260 | int iReturn; |
1251 | TDBGBLOCK db; | 1261 | TDBGBLOCK db; |
1252 | memset(&db, 0, sizeof(db)); // fill returned block with 0s | 1262 | memset(&db, 0, sizeof(db)); // fill returned block with 0s |
1253 | 1263 | ||
1254 | mutex_lock(&pdx->io_mutex); | 1264 | mutex_lock(&pdx->io_mutex); |
1255 | dev_dbg(&pdx->interface->dev, "%s", __func__); | 1265 | dev_dbg(&pdx->interface->dev, "%s", __func__); |
1256 | 1266 | ||
1257 | // Read back the last peeked value from the 1401. | 1267 | // Read back the last peeked value from the 1401. |
1258 | iReturn = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), | 1268 | iReturn = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), |
1259 | DB_DATA, (D_TO_H|VENDOR|DEVREQ), 0,0, | 1269 | DB_DATA, (D_TO_H | VENDOR | DEVREQ), 0, 0, |
1260 | &db.iData, sizeof(db.iData), HZ); | 1270 | &db.iData, sizeof(db.iData), HZ); |
1261 | if (iReturn == sizeof(db.iData)) | 1271 | if (iReturn == sizeof(db.iData)) { |
1262 | { | 1272 | copy_to_user(pDB, &db, sizeof(db)); |
1263 | copy_to_user(pDB, &db, sizeof(db)); | 1273 | iReturn = U14ERR_NOERROR; |
1264 | iReturn = U14ERR_NOERROR; | 1274 | } else |
1265 | } | 1275 | dev_err(&pdx->interface->dev, "%s failed, code %d", __func__, |
1266 | else | 1276 | iReturn); |
1267 | dev_err(&pdx->interface->dev, "%s failed, code %d", __func__, iReturn); | 1277 | |
1268 | 1278 | mutex_unlock(&pdx->io_mutex); | |
1269 | mutex_unlock(&pdx->io_mutex); | 1279 | |
1270 | 1280 | return iReturn; | |
1271 | return iReturn; | ||
1272 | } | 1281 | } |
1273 | 1282 | ||
1274 | /**************************************************************************** | 1283 | /**************************************************************************** |
@@ -1277,20 +1286,19 @@ int DbgGetData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB) | |||
1277 | ** Stop any never-ending debug loop, we just call Get1401State for USB | 1286 | ** Stop any never-ending debug loop, we just call Get1401State for USB |
1278 | ** | 1287 | ** |
1279 | ****************************************************************************/ | 1288 | ****************************************************************************/ |
1280 | int DbgStopLoop(DEVICE_EXTENSION *pdx) | 1289 | int DbgStopLoop(DEVICE_EXTENSION * pdx) |
1281 | { | 1290 | { |
1282 | int iReturn; | 1291 | int iReturn; |
1283 | unsigned int uState, uErr; | 1292 | unsigned int uState, uErr; |
1284 | 1293 | ||
1285 | mutex_lock(&pdx->io_mutex); | 1294 | mutex_lock(&pdx->io_mutex); |
1286 | dev_dbg(&pdx->interface->dev, "%s", __func__); | 1295 | dev_dbg(&pdx->interface->dev, "%s", __func__); |
1287 | iReturn = Get1401State(pdx, &uState, &uErr); | 1296 | iReturn = Get1401State(pdx, &uState, &uErr); |
1288 | mutex_unlock(&pdx->io_mutex); | 1297 | mutex_unlock(&pdx->io_mutex); |
1289 | 1298 | ||
1290 | return iReturn; | 1299 | return iReturn; |
1291 | } | 1300 | } |
1292 | 1301 | ||
1293 | |||
1294 | /**************************************************************************** | 1302 | /**************************************************************************** |
1295 | ** SetCircular | 1303 | ** SetCircular |
1296 | ** | 1304 | ** |
@@ -1299,22 +1307,26 @@ int DbgStopLoop(DEVICE_EXTENSION *pdx) | |||
1299 | ** booked and a transfer to that area is in progress. Otherwise, we will | 1307 | ** booked and a transfer to that area is in progress. Otherwise, we will |
1300 | ** release the area and re-assign it. | 1308 | ** release the area and re-assign it. |
1301 | ****************************************************************************/ | 1309 | ****************************************************************************/ |
1302 | int SetCircular(DEVICE_EXTENSION *pdx, TRANSFERDESC __user *pTD) | 1310 | int SetCircular(DEVICE_EXTENSION * pdx, TRANSFERDESC __user * pTD) |
1303 | { | 1311 | { |
1304 | int iReturn; | 1312 | int iReturn; |
1305 | bool bToHost; | 1313 | bool bToHost; |
1306 | TRANSFERDESC td; | 1314 | TRANSFERDESC td; |
1307 | copy_from_user(&td, pTD, sizeof(td)); | 1315 | copy_from_user(&td, pTD, sizeof(td)); |
1308 | mutex_lock(&pdx->io_mutex); | 1316 | mutex_lock(&pdx->io_mutex); |
1309 | dev_dbg(&pdx->interface->dev,"%s area:%d, size:%08x", __func__, td.wAreaNum, td.dwLength); | 1317 | dev_dbg(&pdx->interface->dev, "%s area:%d, size:%08x", __func__, |
1310 | bToHost = td.eSize != 0; // this is used as the tohost flag | 1318 | td.wAreaNum, td.dwLength); |
1311 | 1319 | bToHost = td.eSize != 0; // this is used as the tohost flag | |
1312 | // The strange cast is done so that we don't get warnings in 32-bit linux about the size of the | 1320 | |
1313 | // pointer. The pointer is always passed as a 64-bit object so that we don't have problems using | 1321 | // The strange cast is done so that we don't get warnings in 32-bit linux about the size of the |
1314 | // a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system. | 1322 | // pointer. The pointer is always passed as a 64-bit object so that we don't have problems using |
1315 | iReturn = SetArea(pdx, td.wAreaNum, (char __user *)((unsigned long)td.lpvBuff), td.dwLength, true, bToHost); | 1323 | // a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system. |
1316 | mutex_unlock(&pdx->io_mutex); | 1324 | iReturn = |
1317 | return iReturn; | 1325 | SetArea(pdx, td.wAreaNum, |
1326 | (char __user *)((unsigned long)td.lpvBuff), td.dwLength, | ||
1327 | true, bToHost); | ||
1328 | mutex_unlock(&pdx->io_mutex); | ||
1329 | return iReturn; | ||
1318 | } | 1330 | } |
1319 | 1331 | ||
1320 | /**************************************************************************** | 1332 | /**************************************************************************** |
@@ -1322,140 +1334,145 @@ int SetCircular(DEVICE_EXTENSION *pdx, TRANSFERDESC __user *pTD) | |||
1322 | ** | 1334 | ** |
1323 | ** Return the next available block of circularly-transferred data. | 1335 | ** Return the next available block of circularly-transferred data. |
1324 | ****************************************************************************/ | 1336 | ****************************************************************************/ |
1325 | int GetCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user* pCB) | 1337 | int GetCircBlock(DEVICE_EXTENSION * pdx, TCIRCBLOCK __user * pCB) |
1326 | { | 1338 | { |
1327 | int iReturn = U14ERR_NOERROR; | 1339 | int iReturn = U14ERR_NOERROR; |
1328 | unsigned int nArea; | 1340 | unsigned int nArea; |
1329 | TCIRCBLOCK cb; | 1341 | TCIRCBLOCK cb; |
1330 | dev_dbg(&pdx->interface->dev, "%s", __func__); | 1342 | dev_dbg(&pdx->interface->dev, "%s", __func__); |
1331 | copy_from_user(&cb, pCB, sizeof(cb)); | 1343 | copy_from_user(&cb, pCB, sizeof(cb)); |
1332 | mutex_lock(&pdx->io_mutex); | 1344 | mutex_lock(&pdx->io_mutex); |
1333 | 1345 | ||
1334 | nArea = cb.nArea; // Retrieve parameters first | 1346 | nArea = cb.nArea; // Retrieve parameters first |
1335 | cb.dwOffset = 0; // set default result (nothing) | 1347 | cb.dwOffset = 0; // set default result (nothing) |
1336 | cb.dwSize = 0; | 1348 | cb.dwSize = 0; |
1337 | 1349 | ||
1338 | if (nArea < MAX_TRANSAREAS) // The area number must be OK | 1350 | if (nArea < MAX_TRANSAREAS) // The area number must be OK |
1339 | { | 1351 | { |
1340 | TRANSAREA* pArea = &pdx->rTransDef[nArea]; // Pointer to relevant info | 1352 | TRANSAREA *pArea = &pdx->rTransDef[nArea]; // Pointer to relevant info |
1341 | spin_lock_irq(&pdx->stagedLock); // Lock others out | 1353 | spin_lock_irq(&pdx->stagedLock); // Lock others out |
1342 | 1354 | ||
1343 | if ((pArea->bUsed) && (pArea->bCircular) && // Must be circular area | 1355 | if ((pArea->bUsed) && (pArea->bCircular) && // Must be circular area |
1344 | (pArea->bCircToHost)) // For now at least must be to host | 1356 | (pArea->bCircToHost)) // For now at least must be to host |
1345 | { | 1357 | { |
1346 | if (pArea->aBlocks[0].dwSize > 0) // Got anything? | 1358 | if (pArea->aBlocks[0].dwSize > 0) // Got anything? |
1347 | { | 1359 | { |
1348 | cb.dwOffset = pArea->aBlocks[0].dwOffset; | 1360 | cb.dwOffset = pArea->aBlocks[0].dwOffset; |
1349 | cb.dwSize = pArea->aBlocks[0].dwSize; | 1361 | cb.dwSize = pArea->aBlocks[0].dwSize; |
1350 | dev_dbg(&pdx->interface->dev, "%s return block 0: %d bytes at %d", __func__, cb.dwSize, cb.dwOffset); | 1362 | dev_dbg(&pdx->interface->dev, |
1351 | } | 1363 | "%s return block 0: %d bytes at %d", |
1352 | } | 1364 | __func__, cb.dwSize, cb.dwOffset); |
1353 | else | 1365 | } |
1354 | iReturn = U14ERR_NOTSET; | 1366 | } else |
1355 | 1367 | iReturn = U14ERR_NOTSET; | |
1356 | spin_unlock_irq(&pdx->stagedLock); | 1368 | |
1357 | } | 1369 | spin_unlock_irq(&pdx->stagedLock); |
1358 | else | 1370 | } else |
1359 | iReturn = U14ERR_BADAREA; | 1371 | iReturn = U14ERR_BADAREA; |
1360 | 1372 | ||
1361 | copy_to_user(pCB, &cb, sizeof(cb)); | 1373 | copy_to_user(pCB, &cb, sizeof(cb)); |
1362 | mutex_unlock(&pdx->io_mutex); | 1374 | mutex_unlock(&pdx->io_mutex); |
1363 | return iReturn; | 1375 | return iReturn; |
1364 | } | 1376 | } |
1365 | 1377 | ||
1366 | |||
1367 | /**************************************************************************** | 1378 | /**************************************************************************** |
1368 | ** FreeCircBlock | 1379 | ** FreeCircBlock |
1369 | ** | 1380 | ** |
1370 | ** Frees a block of circularly-transferred data and returns the next one. | 1381 | ** Frees a block of circularly-transferred data and returns the next one. |
1371 | ****************************************************************************/ | 1382 | ****************************************************************************/ |
1372 | int FreeCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user* pCB) | 1383 | int FreeCircBlock(DEVICE_EXTENSION * pdx, TCIRCBLOCK __user * pCB) |
1373 | { | 1384 | { |
1374 | int iReturn = U14ERR_NOERROR; | 1385 | int iReturn = U14ERR_NOERROR; |
1375 | unsigned int nArea, uStart, uSize; | 1386 | unsigned int nArea, uStart, uSize; |
1376 | TCIRCBLOCK cb; | 1387 | TCIRCBLOCK cb; |
1377 | dev_dbg(&pdx->interface->dev, "%s", __func__); | 1388 | dev_dbg(&pdx->interface->dev, "%s", __func__); |
1378 | copy_from_user(&cb, pCB, sizeof(cb)); | 1389 | copy_from_user(&cb, pCB, sizeof(cb)); |
1379 | mutex_lock(&pdx->io_mutex); | 1390 | mutex_lock(&pdx->io_mutex); |
1380 | 1391 | ||
1381 | nArea = cb.nArea; // Retrieve parameters first | 1392 | nArea = cb.nArea; // Retrieve parameters first |
1382 | uStart = cb.dwOffset; | 1393 | uStart = cb.dwOffset; |
1383 | uSize = cb.dwSize; | 1394 | uSize = cb.dwSize; |
1384 | cb.dwOffset = 0; // then set default result (nothing) | 1395 | cb.dwOffset = 0; // then set default result (nothing) |
1385 | cb.dwSize = 0; | 1396 | cb.dwSize = 0; |
1386 | 1397 | ||
1387 | if (nArea < MAX_TRANSAREAS) // The area number must be OK | 1398 | if (nArea < MAX_TRANSAREAS) // The area number must be OK |
1388 | { | 1399 | { |
1389 | TRANSAREA* pArea = &pdx->rTransDef[nArea]; // Pointer to relevant info | 1400 | TRANSAREA *pArea = &pdx->rTransDef[nArea]; // Pointer to relevant info |
1390 | spin_lock_irq(&pdx->stagedLock); // Lock others out | 1401 | spin_lock_irq(&pdx->stagedLock); // Lock others out |
1391 | 1402 | ||
1392 | if ((pArea->bUsed) && (pArea->bCircular) && // Must be circular area | 1403 | if ((pArea->bUsed) && (pArea->bCircular) && // Must be circular area |
1393 | (pArea->bCircToHost)) // For now at least must be to host | 1404 | (pArea->bCircToHost)) // For now at least must be to host |
1394 | { | 1405 | { |
1395 | bool bWaiting = false; | 1406 | bool bWaiting = false; |
1396 | 1407 | ||
1397 | if ((pArea->aBlocks[0].dwSize >= uSize) && // Got anything? | 1408 | if ((pArea->aBlocks[0].dwSize >= uSize) && // Got anything? |
1398 | (pArea->aBlocks[0].dwOffset == uStart)) // Must be legal data | 1409 | (pArea->aBlocks[0].dwOffset == uStart)) // Must be legal data |
1399 | { | 1410 | { |
1400 | pArea->aBlocks[0].dwSize -= uSize; | 1411 | pArea->aBlocks[0].dwSize -= uSize; |
1401 | pArea->aBlocks[0].dwOffset += uSize; | 1412 | pArea->aBlocks[0].dwOffset += uSize; |
1402 | if (pArea->aBlocks[0].dwSize == 0) // Have we emptied this block? | 1413 | if (pArea->aBlocks[0].dwSize == 0) // Have we emptied this block? |
1403 | { | 1414 | { |
1404 | if (pArea->aBlocks[1].dwSize) // Is there a second block? | 1415 | if (pArea->aBlocks[1].dwSize) // Is there a second block? |
1405 | { | 1416 | { |
1406 | pArea->aBlocks[0] = pArea->aBlocks[1]; // Copy down block 2 data | 1417 | pArea->aBlocks[0] = pArea->aBlocks[1]; // Copy down block 2 data |
1407 | pArea->aBlocks[1].dwSize = 0; // and mark the second block as unused | 1418 | pArea->aBlocks[1].dwSize = 0; // and mark the second block as unused |
1408 | pArea->aBlocks[1].dwOffset = 0; | 1419 | pArea->aBlocks[1].dwOffset = 0; |
1409 | } | 1420 | } else |
1410 | else | 1421 | pArea->aBlocks[0].dwOffset = 0; |
1411 | pArea->aBlocks[0].dwOffset = 0; | 1422 | } |
1412 | } | 1423 | |
1413 | 1424 | dev_dbg(&pdx->interface->dev, | |
1414 | dev_dbg(&pdx->interface->dev, "%s free %d bytes at %d, return %d bytes at %d, wait=%d", | 1425 | "%s free %d bytes at %d, return %d bytes at %d, wait=%d", |
1415 | __func__, uSize, uStart, pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset, pdx->bXFerWaiting); | 1426 | __func__, uSize, uStart, |
1416 | 1427 | pArea->aBlocks[0].dwSize, | |
1417 | // Return the next available block of memory as well | 1428 | pArea->aBlocks[0].dwOffset, |
1418 | if (pArea->aBlocks[0].dwSize > 0) // Got anything? | 1429 | pdx->bXFerWaiting); |
1419 | { | 1430 | |
1420 | cb.dwOffset = pArea->aBlocks[0].dwOffset; | 1431 | // Return the next available block of memory as well |
1421 | cb.dwSize = pArea->aBlocks[0].dwSize; | 1432 | if (pArea->aBlocks[0].dwSize > 0) // Got anything? |
1422 | } | 1433 | { |
1423 | 1434 | cb.dwOffset = | |
1424 | bWaiting = pdx->bXFerWaiting; | 1435 | pArea->aBlocks[0].dwOffset; |
1425 | if (bWaiting && pdx->bStagedUrbPending) | 1436 | cb.dwSize = pArea->aBlocks[0].dwSize; |
1426 | { | 1437 | } |
1427 | dev_err(&pdx->interface->dev, "%s ERROR: waiting xfer and staged Urb pending!", __func__); | 1438 | |
1428 | bWaiting = false; | 1439 | bWaiting = pdx->bXFerWaiting; |
1429 | } | 1440 | if (bWaiting && pdx->bStagedUrbPending) { |
1430 | } | 1441 | dev_err(&pdx->interface->dev, |
1431 | else | 1442 | "%s ERROR: waiting xfer and staged Urb pending!", |
1432 | { | 1443 | __func__); |
1433 | dev_err(&pdx->interface->dev, "%s ERROR: freeing %d bytes at %d, block 0 is %d bytes at %d", | 1444 | bWaiting = false; |
1434 | __func__, uSize, uStart, pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset); | 1445 | } |
1435 | iReturn = U14ERR_NOMEMORY; | 1446 | } else { |
1436 | } | 1447 | dev_err(&pdx->interface->dev, |
1437 | 1448 | "%s ERROR: freeing %d bytes at %d, block 0 is %d bytes at %d", | |
1438 | // If we have one, kick off pending transfer | 1449 | __func__, uSize, uStart, |
1439 | if (bWaiting) // Got a block xfer waiting? | 1450 | pArea->aBlocks[0].dwSize, |
1440 | { | 1451 | pArea->aBlocks[0].dwOffset); |
1441 | int RWMStat = ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard, | 1452 | iReturn = U14ERR_NOMEMORY; |
1442 | pdx->rDMAInfo.wIdent, pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize); | 1453 | } |
1443 | if (RWMStat != U14ERR_NOERROR) | 1454 | |
1444 | dev_err(&pdx->interface->dev, "%s rw setup failed %d", __func__, RWMStat); | 1455 | // If we have one, kick off pending transfer |
1445 | } | 1456 | if (bWaiting) // Got a block xfer waiting? |
1446 | } | 1457 | { |
1447 | else | 1458 | int RWMStat = |
1448 | iReturn = U14ERR_NOTSET; | 1459 | ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard, |
1449 | 1460 | pdx->rDMAInfo.wIdent, | |
1450 | spin_unlock_irq(&pdx->stagedLock); | 1461 | pdx->rDMAInfo.dwOffset, |
1451 | } | 1462 | pdx->rDMAInfo.dwSize); |
1452 | else | 1463 | if (RWMStat != U14ERR_NOERROR) |
1453 | iReturn = U14ERR_BADAREA; | 1464 | dev_err(&pdx->interface->dev, |
1454 | 1465 | "%s rw setup failed %d", | |
1455 | copy_to_user(pCB, &cb, sizeof(cb)); | 1466 | __func__, RWMStat); |
1456 | mutex_unlock(&pdx->io_mutex); | 1467 | } |
1457 | return iReturn; | 1468 | } else |
1469 | iReturn = U14ERR_NOTSET; | ||
1470 | |||
1471 | spin_unlock_irq(&pdx->stagedLock); | ||
1472 | } else | ||
1473 | iReturn = U14ERR_BADAREA; | ||
1474 | |||
1475 | copy_to_user(pCB, &cb, sizeof(cb)); | ||
1476 | mutex_unlock(&pdx->io_mutex); | ||
1477 | return iReturn; | ||
1458 | } | 1478 | } |
1459 | |||
1460 | |||
1461 | |||
diff --git a/drivers/staging/ced1401/ced_ioctl.h b/drivers/staging/ced1401/ced_ioctl.h index 075ecadc69d1..0895c9414b4f 100644 --- a/drivers/staging/ced1401/ced_ioctl.h +++ b/drivers/staging/ced1401/ced_ioctl.h | |||
@@ -1,232 +1,345 @@ | |||
1 | /* ced_ioctl.h | 1 | /* |
2 | IOCTL calls for the CED1401 driver | 2 | * IOCTL calls for the CED1401 driver |
3 | Copyright (C) 2010 Cambridge Electronic Design Ltd | 3 | * Copyright (C) 2010 Cambridge Electronic Design Ltd |
4 | Author Greg P Smith (greg@ced.co.uk) | 4 | * Author Greg P Smith (greg@ced.co.uk) |
5 | 5 | * | |
6 | This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
7 | modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
8 | as published by the Free Software Foundation; either version 2 | 8 | * as published by the Free Software Foundation; either version 2 |
9 | of the License, or (at your option) any later version. | 9 | * of the License, or (at your option) any later version. |
10 | 10 | * | |
11 | This program is distributed in the hope that it will be useful, | 11 | * This program is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | 15 | */ | |
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | #ifndef __CED_IOCTL_H__ | 16 | #ifndef __CED_IOCTL_H__ |
21 | #define __CED_IOCTL_H__ | 17 | #define __CED_IOCTL_H__ |
22 | #include <asm/ioctl.h> | ||
23 | 18 | ||
24 | /// dma modes, only MODE_CHAR and MODE_LINEAR are used in this driver | 19 | #include <linux/ioctl.h> |
25 | #define MODE_CHAR 0 | 20 | |
26 | #define MODE_LINEAR 1 | 21 | /* dma modes, only MODE_CHAR and MODE_LINEAR are used in this driver */ |
22 | #define MODE_CHAR 0 | ||
23 | #define MODE_LINEAR 1 | ||
27 | 24 | ||
28 | /**************************************************************************** | 25 | /**************************************************************************** |
29 | ** TypeDefs | 26 | ** TypeDefs |
30 | *****************************************************************************/ | 27 | *****************************************************************************/ |
31 | 28 | ||
32 | typedef unsigned short TBLOCKENTRY; // index the blk transfer table 0-7 | 29 | typedef unsigned short TBLOCKENTRY; /* index the blk transfer table 0-7 */ |
33 | 30 | ||
34 | typedef struct TransferDesc | 31 | typedef struct TransferDesc { |
35 | { | 32 | long long lpvBuff; /* address of transfer area (for 64 or 32 bit) */ |
36 | long long lpvBuff; // address of transfer area (for 64 or 32 bit) | 33 | unsigned int dwLength; /* length of the area */ |
37 | unsigned int dwLength; // length of the area | 34 | TBLOCKENTRY wAreaNum; /* number of transfer area to set up */ |
38 | TBLOCKENTRY wAreaNum; // number of transfer area to set up | 35 | short eSize; /* element size - is tohost flag for circular */ |
39 | short eSize; // element size - is tohost flag for circular | ||
40 | } TRANSFERDESC; | 36 | } TRANSFERDESC; |
41 | 37 | ||
42 | typedef TRANSFERDESC* LPTRANSFERDESC; | 38 | typedef TRANSFERDESC * LPTRANSFERDESC; |
43 | 39 | ||
44 | typedef struct TransferEvent | 40 | typedef struct TransferEvent { |
45 | { | 41 | unsigned int dwStart; /* offset into the area */ |
46 | unsigned int dwStart; // offset into the area | 42 | unsigned int dwLength; /* length of the region */ |
47 | unsigned int dwLength; // length of the region | 43 | unsigned short wAreaNum; /* the area number */ |
48 | unsigned short wAreaNum; // the area number | 44 | unsigned short wFlags; /* bit 0 set for toHost */ |
49 | unsigned short wFlags; // bit 0 set for toHost | 45 | int iSetEvent; /* could be dummy in LINUX */ |
50 | int iSetEvent; // could be dummy in LINUX | ||
51 | } TRANSFEREVENT; | 46 | } TRANSFEREVENT; |
52 | 47 | ||
53 | #define MAX_TRANSFER_SIZE 0x4000 /* Maximum data bytes per IRP */ | 48 | #define MAX_TRANSFER_SIZE 0x4000 /* Maximum data bytes per IRP */ |
54 | #define MAX_AREA_LENGTH 0x100000 /* Maximum size of transfer area */ | 49 | #define MAX_AREA_LENGTH 0x100000 /* Maximum size of transfer area */ |
55 | #define MAX_TRANSAREAS 8 /* definitions for dma set up */ | 50 | #define MAX_TRANSAREAS 8 /* definitions for dma set up */ |
56 | 51 | ||
57 | typedef struct TGetSelfTest | 52 | typedef struct TGetSelfTest { |
58 | { | 53 | int code; /* self-test error code */ |
59 | int code; // self-test error code | 54 | int x, y; /* additional information */ |
60 | int x,y; // additional information | ||
61 | } TGET_SELFTEST; | 55 | } TGET_SELFTEST; |
62 | 56 | ||
63 | /// Debug block used for several commands. Not all fields are used for all commands. | 57 | /* Debug block used for several commands. Not all fields are used for all commands. */ |
64 | typedef struct TDbgBlock | 58 | typedef struct TDbgBlock { |
65 | { | 59 | int iAddr; /* the address in the 1401 */ |
66 | int iAddr; // the address in the 1401 | 60 | int iRepeats; /* number of repeats */ |
67 | int iRepeats; // number of repeats | 61 | int iWidth; /* width in bytes 1, 2, 4 */ |
68 | int iWidth; // width in bytes 1, 2, 4 | 62 | int iDefault; /* default value */ |
69 | int iDefault; // default value | 63 | int iMask; /* mask to apply */ |
70 | int iMask; // mask to apply | 64 | int iData; /* data for poke, result for peek */ |
71 | int iData; // data for poke, result for peek | ||
72 | } TDBGBLOCK; | 65 | } TDBGBLOCK; |
73 | 66 | ||
74 | /// Used to collect information about a circular block from the device driver | 67 | /* Used to collect information about a circular block from the device driver */ |
75 | typedef struct TCircBlock | 68 | typedef struct TCircBlock { |
76 | { | 69 | unsigned int nArea; /* the area to collect information from */ |
77 | unsigned int nArea; // the area to collect information from | 70 | unsigned int dwOffset; /* offset into the area to the available block */ |
78 | unsigned int dwOffset; // offset into the area to the available block | 71 | unsigned int dwSize; /* size of the area */ |
79 | unsigned int dwSize; // size of the area | ||
80 | } TCIRCBLOCK; | 72 | } TCIRCBLOCK; |
81 | 73 | ||
82 | /// Used to clollect the 1401 status | 74 | /* Used to clollect the 1401 status */ |
83 | typedef struct TCSBlock | 75 | typedef struct TCSBlock { |
84 | { | 76 | unsigned int uiState; |
85 | unsigned int uiState; | 77 | unsigned int uiError; |
86 | unsigned int uiError; | ||
87 | } TCSBLOCK; | 78 | } TCSBLOCK; |
88 | 79 | ||
89 | // As seen by the user, an ioctl call looks like: | 80 | /* |
90 | // int ioctl(int fd, unsigned long cmd, char* argp); | 81 | * As seen by the user, an ioctl call looks like: int ioctl(int fd, unsigned |
91 | // We will then have all sorts of variants on this that can be used | 82 | * long cmd, char* argp); We will then have all sorts of variants on this that |
92 | // to pass stuff to our driver. We will generate macros for each type | 83 | * can be used to pass stuff to our driver. We will generate macros for each |
93 | // of call so as to provide some sort of type safety in the calling: | 84 | * type of call so as to provide some sort of type safety in the calling: |
85 | */ | ||
94 | #define CED_MAGIC_IOC 0xce | 86 | #define CED_MAGIC_IOC 0xce |
95 | 87 | ||
96 | // NBNB: READ and WRITE are from the point of view of the device, not user. | 88 | /* NBNB: READ and WRITE are from the point of view of the device, not user. */ |
97 | typedef struct ced_ioc_string | 89 | typedef struct ced_ioc_string { |
98 | { | 90 | int nChars; |
99 | int nChars; | 91 | char buffer[256]; |
100 | char buffer[256]; | ||
101 | } CED_IOC_STRING; | 92 | } CED_IOC_STRING; |
102 | 93 | ||
103 | #define IOCTL_CED_SENDSTRING(n) _IOC(_IOC_WRITE, CED_MAGIC_IOC, 2, n) | 94 | #define IOCTL_CED_SENDSTRING(n) _IOC(_IOC_WRITE, CED_MAGIC_IOC, 2, n) |
104 | 95 | ||
105 | #define IOCTL_CED_RESET1401 _IO(CED_MAGIC_IOC, 3) | 96 | #define IOCTL_CED_RESET1401 _IO(CED_MAGIC_IOC, 3) |
106 | #define IOCTL_CED_GETCHAR _IO(CED_MAGIC_IOC, 4) | 97 | #define IOCTL_CED_GETCHAR _IO(CED_MAGIC_IOC, 4) |
107 | #define IOCTL_CED_SENDCHAR _IO(CED_MAGIC_IOC, 5) | 98 | #define IOCTL_CED_SENDCHAR _IO(CED_MAGIC_IOC, 5) |
108 | #define IOCTL_CED_STAT1401 _IO(CED_MAGIC_IOC, 6) | 99 | #define IOCTL_CED_STAT1401 _IO(CED_MAGIC_IOC, 6) |
109 | #define IOCTL_CED_LINECOUNT _IO(CED_MAGIC_IOC, 7) | 100 | #define IOCTL_CED_LINECOUNT _IO(CED_MAGIC_IOC, 7) |
110 | #define IOCTL_CED_GETSTRING(nMax) _IOC(_IOC_READ, CED_MAGIC_IOC, 8, nMax) | 101 | #define IOCTL_CED_GETSTRING(nMax) _IOC(_IOC_READ, CED_MAGIC_IOC, 8, nMax) |
111 | 102 | ||
112 | #define IOCTL_CED_SETTRANSFER _IOW(CED_MAGIC_IOC, 11, TRANSFERDESC) | 103 | #define IOCTL_CED_SETTRANSFER _IOW(CED_MAGIC_IOC, 11, TRANSFERDESC) |
113 | #define IOCTL_CED_UNSETTRANSFER _IO(CED_MAGIC_IOC, 12) | 104 | #define IOCTL_CED_UNSETTRANSFER _IO(CED_MAGIC_IOC, 12) |
114 | #define IOCTL_CED_SETEVENT _IOW(CED_MAGIC_IOC,13, TRANSFEREVENT) | 105 | #define IOCTL_CED_SETEVENT _IOW(CED_MAGIC_IOC, 13, TRANSFEREVENT) |
115 | #define IOCTL_CED_GETOUTBUFSPACE _IO(CED_MAGIC_IOC, 14) | 106 | #define IOCTL_CED_GETOUTBUFSPACE _IO(CED_MAGIC_IOC, 14) |
116 | #define IOCTL_CED_GETBASEADDRESS _IO(CED_MAGIC_IOC, 15) | 107 | #define IOCTL_CED_GETBASEADDRESS _IO(CED_MAGIC_IOC, 15) |
117 | #define IOCTL_CED_GETDRIVERREVISION _IO(CED_MAGIC_IOC, 16) | 108 | #define IOCTL_CED_GETDRIVERREVISION _IO(CED_MAGIC_IOC, 16) |
118 | 109 | ||
119 | #define IOCTL_CED_GETTRANSFER _IOR(CED_MAGIC_IOC,17, TGET_TX_BLOCK) | 110 | #define IOCTL_CED_GETTRANSFER _IOR(CED_MAGIC_IOC, 17, TGET_TX_BLOCK) |
120 | #define IOCTL_CED_KILLIO1401 _IO(CED_MAGIC_IOC,18) | 111 | #define IOCTL_CED_KILLIO1401 _IO(CED_MAGIC_IOC, 18) |
121 | #define IOCTL_CED_BLKTRANSSTATE _IO(CED_MAGIC_IOC,19) | 112 | #define IOCTL_CED_BLKTRANSSTATE _IO(CED_MAGIC_IOC, 19) |
122 | 113 | ||
123 | #define IOCTL_CED_STATEOF1401 _IO(CED_MAGIC_IOC,23) | 114 | #define IOCTL_CED_STATEOF1401 _IO(CED_MAGIC_IOC, 23) |
124 | #define IOCTL_CED_GRAB1401 _IO(CED_MAGIC_IOC,25) | 115 | #define IOCTL_CED_GRAB1401 _IO(CED_MAGIC_IOC, 25) |
125 | #define IOCTL_CED_FREE1401 _IO(CED_MAGIC_IOC,26) | 116 | #define IOCTL_CED_FREE1401 _IO(CED_MAGIC_IOC, 26) |
126 | #define IOCTL_CED_STARTSELFTEST _IO(CED_MAGIC_IOC,31) | 117 | #define IOCTL_CED_STARTSELFTEST _IO(CED_MAGIC_IOC, 31) |
127 | #define IOCTL_CED_CHECKSELFTEST _IOR(CED_MAGIC_IOC,32, TGET_SELFTEST) | 118 | #define IOCTL_CED_CHECKSELFTEST _IOR(CED_MAGIC_IOC, 32, TGET_SELFTEST) |
128 | #define IOCTL_CED_TYPEOF1401 _IO(CED_MAGIC_IOC,33) | 119 | #define IOCTL_CED_TYPEOF1401 _IO(CED_MAGIC_IOC, 33) |
129 | #define IOCTL_CED_TRANSFERFLAGS _IO(CED_MAGIC_IOC,34) | 120 | #define IOCTL_CED_TRANSFERFLAGS _IO(CED_MAGIC_IOC, 34) |
130 | 121 | ||
131 | #define IOCTL_CED_DBGPEEK _IOW(CED_MAGIC_IOC,35, TDBGBLOCK) | 122 | #define IOCTL_CED_DBGPEEK _IOW(CED_MAGIC_IOC, 35, TDBGBLOCK) |
132 | #define IOCTL_CED_DBGPOKE _IOW(CED_MAGIC_IOC,36, TDBGBLOCK) | 123 | #define IOCTL_CED_DBGPOKE _IOW(CED_MAGIC_IOC, 36, TDBGBLOCK) |
133 | #define IOCTL_CED_DBGRAMPDATA _IOW(CED_MAGIC_IOC,37, TDBGBLOCK) | 124 | #define IOCTL_CED_DBGRAMPDATA _IOW(CED_MAGIC_IOC, 37, TDBGBLOCK) |
134 | #define IOCTL_CED_DBGRAMPADDR _IOW(CED_MAGIC_IOC,38, TDBGBLOCK) | 125 | #define IOCTL_CED_DBGRAMPADDR _IOW(CED_MAGIC_IOC, 38, TDBGBLOCK) |
135 | #define IOCTL_CED_DBGGETDATA _IOR(CED_MAGIC_IOC,39, TDBGBLOCK) | 126 | #define IOCTL_CED_DBGGETDATA _IOR(CED_MAGIC_IOC, 39, TDBGBLOCK) |
136 | #define IOCTL_CED_DBGSTOPLOOP _IO(CED_MAGIC_IOC,40) | 127 | #define IOCTL_CED_DBGSTOPLOOP _IO(CED_MAGIC_IOC, 40) |
137 | #define IOCTL_CED_FULLRESET _IO(CED_MAGIC_IOC,41) | 128 | #define IOCTL_CED_FULLRESET _IO(CED_MAGIC_IOC, 41) |
138 | #define IOCTL_CED_SETCIRCULAR _IOW(CED_MAGIC_IOC,42, TRANSFERDESC) | 129 | #define IOCTL_CED_SETCIRCULAR _IOW(CED_MAGIC_IOC, 42, TRANSFERDESC) |
139 | #define IOCTL_CED_GETCIRCBLOCK _IOWR(CED_MAGIC_IOC,43, TCIRCBLOCK) | 130 | #define IOCTL_CED_GETCIRCBLOCK _IOWR(CED_MAGIC_IOC, 43, TCIRCBLOCK) |
140 | #define IOCTL_CED_FREECIRCBLOCK _IOWR(CED_MAGIC_IOC,44, TCIRCBLOCK) | 131 | #define IOCTL_CED_FREECIRCBLOCK _IOWR(CED_MAGIC_IOC, 44, TCIRCBLOCK) |
141 | #define IOCTL_CED_WAITEVENT _IO(CED_MAGIC_IOC, 45) | 132 | #define IOCTL_CED_WAITEVENT _IO(CED_MAGIC_IOC, 45) |
142 | #define IOCTL_CED_TESTEVENT _IO(CED_MAGIC_IOC, 46) | 133 | #define IOCTL_CED_TESTEVENT _IO(CED_MAGIC_IOC, 46) |
143 | 134 | ||
144 | #ifndef __KERNEL__ | 135 | #ifndef __KERNEL__ |
145 | // If nothing said about return value, it is a U14ERR_... error code (U14ERR_NOERROR for none) | 136 | /* |
146 | inline int CED_SendString(int fh, const char* szText, int n){return ioctl(fh, IOCTL_CED_SENDSTRING(n), szText);} | 137 | * If nothing said about return value, it is a U14ERR_... error code |
138 | * (U14ERR_NOERROR for none) | ||
139 | */ | ||
140 | inline int CED_SendString(int fh, const char *szText, int n) | ||
141 | { | ||
142 | return ioctl(fh, IOCTL_CED_SENDSTRING(n), szText); | ||
143 | } | ||
147 | 144 | ||
148 | inline int CED_Reset1401(int fh){return ioctl(fh, IOCTL_CED_RESET1401);} | 145 | inline int CED_Reset1401(int fh) |
146 | { | ||
147 | return ioctl(fh, IOCTL_CED_RESET1401); | ||
148 | } | ||
149 | 149 | ||
150 | inline int CED_GetChar(int fh){return ioctl(fh, IOCTL_CED_GETCHAR);} | 150 | /* Return the singe character or a -ve error code. */ |
151 | // Return the singe character or a -ve error code. | 151 | inline int CED_GetChar(int fh) |
152 | { | ||
153 | return ioctl(fh, IOCTL_CED_GETCHAR); | ||
154 | } | ||
152 | 155 | ||
153 | inline int CED_Stat1401(int fh){return ioctl(fh, IOCTL_CED_STAT1401);} | 156 | /* Return character count in input buffer */ |
154 | // Return character count in input buffer | 157 | inline int CED_Stat1401(int fh) |
158 | { | ||
159 | return ioctl(fh, IOCTL_CED_STAT1401); | ||
160 | } | ||
155 | 161 | ||
156 | inline int CED_SendChar(int fh, char c){return ioctl(fh, IOCTL_CED_SENDCHAR, c);} | 162 | inline int CED_SendChar(int fh, char c) |
163 | { | ||
164 | return ioctl(fh, IOCTL_CED_SENDCHAR, c); | ||
165 | } | ||
157 | 166 | ||
158 | inline int CED_LineCount(int fh){return ioctl(fh, IOCTL_CED_LINECOUNT);} | 167 | inline int CED_LineCount(int fh) |
168 | { | ||
169 | return ioctl(fh, IOCTL_CED_LINECOUNT); | ||
170 | } | ||
171 | |||
172 | /* | ||
173 | * return the count of characters returned. If the string was terminated by CR | ||
174 | * or 0, then the 0 is part of the count. Otherwise, we will add a zero if | ||
175 | * there is room, but it is not included in the count. The return value is 0 | ||
176 | * if there was nothing to read. | ||
177 | */ | ||
178 | inline int CED_GetString(int fh, char *szText, int nMax) | ||
179 | { | ||
180 | return ioctl(fh, IOCTL_CED_GETSTRING(nMax), szText); | ||
181 | } | ||
159 | 182 | ||
160 | inline int CED_GetString(int fh, char* szText, int nMax){return ioctl(fh, IOCTL_CED_GETSTRING(nMax), szText);} | 183 | /* returns space in the output buffer. */ |
161 | // return the count of characters returned. If the string was terminated by CR or 0, then the 0 is part | 184 | inline int CED_GetOutBufSpace(int fh) |
162 | // of the count. Otherwise, we will add a zero if there is room, but it is not included in the count. | 185 | { |
163 | // The return value is 0 if there was nothing to read. | 186 | return ioctl(fh, IOCTL_CED_GETOUTBUFSPACE); |
187 | } | ||
164 | 188 | ||
165 | inline int CED_GetOutBufSpace(int fh){return ioctl(fh, IOCTL_CED_GETOUTBUFSPACE);} | 189 | /* This always returns -1 as not implemented. */ |
166 | // returns space in the output buffer. | 190 | inline int CED_GetBaseAddress(int fh) |
191 | { | ||
192 | return ioctl(fh, IOCTL_CED_GETBASEADDRESS); | ||
193 | } | ||
167 | 194 | ||
168 | inline int CED_GetBaseAddress(int fh){return ioctl(fh, IOCTL_CED_GETBASEADDRESS);} | 195 | /* returns the major revision <<16 | minor revision. */ |
169 | // This always returns -1 as not implemented. | 196 | inline int CED_GetDriverRevision(int fh) |
197 | { | ||
198 | return ioctl(fh, IOCTL_CED_GETDRIVERREVISION); | ||
199 | } | ||
170 | 200 | ||
171 | inline int CED_GetDriverRevision(int fh){return ioctl(fh, IOCTL_CED_GETDRIVERREVISION);} | 201 | inline int CED_SetTransfer(int fh, TRANSFERDESC *pTD) |
172 | // returns the major revision <<16 | minor revision. | 202 | { |
203 | return ioctl(fh, IOCTL_CED_SETTRANSFER, pTD); | ||
204 | } | ||
173 | 205 | ||
174 | inline int CED_SetTransfer(int fh, TRANSFERDESC* pTD){return ioctl(fh, IOCTL_CED_SETTRANSFER, pTD);} | 206 | inline int CED_UnsetTransfer(int fh, int nArea) |
207 | { | ||
208 | return ioctl(fh, IOCTL_CED_UNSETTRANSFER, nArea); | ||
209 | } | ||
175 | 210 | ||
176 | inline int CED_UnsetTransfer(int fh, int nArea){return ioctl(fh, IOCTL_CED_UNSETTRANSFER, nArea);} | 211 | inline int CED_SetEvent(int fh, TRANSFEREVENT *pTE) |
212 | { | ||
213 | return ioctl(fh, IOCTL_CED_SETEVENT, pTE); | ||
214 | } | ||
177 | 215 | ||
178 | inline int CED_SetEvent(int fh, TRANSFEREVENT* pTE){return ioctl(fh, IOCTL_CED_SETEVENT, pTE);} | 216 | inline int CED_GetTransfer(int fh, TGET_TX_BLOCK *pTX) |
217 | { | ||
218 | return ioctl(fh, IOCTL_CED_GETTRANSFER, pTX); | ||
219 | } | ||
179 | 220 | ||
180 | inline int CED_GetTransfer(int fh, TGET_TX_BLOCK* pTX){return ioctl(fh, IOCTL_CED_GETTRANSFER, pTX);} | 221 | inline int CED_KillIO1401(int fh) |
222 | { | ||
223 | return ioctl(fh, IOCTL_CED_KILLIO1401); | ||
224 | } | ||
181 | 225 | ||
182 | inline int CED_KillIO1401(int fh){return ioctl(fh, IOCTL_CED_KILLIO1401);} | 226 | /* returns 0 if no active DMA, 1 if active */ |
227 | inline int CED_BlkTransState(int fh) | ||
228 | { | ||
229 | return ioctl(fh, IOCTL_CED_BLKTRANSSTATE); | ||
230 | } | ||
183 | 231 | ||
184 | inline int CED_BlkTransState(int fh){return ioctl(fh, IOCTL_CED_BLKTRANSSTATE);} | 232 | inline int CED_StateOf1401(int fh) |
185 | // returns 0 if no active DMA, 1 if active | 233 | { |
234 | return ioctl(fh, IOCTL_CED_STATEOF1401); | ||
235 | } | ||
186 | 236 | ||
187 | inline int CED_StateOf1401(int fh){return ioctl(fh, IOCTL_CED_STATEOF1401);} | 237 | inline int CED_Grab1401(int fh) |
238 | { | ||
239 | return ioctl(fh, IOCTL_CED_GRAB1401); | ||
240 | } | ||
188 | 241 | ||
189 | inline int CED_Grab1401(int fh){return ioctl(fh, IOCTL_CED_GRAB1401);} | 242 | inline int CED_Free1401(int fh) |
190 | inline int CED_Free1401(int fh){return ioctl(fh, IOCTL_CED_FREE1401);} | 243 | { |
244 | return ioctl(fh, IOCTL_CED_FREE1401); | ||
245 | } | ||
191 | 246 | ||
192 | inline int CED_StartSelfTest(int fh){return ioctl(fh, IOCTL_CED_STARTSELFTEST);} | 247 | inline int CED_StartSelfTest(int fh) |
193 | inline int CED_CheckSelfTest(int fh, TGET_SELFTEST* pGST){return ioctl(fh, IOCTL_CED_CHECKSELFTEST, pGST);} | 248 | { |
249 | return ioctl(fh, IOCTL_CED_STARTSELFTEST); | ||
250 | } | ||
251 | |||
252 | inline int CED_CheckSelfTest(int fh, TGET_SELFTEST *pGST) | ||
253 | { | ||
254 | return ioctl(fh, IOCTL_CED_CHECKSELFTEST, pGST); | ||
255 | } | ||
256 | |||
257 | inline int CED_TypeOf1401(int fh) | ||
258 | { | ||
259 | return ioctl(fh, IOCTL_CED_TYPEOF1401); | ||
260 | } | ||
261 | |||
262 | inline int CED_TransferFlags(int fh) | ||
263 | { | ||
264 | return ioctl(fh, IOCTL_CED_TRANSFERFLAGS); | ||
265 | } | ||
266 | |||
267 | inline int CED_DbgPeek(int fh, TDBGBLOCK *pDB) | ||
268 | { | ||
269 | return ioctl(fh, IOCTL_CED_DBGPEEK, pDB); | ||
270 | } | ||
271 | |||
272 | inline int CED_DbgPoke(int fh, TDBGBLOCK *pDB) | ||
273 | { | ||
274 | return ioctl(fh, IOCTL_CED_DBGPOKE, pDB); | ||
275 | } | ||
276 | |||
277 | inline int CED_DbgRampData(int fh, TDBGBLOCK *pDB) | ||
278 | { | ||
279 | return ioctl(fh, IOCTL_CED_DBGRAMPDATA, pDB); | ||
280 | } | ||
194 | 281 | ||
195 | inline int CED_TypeOf1401(int fh){return ioctl(fh, IOCTL_CED_TYPEOF1401);} | 282 | inline int CED_DbgRampAddr(int fh, TDBGBLOCK *pDB) |
196 | inline int CED_TransferFlags(int fh){return ioctl(fh, IOCTL_CED_TRANSFERFLAGS);} | 283 | { |
284 | return ioctl(fh, IOCTL_CED_DBGRAMPADDR, pDB); | ||
285 | } | ||
197 | 286 | ||
198 | inline int CED_DbgPeek(int fh, TDBGBLOCK* pDB){return ioctl(fh, IOCTL_CED_DBGPEEK, pDB);} | 287 | inline int CED_DbgGetData(int fh, TDBGBLOCK *pDB) |
199 | inline int CED_DbgPoke(int fh, TDBGBLOCK* pDB){return ioctl(fh, IOCTL_CED_DBGPOKE, pDB);} | 288 | { |
200 | inline int CED_DbgRampData(int fh, TDBGBLOCK* pDB){return ioctl(fh, IOCTL_CED_DBGRAMPDATA, pDB);} | 289 | return ioctl(fh, IOCTL_CED_DBGGETDATA, pDB); |
201 | inline int CED_DbgRampAddr(int fh, TDBGBLOCK* pDB){return ioctl(fh, IOCTL_CED_DBGRAMPADDR, pDB);} | 290 | } |
202 | inline int CED_DbgGetData(int fh, TDBGBLOCK* pDB){return ioctl(fh, IOCTL_CED_DBGGETDATA, pDB);} | ||
203 | inline int CED_DbgStopLoop(int fh){return ioctl(fh, IOCTL_CED_DBGSTOPLOOP);} | ||
204 | 291 | ||
205 | inline int CED_FullReset(int fh){return ioctl(fh, IOCTL_CED_FULLRESET);} | 292 | inline int CED_DbgStopLoop(int fh) |
293 | { | ||
294 | return ioctl(fh, IOCTL_CED_DBGSTOPLOOP); | ||
295 | } | ||
206 | 296 | ||
207 | inline int CED_SetCircular(int fh, TRANSFERDESC* pTD){return ioctl(fh, IOCTL_CED_SETCIRCULAR, pTD);} | 297 | inline int CED_FullReset(int fh) |
208 | inline int CED_GetCircBlock(int fh, TCIRCBLOCK* pCB){return ioctl(fh, IOCTL_CED_GETCIRCBLOCK, pCB);} | 298 | { |
209 | inline int CED_FreeCircBlock(int fh, TCIRCBLOCK* pCB){return ioctl(fh, IOCTL_CED_FREECIRCBLOCK, pCB);} | 299 | return ioctl(fh, IOCTL_CED_FULLRESET); |
300 | } | ||
210 | 301 | ||
211 | inline int CED_WaitEvent(int fh, int nArea, int msTimeOut){return ioctl(fh, IOCTL_CED_WAITEVENT, (nArea & 0xff)|(msTimeOut << 8));} | 302 | inline int CED_SetCircular(int fh, TRANSFERDESC *pTD) |
212 | inline int CED_TestEvent(int fh, int nArea){return ioctl(fh, IOCTL_CED_TESTEVENT, nArea);} | 303 | { |
304 | return ioctl(fh, IOCTL_CED_SETCIRCULAR, pTD); | ||
305 | } | ||
306 | |||
307 | inline int CED_GetCircBlock(int fh, TCIRCBLOCK *pCB) | ||
308 | { | ||
309 | return ioctl(fh, IOCTL_CED_GETCIRCBLOCK, pCB); | ||
310 | } | ||
311 | |||
312 | inline int CED_FreeCircBlock(int fh, TCIRCBLOCK *pCB) | ||
313 | { | ||
314 | return ioctl(fh, IOCTL_CED_FREECIRCBLOCK, pCB); | ||
315 | } | ||
316 | |||
317 | inline int CED_WaitEvent(int fh, int nArea, int msTimeOut) | ||
318 | { | ||
319 | return ioctl(fh, IOCTL_CED_WAITEVENT, (nArea & 0xff)|(msTimeOut << 8)); | ||
320 | } | ||
321 | |||
322 | inline int CED_TestEvent(int fh, int nArea) | ||
323 | { | ||
324 | return ioctl(fh, IOCTL_CED_TESTEVENT, nArea); | ||
325 | } | ||
213 | #endif | 326 | #endif |
214 | 327 | ||
215 | #ifdef NOTWANTEDYET | 328 | #ifdef NOTWANTEDYET |
216 | #define IOCTL_CED_REGCALLBACK _IO(CED_MAGIC_IOC,9) // Not used | 329 | #define IOCTL_CED_REGCALLBACK _IO(CED_MAGIC_IOC, 9) /* Not used */ |
217 | #define IOCTL_CED_GETMONITORBUF _IO(CED_MAGIC_IOC,10) // Not used | 330 | #define IOCTL_CED_GETMONITORBUF _IO(CED_MAGIC_IOC, 10) /* Not used */ |
218 | 331 | ||
219 | #define IOCTL_CED_BYTECOUNT _IO(CED_MAGIC_IOC,20) // Not used | 332 | #define IOCTL_CED_BYTECOUNT _IO(CED_MAGIC_IOC, 20) /* Not used */ |
220 | #define IOCTL_CED_ZEROBLOCKCOUNT _IO(CED_MAGIC_IOC,21) // Not used | 333 | #define IOCTL_CED_ZEROBLOCKCOUNT _IO(CED_MAGIC_IOC, 21) /* Not used */ |
221 | #define IOCTL_CED_STOPCIRCULAR _IO(CED_MAGIC_IOC,22) // Not used | 334 | #define IOCTL_CED_STOPCIRCULAR _IO(CED_MAGIC_IOC, 22) /* Not used */ |
222 | 335 | ||
223 | #define IOCTL_CED_REGISTERS1401 _IO(CED_MAGIC_IOC,24) // Not used | 336 | #define IOCTL_CED_REGISTERS1401 _IO(CED_MAGIC_IOC, 24) /* Not used */ |
224 | #define IOCTL_CED_STEP1401 _IO(CED_MAGIC_IOC,27) // Not used | 337 | #define IOCTL_CED_STEP1401 _IO(CED_MAGIC_IOC, 27) /* Not used */ |
225 | #define IOCTL_CED_SET1401REGISTERS _IO(CED_MAGIC_IOC,28) // Not used | 338 | #define IOCTL_CED_SET1401REGISTERS _IO(CED_MAGIC_IOC, 28) /* Not used */ |
226 | #define IOCTL_CED_STEPTILL1401 _IO(CED_MAGIC_IOC,29) // Not used | 339 | #define IOCTL_CED_STEPTILL1401 _IO(CED_MAGIC_IOC, 29) /* Not used */ |
227 | #define IOCTL_CED_SETORIN _IO(CED_MAGIC_IOC,30) // Not used | 340 | #define IOCTL_CED_SETORIN _IO(CED_MAGIC_IOC, 30) /* Not used */ |
228 | 341 | ||
229 | #endif | 342 | #endif |
230 | 343 | ||
231 | // __CED_IOCTL_H__ | 344 | /* __CED_IOCTL_H__ */ |
232 | #endif | 345 | #endif |
diff --git a/drivers/staging/ced1401/usb1401.c b/drivers/staging/ced1401/usb1401.c index bf08baaab2f4..69b7f20c9d51 100644 --- a/drivers/staging/ced1401/usb1401.c +++ b/drivers/staging/ced1401/usb1401.c | |||
@@ -23,7 +23,6 @@ | |||
23 | along with this program; if not, write to the Free Software | 23 | along with this program; if not, write to the Free Software |
24 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 24 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
25 | 25 | ||
26 | |||
27 | Endpoints | 26 | Endpoints |
28 | ********* | 27 | ********* |
29 | There are 4 endpoints plus the control endpoint in the standard interface | 28 | There are 4 endpoints plus the control endpoint in the standard interface |
@@ -92,14 +91,13 @@ synchronous non-Urb based transfers. | |||
92 | #include <linux/highmem.h> | 91 | #include <linux/highmem.h> |
93 | #include <linux/version.h> | 92 | #include <linux/version.h> |
94 | #if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) ) | 93 | #if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) ) |
95 | #include <linux/init.h> | 94 | #include <linux/init.h> |
96 | #include <linux/slab.h> | 95 | #include <linux/slab.h> |
97 | #include <linux/module.h> | 96 | #include <linux/module.h> |
98 | #include <linux/kref.h> | 97 | #include <linux/kref.h> |
99 | #include <linux/uaccess.h> | 98 | #include <linux/uaccess.h> |
100 | #endif | 99 | #endif |
101 | 100 | ||
102 | |||
103 | #include "usb1401.h" | 101 | #include "usb1401.h" |
104 | 102 | ||
105 | /* Define these values to match your devices */ | 103 | /* Define these values to match your devices */ |
@@ -107,13 +105,12 @@ synchronous non-Urb based transfers. | |||
107 | #define USB_CED_PRODUCT_ID 0xa0f0 | 105 | #define USB_CED_PRODUCT_ID 0xa0f0 |
108 | 106 | ||
109 | /* table of devices that work with this driver */ | 107 | /* table of devices that work with this driver */ |
110 | static const struct usb_device_id ced_table[] = | 108 | static const struct usb_device_id ced_table[] = { |
111 | { | 109 | {USB_DEVICE(USB_CED_VENDOR_ID, USB_CED_PRODUCT_ID)}, |
112 | { USB_DEVICE(USB_CED_VENDOR_ID, USB_CED_PRODUCT_ID) }, | 110 | {} /* Terminating entry */ |
113 | { } /* Terminating entry */ | ||
114 | }; | 111 | }; |
115 | MODULE_DEVICE_TABLE(usb, ced_table); | ||
116 | 112 | ||
113 | MODULE_DEVICE_TABLE(usb, ced_table); | ||
117 | 114 | ||
118 | /* Get a minor range for your devices from the usb maintainer */ | 115 | /* Get a minor range for your devices from the usb maintainer */ |
119 | #define USB_CED_MINOR_BASE 192 | 116 | #define USB_CED_MINOR_BASE 192 |
@@ -134,151 +131,152 @@ The cause for these errors is that the driver makes use of the functions usb_buf | |||
134 | This is needed on Debian 2.6.32-5-amd64 | 131 | This is needed on Debian 2.6.32-5-amd64 |
135 | */ | 132 | */ |
136 | #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ) | 133 | #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ) |
137 | #define usb_alloc_coherent usb_buffer_alloc | 134 | #define usb_alloc_coherent usb_buffer_alloc |
138 | #define usb_free_coherent usb_buffer_free | 135 | #define usb_free_coherent usb_buffer_free |
139 | #define noop_llseek NULL | 136 | #define noop_llseek NULL |
140 | #endif | 137 | #endif |
141 | 138 | ||
142 | static struct usb_driver ced_driver; | 139 | static struct usb_driver ced_driver; |
143 | 140 | ||
144 | static void ced_delete(struct kref *kref) | 141 | static void ced_delete(struct kref *kref) |
145 | { | 142 | { |
146 | DEVICE_EXTENSION *pdx = to_DEVICE_EXTENSION(kref); | 143 | DEVICE_EXTENSION *pdx = to_DEVICE_EXTENSION(kref); |
147 | 144 | ||
148 | // Free up the output buffer, then free the output urb. Note that the interface member | 145 | // Free up the output buffer, then free the output urb. Note that the interface member |
149 | // of pdx will probably be NULL, so cannot be used to get to dev. | 146 | // of pdx will probably be NULL, so cannot be used to get to dev. |
150 | usb_free_coherent(pdx->udev, OUTBUF_SZ, pdx->pCoherCharOut, pdx->pUrbCharOut->transfer_dma); | 147 | usb_free_coherent(pdx->udev, OUTBUF_SZ, pdx->pCoherCharOut, |
151 | usb_free_urb(pdx->pUrbCharOut); | 148 | pdx->pUrbCharOut->transfer_dma); |
152 | 149 | usb_free_urb(pdx->pUrbCharOut); | |
153 | // Do the same for chan input | 150 | |
154 | usb_free_coherent(pdx->udev, INBUF_SZ, pdx->pCoherCharIn, pdx->pUrbCharIn->transfer_dma); | 151 | // Do the same for chan input |
155 | usb_free_urb(pdx->pUrbCharIn); | 152 | usb_free_coherent(pdx->udev, INBUF_SZ, pdx->pCoherCharIn, |
156 | 153 | pdx->pUrbCharIn->transfer_dma); | |
157 | // Do the same for the block transfers | 154 | usb_free_urb(pdx->pUrbCharIn); |
158 | usb_free_coherent(pdx->udev, STAGED_SZ, pdx->pCoherStagedIO, pdx->pStagedUrb->transfer_dma); | 155 | |
159 | usb_free_urb(pdx->pStagedUrb); | 156 | // Do the same for the block transfers |
160 | 157 | usb_free_coherent(pdx->udev, STAGED_SZ, pdx->pCoherStagedIO, | |
161 | usb_put_dev(pdx->udev); | 158 | pdx->pStagedUrb->transfer_dma); |
162 | kfree(pdx); | 159 | usb_free_urb(pdx->pStagedUrb); |
160 | |||
161 | usb_put_dev(pdx->udev); | ||
162 | kfree(pdx); | ||
163 | } | 163 | } |
164 | 164 | ||
165 | // This is the driver end of the open() call from user space. | 165 | // This is the driver end of the open() call from user space. |
166 | static int ced_open(struct inode *inode, struct file *file) | 166 | static int ced_open(struct inode *inode, struct file *file) |
167 | { | 167 | { |
168 | DEVICE_EXTENSION *pdx; | 168 | DEVICE_EXTENSION *pdx; |
169 | int retval = 0; | 169 | int retval = 0; |
170 | int subminor = iminor(inode); | 170 | int subminor = iminor(inode); |
171 | struct usb_interface* interface = usb_find_interface(&ced_driver, subminor); | 171 | struct usb_interface *interface = |
172 | if (!interface) | 172 | usb_find_interface(&ced_driver, subminor); |
173 | { | 173 | if (!interface) { |
174 | pr_err("%s - error, can't find device for minor %d", __func__, subminor); | 174 | pr_err("%s - error, can't find device for minor %d", __func__, |
175 | retval = -ENODEV; | 175 | subminor); |
176 | goto exit; | 176 | retval = -ENODEV; |
177 | } | 177 | goto exit; |
178 | 178 | } | |
179 | pdx = usb_get_intfdata(interface); | 179 | |
180 | if (!pdx) | 180 | pdx = usb_get_intfdata(interface); |
181 | { | 181 | if (!pdx) { |
182 | retval = -ENODEV; | 182 | retval = -ENODEV; |
183 | goto exit; | 183 | goto exit; |
184 | } | 184 | } |
185 | 185 | ||
186 | dev_dbg(&interface->dev, "%s got pdx", __func__); | 186 | dev_dbg(&interface->dev, "%s got pdx", __func__); |
187 | 187 | ||
188 | /* increment our usage count for the device */ | 188 | /* increment our usage count for the device */ |
189 | kref_get(&pdx->kref); | 189 | kref_get(&pdx->kref); |
190 | 190 | ||
191 | /* lock the device to allow correctly handling errors | 191 | /* lock the device to allow correctly handling errors |
192 | * in resumption */ | 192 | * in resumption */ |
193 | mutex_lock(&pdx->io_mutex); | 193 | mutex_lock(&pdx->io_mutex); |
194 | 194 | ||
195 | if (!pdx->open_count++) | 195 | if (!pdx->open_count++) { |
196 | { | 196 | retval = usb_autopm_get_interface(interface); |
197 | retval = usb_autopm_get_interface(interface); | 197 | if (retval) { |
198 | if (retval) | 198 | pdx->open_count--; |
199 | { | 199 | mutex_unlock(&pdx->io_mutex); |
200 | pdx->open_count--; | 200 | kref_put(&pdx->kref, ced_delete); |
201 | mutex_unlock(&pdx->io_mutex); | 201 | goto exit; |
202 | kref_put(&pdx->kref, ced_delete); | 202 | } |
203 | goto exit; | 203 | } else { //uncomment this block if you want exclusive open |
204 | } | 204 | dev_err(&interface->dev, "%s fail: already open", __func__); |
205 | } | ||
206 | else | ||
207 | { //uncomment this block if you want exclusive open | ||
208 | dev_err(&interface->dev, "%s fail: already open", __func__); | ||
209 | retval = -EBUSY; | 205 | retval = -EBUSY; |
210 | pdx->open_count--; | 206 | pdx->open_count--; |
211 | mutex_unlock(&pdx->io_mutex); | 207 | mutex_unlock(&pdx->io_mutex); |
212 | kref_put(&pdx->kref, ced_delete); | 208 | kref_put(&pdx->kref, ced_delete); |
213 | goto exit; | 209 | goto exit; |
214 | } | 210 | } |
215 | /* prevent the device from being autosuspended */ | 211 | /* prevent the device from being autosuspended */ |
216 | 212 | ||
217 | /* save our object in the file's private structure */ | 213 | /* save our object in the file's private structure */ |
218 | file->private_data = pdx; | 214 | file->private_data = pdx; |
219 | mutex_unlock(&pdx->io_mutex); | 215 | mutex_unlock(&pdx->io_mutex); |
220 | 216 | ||
221 | exit: | 217 | exit: |
222 | return retval; | 218 | return retval; |
223 | } | 219 | } |
224 | 220 | ||
225 | static int ced_release(struct inode *inode, struct file *file) | 221 | static int ced_release(struct inode *inode, struct file *file) |
226 | { | 222 | { |
227 | DEVICE_EXTENSION *pdx = file->private_data; | 223 | DEVICE_EXTENSION *pdx = file->private_data; |
228 | if (pdx == NULL) | 224 | if (pdx == NULL) |
229 | return -ENODEV; | 225 | return -ENODEV; |
230 | 226 | ||
231 | dev_dbg(&pdx->interface->dev,"%s called", __func__); | 227 | dev_dbg(&pdx->interface->dev, "%s called", __func__); |
232 | mutex_lock(&pdx->io_mutex); | 228 | mutex_lock(&pdx->io_mutex); |
233 | if (!--pdx->open_count && pdx->interface) // Allow autosuspend | 229 | if (!--pdx->open_count && pdx->interface) // Allow autosuspend |
234 | usb_autopm_put_interface(pdx->interface); | 230 | usb_autopm_put_interface(pdx->interface); |
235 | mutex_unlock(&pdx->io_mutex); | 231 | mutex_unlock(&pdx->io_mutex); |
236 | 232 | ||
237 | kref_put(&pdx->kref, ced_delete); // decrement the count on our device | 233 | kref_put(&pdx->kref, ced_delete); // decrement the count on our device |
238 | return 0; | 234 | return 0; |
239 | } | 235 | } |
240 | 236 | ||
241 | static int ced_flush(struct file *file, fl_owner_t id) | 237 | static int ced_flush(struct file *file, fl_owner_t id) |
242 | { | 238 | { |
243 | int res; | 239 | int res; |
244 | DEVICE_EXTENSION *pdx = file->private_data; | 240 | DEVICE_EXTENSION *pdx = file->private_data; |
245 | if (pdx == NULL) | 241 | if (pdx == NULL) |
246 | return -ENODEV; | 242 | return -ENODEV; |
247 | 243 | ||
248 | dev_dbg(&pdx->interface->dev,"%s char in pend=%d", __func__, pdx->bReadCharsPending); | 244 | dev_dbg(&pdx->interface->dev, "%s char in pend=%d", __func__, |
245 | pdx->bReadCharsPending); | ||
249 | 246 | ||
250 | /* wait for io to stop */ | 247 | /* wait for io to stop */ |
251 | mutex_lock(&pdx->io_mutex); | 248 | mutex_lock(&pdx->io_mutex); |
252 | dev_dbg(&pdx->interface->dev,"%s got io_mutex", __func__); | 249 | dev_dbg(&pdx->interface->dev, "%s got io_mutex", __func__); |
253 | ced_draw_down(pdx); | 250 | ced_draw_down(pdx); |
254 | 251 | ||
255 | /* read out errors, leave subsequent opens a clean slate */ | 252 | /* read out errors, leave subsequent opens a clean slate */ |
256 | spin_lock_irq(&pdx->err_lock); | 253 | spin_lock_irq(&pdx->err_lock); |
257 | res = pdx->errors ? (pdx->errors == -EPIPE ? -EPIPE : -EIO) : 0; | 254 | res = pdx->errors ? (pdx->errors == -EPIPE ? -EPIPE : -EIO) : 0; |
258 | pdx->errors = 0; | 255 | pdx->errors = 0; |
259 | spin_unlock_irq(&pdx->err_lock); | 256 | spin_unlock_irq(&pdx->err_lock); |
260 | 257 | ||
261 | mutex_unlock(&pdx->io_mutex); | 258 | mutex_unlock(&pdx->io_mutex); |
262 | dev_dbg(&pdx->interface->dev,"%s exit reached", __func__); | 259 | dev_dbg(&pdx->interface->dev, "%s exit reached", __func__); |
263 | 260 | ||
264 | return res; | 261 | return res; |
265 | } | 262 | } |
266 | 263 | ||
267 | |||
268 | static ssize_t ced_read(struct file *file, char *buffer, size_t count, | 264 | static ssize_t ced_read(struct file *file, char *buffer, size_t count, |
269 | loff_t *ppos) | 265 | loff_t * ppos) |
270 | { | 266 | { |
271 | DEVICE_EXTENSION *pdx = file->private_data; | 267 | DEVICE_EXTENSION *pdx = file->private_data; |
272 | dev_err(&pdx->interface->dev, "%s called: use ioctl for cedusb", __func__); | 268 | dev_err(&pdx->interface->dev, "%s called: use ioctl for cedusb", |
273 | return 0; // as we do not do reads this way | 269 | __func__); |
270 | return 0; // as we do not do reads this way | ||
274 | } | 271 | } |
275 | 272 | ||
276 | static ssize_t ced_write(struct file *file, const char *user_buffer, | 273 | static ssize_t ced_write(struct file *file, const char *user_buffer, |
277 | size_t count, loff_t *ppos) | 274 | size_t count, loff_t * ppos) |
278 | { | 275 | { |
279 | DEVICE_EXTENSION *pdx = file->private_data; | 276 | DEVICE_EXTENSION *pdx = file->private_data; |
280 | dev_err(&pdx->interface->dev, "%s called: use ioctl for cedusb", __func__); | 277 | dev_err(&pdx->interface->dev, "%s called: use ioctl for cedusb", |
281 | return 0; | 278 | __func__); |
279 | return 0; | ||
282 | } | 280 | } |
283 | 281 | ||
284 | /*************************************************************************** | 282 | /*************************************************************************** |
@@ -288,80 +286,86 @@ static ssize_t ced_write(struct file *file, const char *user_buffer, | |||
288 | ** not help with a device extension held by a file. | 286 | ** not help with a device extension held by a file. |
289 | ** return true if can accept new io requests, else false | 287 | ** return true if can accept new io requests, else false |
290 | */ | 288 | */ |
291 | static bool CanAcceptIoRequests(DEVICE_EXTENSION* pdx) | 289 | static bool CanAcceptIoRequests(DEVICE_EXTENSION * pdx) |
292 | { | 290 | { |
293 | return pdx && pdx->interface; // Can we accept IO requests | 291 | return pdx && pdx->interface; // Can we accept IO requests |
294 | } | 292 | } |
295 | 293 | ||
296 | /**************************************************************************** | 294 | /**************************************************************************** |
297 | ** Callback routine to complete writes. This may need to fire off another | 295 | ** Callback routine to complete writes. This may need to fire off another |
298 | ** urb to complete the transfer. | 296 | ** urb to complete the transfer. |
299 | ****************************************************************************/ | 297 | ****************************************************************************/ |
300 | static void ced_writechar_callback(struct urb* pUrb) | 298 | static void ced_writechar_callback(struct urb *pUrb) |
301 | { | 299 | { |
302 | DEVICE_EXTENSION *pdx = pUrb->context; | 300 | DEVICE_EXTENSION *pdx = pUrb->context; |
303 | int nGot = pUrb->actual_length; // what we transferred | 301 | int nGot = pUrb->actual_length; // what we transferred |
304 | 302 | ||
305 | if (pUrb->status) | 303 | if (pUrb->status) { // sync/async unlink faults aren't errors |
306 | { // sync/async unlink faults aren't errors | 304 | if (! |
307 | if (!(pUrb->status == -ENOENT || pUrb->status == -ECONNRESET || pUrb->status == -ESHUTDOWN)) | 305 | (pUrb->status == -ENOENT || pUrb->status == -ECONNRESET |
308 | { | 306 | || pUrb->status == -ESHUTDOWN)) { |
309 | dev_err(&pdx->interface->dev, "%s - nonzero write bulk status received: %d", __func__, pUrb->status); | 307 | dev_err(&pdx->interface->dev, |
310 | } | 308 | "%s - nonzero write bulk status received: %d", |
311 | 309 | __func__, pUrb->status); | |
312 | spin_lock(&pdx->err_lock); | 310 | } |
313 | pdx->errors = pUrb->status; | 311 | |
314 | spin_unlock(&pdx->err_lock); | 312 | spin_lock(&pdx->err_lock); |
315 | nGot = 0; // and tidy up again if so | 313 | pdx->errors = pUrb->status; |
316 | 314 | spin_unlock(&pdx->err_lock); | |
317 | spin_lock(&pdx->charOutLock); // already at irq level | 315 | nGot = 0; // and tidy up again if so |
318 | pdx->dwOutBuffGet = 0; // Reset the output buffer | 316 | |
319 | pdx->dwOutBuffPut = 0; | 317 | spin_lock(&pdx->charOutLock); // already at irq level |
320 | pdx->dwNumOutput = 0; // Clear the char count | 318 | pdx->dwOutBuffGet = 0; // Reset the output buffer |
321 | pdx->bPipeError[0] = 1; // Flag an error for later | 319 | pdx->dwOutBuffPut = 0; |
322 | pdx->bSendCharsPending = false; // Allow other threads again | 320 | pdx->dwNumOutput = 0; // Clear the char count |
323 | spin_unlock(&pdx->charOutLock); // already at irq level | 321 | pdx->bPipeError[0] = 1; // Flag an error for later |
324 | dev_dbg(&pdx->interface->dev, "%s - char out done, 0 chars sent", __func__); | 322 | pdx->bSendCharsPending = false; // Allow other threads again |
325 | } | 323 | spin_unlock(&pdx->charOutLock); // already at irq level |
326 | else | 324 | dev_dbg(&pdx->interface->dev, |
327 | { | 325 | "%s - char out done, 0 chars sent", __func__); |
328 | dev_dbg(&pdx->interface->dev, "%s - char out done, %d chars sent", __func__, nGot); | 326 | } else { |
329 | spin_lock(&pdx->charOutLock); // already at irq level | 327 | dev_dbg(&pdx->interface->dev, |
330 | pdx->dwNumOutput -= nGot; // Now adjust the char send buffer | 328 | "%s - char out done, %d chars sent", __func__, nGot); |
331 | pdx->dwOutBuffGet += nGot; // to match what we did | 329 | spin_lock(&pdx->charOutLock); // already at irq level |
332 | if (pdx->dwOutBuffGet >= OUTBUF_SZ) // Can't do this any earlier as data could be overwritten | 330 | pdx->dwNumOutput -= nGot; // Now adjust the char send buffer |
333 | pdx->dwOutBuffGet = 0; | 331 | pdx->dwOutBuffGet += nGot; // to match what we did |
334 | 332 | if (pdx->dwOutBuffGet >= OUTBUF_SZ) // Can't do this any earlier as data could be overwritten | |
335 | if (pdx->dwNumOutput > 0) // if more to be done... | 333 | pdx->dwOutBuffGet = 0; |
336 | { | 334 | |
337 | int nPipe = 0; // The pipe number to use | 335 | if (pdx->dwNumOutput > 0) // if more to be done... |
338 | int iReturn; | 336 | { |
339 | char* pDat = &pdx->outputBuffer[pdx->dwOutBuffGet]; | 337 | int nPipe = 0; // The pipe number to use |
340 | unsigned int dwCount = pdx->dwNumOutput; // maximum to send | 338 | int iReturn; |
341 | if ((pdx->dwOutBuffGet+dwCount) > OUTBUF_SZ) // does it cross buffer end? | 339 | char *pDat = &pdx->outputBuffer[pdx->dwOutBuffGet]; |
342 | dwCount = OUTBUF_SZ - pdx->dwOutBuffGet; | 340 | unsigned int dwCount = pdx->dwNumOutput; // maximum to send |
343 | spin_unlock(&pdx->charOutLock); // we are done with stuff that changes | 341 | if ((pdx->dwOutBuffGet + dwCount) > OUTBUF_SZ) // does it cross buffer end? |
344 | memcpy(pdx->pCoherCharOut, pDat, dwCount); // copy output data to the buffer | 342 | dwCount = OUTBUF_SZ - pdx->dwOutBuffGet; |
345 | usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev, | 343 | spin_unlock(&pdx->charOutLock); // we are done with stuff that changes |
346 | usb_sndbulkpipe(pdx->udev, pdx->epAddr[0]), | 344 | memcpy(pdx->pCoherCharOut, pDat, dwCount); // copy output data to the buffer |
347 | pdx->pCoherCharOut, dwCount, ced_writechar_callback, pdx); | 345 | usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev, |
348 | pdx->pUrbCharOut->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 346 | usb_sndbulkpipe(pdx->udev, |
349 | usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted); // in case we need to kill it | 347 | pdx->epAddr[0]), |
350 | iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_ATOMIC); | 348 | pdx->pCoherCharOut, dwCount, |
351 | dev_dbg(&pdx->interface->dev, "%s n=%d>%s<", __func__, dwCount, pDat); | 349 | ced_writechar_callback, pdx); |
352 | spin_lock(&pdx->charOutLock); // grab lock for errors | 350 | pdx->pUrbCharOut->transfer_flags |= |
353 | if (iReturn) | 351 | URB_NO_TRANSFER_DMA_MAP; |
354 | { | 352 | usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted); // in case we need to kill it |
355 | pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later | 353 | iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_ATOMIC); |
356 | pdx->bSendCharsPending = false; // Allow other threads again | 354 | dev_dbg(&pdx->interface->dev, "%s n=%d>%s<", __func__, |
357 | usb_unanchor_urb(pdx->pUrbCharOut); | 355 | dwCount, pDat); |
358 | dev_err(&pdx->interface->dev, "%s usb_submit_urb() returned %d", __func__, iReturn); | 356 | spin_lock(&pdx->charOutLock); // grab lock for errors |
359 | } | 357 | if (iReturn) { |
360 | } | 358 | pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later |
361 | else | 359 | pdx->bSendCharsPending = false; // Allow other threads again |
362 | pdx->bSendCharsPending = false; // Allow other threads again | 360 | usb_unanchor_urb(pdx->pUrbCharOut); |
363 | spin_unlock(&pdx->charOutLock); // already at irq level | 361 | dev_err(&pdx->interface->dev, |
364 | } | 362 | "%s usb_submit_urb() returned %d", |
363 | __func__, iReturn); | ||
364 | } | ||
365 | } else | ||
366 | pdx->bSendCharsPending = false; // Allow other threads again | ||
367 | spin_unlock(&pdx->charOutLock); // already at irq level | ||
368 | } | ||
365 | } | 369 | } |
366 | 370 | ||
367 | /**************************************************************************** | 371 | /**************************************************************************** |
@@ -369,93 +373,91 @@ static void ced_writechar_callback(struct urb* pUrb) | |||
369 | ** Transmit the characters in the output buffer to the 1401. This may need | 373 | ** Transmit the characters in the output buffer to the 1401. This may need |
370 | ** breaking down into multiple transfers. | 374 | ** breaking down into multiple transfers. |
371 | ****************************************************************************/ | 375 | ****************************************************************************/ |
372 | int SendChars(DEVICE_EXTENSION* pdx) | 376 | int SendChars(DEVICE_EXTENSION * pdx) |
373 | { | 377 | { |
374 | int iReturn = U14ERR_NOERROR; | 378 | int iReturn = U14ERR_NOERROR; |
375 | 379 | ||
376 | spin_lock_irq(&pdx->charOutLock); // Protect ourselves | 380 | spin_lock_irq(&pdx->charOutLock); // Protect ourselves |
377 | 381 | ||
378 | if ((!pdx->bSendCharsPending) && // Not currently sending | 382 | if ((!pdx->bSendCharsPending) && // Not currently sending |
379 | (pdx->dwNumOutput > 0) && // has characters to output | 383 | (pdx->dwNumOutput > 0) && // has characters to output |
380 | (CanAcceptIoRequests(pdx))) // and current activity is OK | 384 | (CanAcceptIoRequests(pdx))) // and current activity is OK |
381 | { | 385 | { |
382 | unsigned int dwCount = pdx->dwNumOutput; // Get a copy of the character count | 386 | unsigned int dwCount = pdx->dwNumOutput; // Get a copy of the character count |
383 | pdx->bSendCharsPending = true; // Set flag to lock out other threads | 387 | pdx->bSendCharsPending = true; // Set flag to lock out other threads |
384 | 388 | ||
385 | dev_dbg(&pdx->interface->dev, "Send %d chars to 1401, EP0 flag %d\n", dwCount, pdx->nPipes == 3); | 389 | dev_dbg(&pdx->interface->dev, |
386 | // If we have only 3 end points we must send the characters to the 1401 using EP0. | 390 | "Send %d chars to 1401, EP0 flag %d\n", dwCount, |
387 | if (pdx->nPipes == 3) | 391 | pdx->nPipes == 3); |
388 | { | 392 | // If we have only 3 end points we must send the characters to the 1401 using EP0. |
389 | // For EP0 character transmissions to the 1401, we have to hang about until they | 393 | if (pdx->nPipes == 3) { |
390 | // are gone, as otherwise without more character IO activity they will never go. | 394 | // For EP0 character transmissions to the 1401, we have to hang about until they |
391 | unsigned int count = dwCount; // Local char counter | 395 | // are gone, as otherwise without more character IO activity they will never go. |
392 | unsigned int index = 0; // The index into the char buffer | 396 | unsigned int count = dwCount; // Local char counter |
393 | 397 | unsigned int index = 0; // The index into the char buffer | |
394 | spin_unlock_irq(&pdx->charOutLock); // Free spinlock as we call USBD | 398 | |
395 | 399 | spin_unlock_irq(&pdx->charOutLock); // Free spinlock as we call USBD | |
396 | while ((count > 0) && (iReturn == U14ERR_NOERROR)) | 400 | |
397 | { | 401 | while ((count > 0) && (iReturn == U14ERR_NOERROR)) { |
398 | // We have to break the transfer up into 64-byte chunks because of a 2270 problem | 402 | // We have to break the transfer up into 64-byte chunks because of a 2270 problem |
399 | int n = count > 64 ? 64 : count; // Chars for this xfer, max of 64 | 403 | int n = count > 64 ? 64 : count; // Chars for this xfer, max of 64 |
400 | int nSent = usb_control_msg(pdx->udev, | 404 | int nSent = usb_control_msg(pdx->udev, |
401 | usb_sndctrlpipe(pdx->udev,0), // use end point 0 | 405 | usb_sndctrlpipe(pdx->udev, 0), // use end point 0 |
402 | DB_CHARS, // bRequest | 406 | DB_CHARS, // bRequest |
403 | (H_TO_D|VENDOR|DEVREQ), // to the device, vendor request to the device | 407 | (H_TO_D | VENDOR | DEVREQ), // to the device, vendor request to the device |
404 | 0,0, // value and index are both 0 | 408 | 0, 0, // value and index are both 0 |
405 | &pdx->outputBuffer[index], // where to send from | 409 | &pdx->outputBuffer[index], // where to send from |
406 | n, // how much to send | 410 | n, // how much to send |
407 | 1000); // timeout in jiffies | 411 | 1000); // timeout in jiffies |
408 | if (nSent <= 0) | 412 | if (nSent <= 0) { |
409 | { | 413 | iReturn = nSent ? nSent : -ETIMEDOUT; // if 0 chars says we timed out |
410 | iReturn = nSent ? nSent : -ETIMEDOUT; // if 0 chars says we timed out | 414 | dev_err(&pdx->interface->dev, |
411 | dev_err(&pdx->interface->dev, "Send %d chars by EP0 failed: %d", n, iReturn); | 415 | "Send %d chars by EP0 failed: %d", |
412 | } | 416 | n, iReturn); |
413 | else | 417 | } else { |
414 | { | 418 | dev_dbg(&pdx->interface->dev, |
415 | dev_dbg(&pdx->interface->dev, "Sent %d chars by EP0", n); | 419 | "Sent %d chars by EP0", n); |
416 | count -= nSent; | 420 | count -= nSent; |
417 | index += nSent; | 421 | index += nSent; |
418 | } | 422 | } |
419 | } | 423 | } |
420 | 424 | ||
421 | spin_lock_irq(&pdx->charOutLock); // Protect pdx changes, released by general code | 425 | spin_lock_irq(&pdx->charOutLock); // Protect pdx changes, released by general code |
422 | pdx->dwOutBuffGet = 0; // so reset the output buffer | 426 | pdx->dwOutBuffGet = 0; // so reset the output buffer |
423 | pdx->dwOutBuffPut = 0; | 427 | pdx->dwOutBuffPut = 0; |
424 | pdx->dwNumOutput = 0; // and clear the buffer count | 428 | pdx->dwNumOutput = 0; // and clear the buffer count |
425 | pdx->bSendCharsPending = false; // Allow other threads again | 429 | pdx->bSendCharsPending = false; // Allow other threads again |
426 | } | 430 | } else { // Here for sending chars normally - we hold the spin lock |
427 | else | 431 | int nPipe = 0; // The pipe number to use |
428 | { // Here for sending chars normally - we hold the spin lock | 432 | char *pDat = &pdx->outputBuffer[pdx->dwOutBuffGet]; |
429 | int nPipe = 0; // The pipe number to use | 433 | |
430 | char* pDat = &pdx->outputBuffer[pdx->dwOutBuffGet]; | 434 | if ((pdx->dwOutBuffGet + dwCount) > OUTBUF_SZ) // does it cross buffer end? |
431 | 435 | dwCount = OUTBUF_SZ - pdx->dwOutBuffGet; | |
432 | if ((pdx->dwOutBuffGet+dwCount) > OUTBUF_SZ) // does it cross buffer end? | 436 | spin_unlock_irq(&pdx->charOutLock); // we are done with stuff that changes |
433 | dwCount = OUTBUF_SZ - pdx->dwOutBuffGet; | 437 | memcpy(pdx->pCoherCharOut, pDat, dwCount); // copy output data to the buffer |
434 | spin_unlock_irq(&pdx->charOutLock); // we are done with stuff that changes | 438 | usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev, |
435 | memcpy(pdx->pCoherCharOut, pDat, dwCount); // copy output data to the buffer | 439 | usb_sndbulkpipe(pdx->udev, |
436 | usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev, | 440 | pdx->epAddr[0]), |
437 | usb_sndbulkpipe(pdx->udev, pdx->epAddr[0]), | 441 | pdx->pCoherCharOut, dwCount, |
438 | pdx->pCoherCharOut, dwCount, ced_writechar_callback, pdx); | 442 | ced_writechar_callback, pdx); |
439 | pdx->pUrbCharOut->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 443 | pdx->pUrbCharOut->transfer_flags |= |
440 | usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted); | 444 | URB_NO_TRANSFER_DMA_MAP; |
441 | iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_KERNEL); | 445 | usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted); |
442 | spin_lock_irq(&pdx->charOutLock); // grab lock for errors | 446 | iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_KERNEL); |
443 | if (iReturn) | 447 | spin_lock_irq(&pdx->charOutLock); // grab lock for errors |
444 | { | 448 | if (iReturn) { |
445 | pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later | 449 | pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later |
446 | pdx->bSendCharsPending = false; // Allow other threads again | 450 | pdx->bSendCharsPending = false; // Allow other threads again |
447 | usb_unanchor_urb(pdx->pUrbCharOut); // remove from list of active urbs | 451 | usb_unanchor_urb(pdx->pUrbCharOut); // remove from list of active urbs |
448 | } | 452 | } |
449 | } | 453 | } |
450 | } | 454 | } else if (pdx->bSendCharsPending && (pdx->dwNumOutput > 0)) |
451 | else | 455 | dev_dbg(&pdx->interface->dev, |
452 | if (pdx->bSendCharsPending && (pdx->dwNumOutput > 0)) | 456 | "SendChars bSendCharsPending:true"); |
453 | dev_dbg(&pdx->interface->dev, "SendChars bSendCharsPending:true"); | 457 | |
454 | 458 | dev_dbg(&pdx->interface->dev, "SendChars exit code: %d", iReturn); | |
455 | 459 | spin_unlock_irq(&pdx->charOutLock); // Now let go of the spinlock | |
456 | dev_dbg(&pdx->interface->dev, "SendChars exit code: %d", iReturn); | 460 | return iReturn; |
457 | spin_unlock_irq(&pdx->charOutLock); // Now let go of the spinlock | ||
458 | return iReturn; | ||
459 | } | 461 | } |
460 | 462 | ||
461 | /*************************************************************************** | 463 | /*************************************************************************** |
@@ -472,228 +474,265 @@ int SendChars(DEVICE_EXTENSION* pdx) | |||
472 | ** pdx Is our device extension which holds all we know about the transfer. | 474 | ** pdx Is our device extension which holds all we know about the transfer. |
473 | ** n The number of bytes to move one way or the other. | 475 | ** n The number of bytes to move one way or the other. |
474 | ***************************************************************************/ | 476 | ***************************************************************************/ |
475 | static void CopyUserSpace(DEVICE_EXTENSION *pdx, int n) | 477 | static void CopyUserSpace(DEVICE_EXTENSION * pdx, int n) |
476 | { | 478 | { |
477 | unsigned int nArea = pdx->StagedId; | 479 | unsigned int nArea = pdx->StagedId; |
478 | if (nArea < MAX_TRANSAREAS) | 480 | if (nArea < MAX_TRANSAREAS) { |
479 | { | 481 | TRANSAREA *pArea = &pdx->rTransDef[nArea]; // area to be used |
480 | TRANSAREA *pArea = &pdx->rTransDef[nArea]; // area to be used | 482 | unsigned int dwOffset = |
481 | unsigned int dwOffset = pdx->StagedDone + pdx->StagedOffset + pArea->dwBaseOffset; | 483 | pdx->StagedDone + pdx->StagedOffset + pArea->dwBaseOffset; |
482 | char* pCoherBuf = pdx->pCoherStagedIO; // coherent buffer | 484 | char *pCoherBuf = pdx->pCoherStagedIO; // coherent buffer |
483 | if (!pArea->bUsed) | 485 | if (!pArea->bUsed) { |
484 | { | 486 | dev_err(&pdx->interface->dev, "%s area %d unused", |
485 | dev_err(&pdx->interface->dev, "%s area %d unused", __func__, nArea); | 487 | __func__, nArea); |
486 | return; | 488 | return; |
487 | } | 489 | } |
488 | 490 | ||
489 | while (n) | 491 | while (n) { |
490 | { | 492 | int nPage = dwOffset >> PAGE_SHIFT; // page number in table |
491 | int nPage = dwOffset >> PAGE_SHIFT; // page number in table | 493 | if (nPage < pArea->nPages) { |
492 | if (nPage < pArea->nPages) | 494 | char *pvAddress = |
493 | { | 495 | (char *)kmap_atomic(pArea->pPages[nPage]); |
494 | char *pvAddress = (char*)kmap_atomic(pArea->pPages[nPage]); | 496 | if (pvAddress) { |
495 | if (pvAddress) | 497 | unsigned int uiPageOff = dwOffset & (PAGE_SIZE - 1); // offset into the page |
496 | { | 498 | size_t uiXfer = PAGE_SIZE - uiPageOff; // max to transfer on this page |
497 | unsigned int uiPageOff = dwOffset & (PAGE_SIZE-1); // offset into the page | 499 | if (uiXfer > n) // limit byte count if too much |
498 | size_t uiXfer = PAGE_SIZE - uiPageOff; // max to transfer on this page | 500 | uiXfer = n; // for the page |
499 | if (uiXfer > n) // limit byte count if too much | 501 | if (pdx->StagedRead) |
500 | uiXfer = n; // for the page | 502 | memcpy(pvAddress + uiPageOff, |
501 | if (pdx->StagedRead) | 503 | pCoherBuf, uiXfer); |
502 | memcpy(pvAddress+uiPageOff, pCoherBuf, uiXfer); | 504 | else |
503 | else | 505 | memcpy(pCoherBuf, |
504 | memcpy(pCoherBuf, pvAddress+uiPageOff, uiXfer); | 506 | pvAddress + uiPageOff, |
505 | kunmap_atomic(pvAddress); | 507 | uiXfer); |
506 | dwOffset += uiXfer; | 508 | kunmap_atomic(pvAddress); |
507 | pCoherBuf += uiXfer; | 509 | dwOffset += uiXfer; |
508 | n -= uiXfer; | 510 | pCoherBuf += uiXfer; |
509 | } | 511 | n -= uiXfer; |
510 | else | 512 | } else { |
511 | { | 513 | dev_err(&pdx->interface->dev, |
512 | dev_err(&pdx->interface->dev, "%s did not map page %d", __func__, nPage); | 514 | "%s did not map page %d", |
513 | return; | 515 | __func__, nPage); |
514 | } | 516 | return; |
515 | 517 | } | |
516 | } | 518 | |
517 | else | 519 | } else { |
518 | { | 520 | dev_err(&pdx->interface->dev, |
519 | dev_err(&pdx->interface->dev, "%s exceeded pages %d", __func__, nPage); | 521 | "%s exceeded pages %d", __func__, |
520 | return; | 522 | nPage); |
521 | } | 523 | return; |
522 | } | 524 | } |
523 | } | 525 | } |
524 | else | 526 | } else |
525 | dev_err(&pdx->interface->dev, "%s bad area %d", __func__, nArea); | 527 | dev_err(&pdx->interface->dev, "%s bad area %d", __func__, |
528 | nArea); | ||
526 | } | 529 | } |
527 | 530 | ||
528 | // Forward declarations for stuff used circularly | 531 | // Forward declarations for stuff used circularly |
529 | static int StageChunk(DEVICE_EXTENSION *pdx); | 532 | static int StageChunk(DEVICE_EXTENSION * pdx); |
530 | /*************************************************************************** | 533 | /*************************************************************************** |
531 | ** ReadWrite_Complete | 534 | ** ReadWrite_Complete |
532 | ** | 535 | ** |
533 | ** Completion routine for our staged read/write Irps | 536 | ** Completion routine for our staged read/write Irps |
534 | */ | 537 | */ |
535 | static void staged_callback(struct urb* pUrb) | 538 | static void staged_callback(struct urb *pUrb) |
536 | { | 539 | { |
537 | DEVICE_EXTENSION *pdx = pUrb->context; | 540 | DEVICE_EXTENSION *pdx = pUrb->context; |
538 | unsigned int nGot = pUrb->actual_length; // what we transferred | 541 | unsigned int nGot = pUrb->actual_length; // what we transferred |
539 | bool bCancel = false; | 542 | bool bCancel = false; |
540 | bool bRestartCharInput; // used at the end | 543 | bool bRestartCharInput; // used at the end |
541 | 544 | ||
542 | spin_lock(&pdx->stagedLock); // stop ReadWriteMem() action while this routine is running | 545 | spin_lock(&pdx->stagedLock); // stop ReadWriteMem() action while this routine is running |
543 | pdx->bStagedUrbPending = false; // clear the flag for staged IRP pending | 546 | pdx->bStagedUrbPending = false; // clear the flag for staged IRP pending |
544 | 547 | ||
545 | if (pUrb->status) | 548 | if (pUrb->status) { // sync/async unlink faults aren't errors |
546 | { // sync/async unlink faults aren't errors | 549 | if (! |
547 | if (!(pUrb->status == -ENOENT || pUrb->status == -ECONNRESET || pUrb->status == -ESHUTDOWN)) | 550 | (pUrb->status == -ENOENT || pUrb->status == -ECONNRESET |
548 | { | 551 | || pUrb->status == -ESHUTDOWN)) { |
549 | dev_err(&pdx->interface->dev, "%s - nonzero write bulk status received: %d", __func__, pUrb->status); | 552 | dev_err(&pdx->interface->dev, |
550 | } | 553 | "%s - nonzero write bulk status received: %d", |
551 | else | 554 | __func__, pUrb->status); |
552 | dev_info(&pdx->interface->dev, "%s - staged xfer cancelled", __func__); | 555 | } else |
553 | 556 | dev_info(&pdx->interface->dev, | |
554 | spin_lock(&pdx->err_lock); | 557 | "%s - staged xfer cancelled", __func__); |
555 | pdx->errors = pUrb->status; | 558 | |
556 | spin_unlock(&pdx->err_lock); | 559 | spin_lock(&pdx->err_lock); |
557 | nGot = 0; // and tidy up again if so | 560 | pdx->errors = pUrb->status; |
558 | bCancel = true; | 561 | spin_unlock(&pdx->err_lock); |
559 | } | 562 | nGot = 0; // and tidy up again if so |
560 | else | 563 | bCancel = true; |
561 | { | 564 | } else { |
562 | dev_dbg(&pdx->interface->dev, "%s %d chars xferred", __func__, nGot); | 565 | dev_dbg(&pdx->interface->dev, "%s %d chars xferred", __func__, |
563 | if (pdx->StagedRead) // if reading, save to user space | 566 | nGot); |
564 | CopyUserSpace(pdx, nGot); // copy from buffer to user | 567 | if (pdx->StagedRead) // if reading, save to user space |
565 | if (nGot == 0) | 568 | CopyUserSpace(pdx, nGot); // copy from buffer to user |
566 | dev_dbg(&pdx->interface->dev, "%s ZLP", __func__); | 569 | if (nGot == 0) |
567 | } | 570 | dev_dbg(&pdx->interface->dev, "%s ZLP", __func__); |
568 | 571 | } | |
569 | // Update the transfer length based on the TransferBufferLength value in the URB | 572 | |
570 | pdx->StagedDone += nGot; | 573 | // Update the transfer length based on the TransferBufferLength value in the URB |
571 | 574 | pdx->StagedDone += nGot; | |
572 | dev_dbg(&pdx->interface->dev, "%s, done %d bytes of %d", __func__, pdx->StagedDone, pdx->StagedLength); | 575 | |
573 | 576 | dev_dbg(&pdx->interface->dev, "%s, done %d bytes of %d", __func__, | |
574 | if ((pdx->StagedDone == pdx->StagedLength) || // If no more to do | 577 | pdx->StagedDone, pdx->StagedLength); |
575 | (bCancel)) // or this IRP was cancelled | 578 | |
576 | { | 579 | if ((pdx->StagedDone == pdx->StagedLength) || // If no more to do |
577 | TRANSAREA* pArea = &pdx->rTransDef[pdx->StagedId]; // Transfer area info | 580 | (bCancel)) // or this IRP was cancelled |
578 | dev_dbg(&pdx->interface->dev, "%s transfer done, bytes %d, cancel %d", __func__, pdx->StagedDone, bCancel); | 581 | { |
579 | 582 | TRANSAREA *pArea = &pdx->rTransDef[pdx->StagedId]; // Transfer area info | |
580 | // Here is where we sort out what to do with this transfer if using a circular buffer. We have | 583 | dev_dbg(&pdx->interface->dev, |
581 | // a completed transfer that can be assumed to fit into the transfer area. We should be able to | 584 | "%s transfer done, bytes %d, cancel %d", __func__, |
582 | // add this to the end of a growing block or to use it to start a new block unless the code | 585 | pdx->StagedDone, bCancel); |
583 | // that calculates the offset to use (in ReadWriteMem) is totally duff. | 586 | |
584 | if ((pArea->bCircular) && (pArea->bCircToHost) && (!bCancel) && // Time to sort out circular buffer info? | 587 | // Here is where we sort out what to do with this transfer if using a circular buffer. We have |
585 | (pdx->StagedRead)) // Only for tohost transfers for now | 588 | // a completed transfer that can be assumed to fit into the transfer area. We should be able to |
586 | { | 589 | // add this to the end of a growing block or to use it to start a new block unless the code |
587 | if (pArea->aBlocks[1].dwSize > 0) // If block 1 is in use we must append to it | 590 | // that calculates the offset to use (in ReadWriteMem) is totally duff. |
588 | { | 591 | if ((pArea->bCircular) && (pArea->bCircToHost) && (!bCancel) && // Time to sort out circular buffer info? |
589 | if (pdx->StagedOffset == (pArea->aBlocks[1].dwOffset + pArea->aBlocks[1].dwSize)) | 592 | (pdx->StagedRead)) // Only for tohost transfers for now |
590 | { | 593 | { |
591 | pArea->aBlocks[1].dwSize += pdx->StagedLength; | 594 | if (pArea->aBlocks[1].dwSize > 0) // If block 1 is in use we must append to it |
592 | dev_dbg(&pdx->interface->dev, "RWM_Complete, circ block 1 now %d bytes at %d", | 595 | { |
593 | pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset); | 596 | if (pdx->StagedOffset == |
594 | } | 597 | (pArea->aBlocks[1].dwOffset + |
595 | else | 598 | pArea->aBlocks[1].dwSize)) { |
596 | { | 599 | pArea->aBlocks[1].dwSize += |
597 | // Here things have gone very, very, wrong, but I cannot see how this can actually be achieved | 600 | pdx->StagedLength; |
598 | pArea->aBlocks[1].dwOffset = pdx->StagedOffset; | 601 | dev_dbg(&pdx->interface->dev, |
599 | pArea->aBlocks[1].dwSize = pdx->StagedLength; | 602 | "RWM_Complete, circ block 1 now %d bytes at %d", |
600 | dev_err(&pdx->interface->dev, "%s ERROR, circ block 1 re-started %d bytes at %d", | 603 | pArea->aBlocks[1].dwSize, |
601 | __func__, pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset); | 604 | pArea->aBlocks[1].dwOffset); |
602 | } | 605 | } else { |
603 | } | 606 | // Here things have gone very, very, wrong, but I cannot see how this can actually be achieved |
604 | else // If block 1 is not used, we try to add to block 0 | 607 | pArea->aBlocks[1].dwOffset = |
605 | { | 608 | pdx->StagedOffset; |
606 | if (pArea->aBlocks[0].dwSize > 0) // Got stored block 0 information? | 609 | pArea->aBlocks[1].dwSize = |
607 | { // Must append onto the existing block 0 | 610 | pdx->StagedLength; |
608 | if (pdx->StagedOffset == (pArea->aBlocks[0].dwOffset + pArea->aBlocks[0].dwSize)) | 611 | dev_err(&pdx->interface->dev, |
609 | { | 612 | "%s ERROR, circ block 1 re-started %d bytes at %d", |
610 | pArea->aBlocks[0].dwSize += pdx->StagedLength; // Just add this transfer in | 613 | __func__, |
611 | dev_dbg(&pdx->interface->dev, "RWM_Complete, circ block 0 now %d bytes at %d", | 614 | pArea->aBlocks[1].dwSize, |
612 | pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset); | 615 | pArea->aBlocks[1].dwOffset); |
613 | } | 616 | } |
614 | else // If it doesn't append, put into new block 1 | 617 | } else // If block 1 is not used, we try to add to block 0 |
615 | { | 618 | { |
616 | pArea->aBlocks[1].dwOffset = pdx->StagedOffset; | 619 | if (pArea->aBlocks[0].dwSize > 0) // Got stored block 0 information? |
617 | pArea->aBlocks[1].dwSize = pdx->StagedLength; | 620 | { // Must append onto the existing block 0 |
618 | dev_dbg(&pdx->interface->dev, "RWM_Complete, circ block 1 started %d bytes at %d", | 621 | if (pdx->StagedOffset == |
619 | pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset); | 622 | (pArea->aBlocks[0].dwOffset + |
620 | } | 623 | pArea->aBlocks[0].dwSize)) { |
621 | } | 624 | pArea->aBlocks[0].dwSize += pdx->StagedLength; // Just add this transfer in |
622 | else // No info stored yet, just save in block 0 | 625 | dev_dbg(&pdx->interface->dev, |
623 | { | 626 | "RWM_Complete, circ block 0 now %d bytes at %d", |
624 | pArea->aBlocks[0].dwOffset = pdx->StagedOffset; | 627 | pArea->aBlocks[0]. |
625 | pArea->aBlocks[0].dwSize = pdx->StagedLength; | 628 | dwSize, |
626 | dev_dbg(&pdx->interface->dev, "RWM_Complete, circ block 0 started %d bytes at %d", | 629 | pArea->aBlocks[0]. |
627 | pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset); | 630 | dwOffset); |
628 | } | 631 | } else // If it doesn't append, put into new block 1 |
629 | } | 632 | { |
630 | } | 633 | pArea->aBlocks[1].dwOffset = |
631 | 634 | pdx->StagedOffset; | |
632 | if (!bCancel) // Don't generate an event if cancelled | 635 | pArea->aBlocks[1].dwSize = |
633 | { | 636 | pdx->StagedLength; |
634 | dev_dbg(&pdx->interface->dev, "RWM_Complete, bCircular %d, bToHost %d, eStart %d, eSize %d", | 637 | dev_dbg(&pdx->interface->dev, |
635 | pArea->bCircular, pArea->bEventToHost, pArea->dwEventSt, pArea->dwEventSz); | 638 | "RWM_Complete, circ block 1 started %d bytes at %d", |
636 | if ((pArea->dwEventSz) && // Set a user-mode event... | 639 | pArea->aBlocks[1]. |
637 | (pdx->StagedRead == pArea->bEventToHost)) // ...on transfers in this direction? | 640 | dwSize, |
638 | { | 641 | pArea->aBlocks[1]. |
639 | int iWakeUp = 0; // assume | 642 | dwOffset); |
640 | // If we have completed the right sort of DMA transfer then set the event to notify | 643 | } |
641 | // the user code to wake up anyone that is waiting. | 644 | } else // No info stored yet, just save in block 0 |
642 | if ((pArea->bCircular) && // Circular areas use a simpler test | 645 | { |
643 | (pArea->bCircToHost)) // only in supported direction | 646 | pArea->aBlocks[0].dwOffset = |
644 | { // Is total data waiting up to size limit? | 647 | pdx->StagedOffset; |
645 | unsigned int dwTotal = pArea->aBlocks[0].dwSize + pArea->aBlocks[1].dwSize; | 648 | pArea->aBlocks[0].dwSize = |
646 | iWakeUp = (dwTotal >= pArea->dwEventSz); | 649 | pdx->StagedLength; |
647 | } | 650 | dev_dbg(&pdx->interface->dev, |
648 | else | 651 | "RWM_Complete, circ block 0 started %d bytes at %d", |
649 | { | 652 | pArea->aBlocks[0].dwSize, |
650 | unsigned int transEnd = pdx->StagedOffset + pdx->StagedLength; | 653 | pArea->aBlocks[0].dwOffset); |
651 | unsigned int eventEnd = pArea->dwEventSt + pArea->dwEventSz; | 654 | } |
652 | iWakeUp = (pdx->StagedOffset < eventEnd) && (transEnd > pArea->dwEventSt); | 655 | } |
653 | } | 656 | } |
654 | 657 | ||
655 | if (iWakeUp) | 658 | if (!bCancel) // Don't generate an event if cancelled |
656 | { | 659 | { |
657 | dev_dbg(&pdx->interface->dev, "About to set event to notify app"); | 660 | dev_dbg(&pdx->interface->dev, |
658 | wake_up_interruptible(&pArea->wqEvent); // wake up waiting processes | 661 | "RWM_Complete, bCircular %d, bToHost %d, eStart %d, eSize %d", |
659 | ++pArea->iWakeUp; // increment wakeup count | 662 | pArea->bCircular, pArea->bEventToHost, |
660 | } | 663 | pArea->dwEventSt, pArea->dwEventSz); |
661 | } | 664 | if ((pArea->dwEventSz) && // Set a user-mode event... |
662 | } | 665 | (pdx->StagedRead == pArea->bEventToHost)) // ...on transfers in this direction? |
663 | 666 | { | |
664 | pdx->dwDMAFlag = MODE_CHAR; // Switch back to char mode before ReadWriteMem call | 667 | int iWakeUp = 0; // assume |
665 | 668 | // If we have completed the right sort of DMA transfer then set the event to notify | |
666 | if (!bCancel) // Don't look for waiting transfer if cancelled | 669 | // the user code to wake up anyone that is waiting. |
667 | { | 670 | if ((pArea->bCircular) && // Circular areas use a simpler test |
668 | // If we have a transfer waiting, kick it off | 671 | (pArea->bCircToHost)) // only in supported direction |
669 | if (pdx->bXFerWaiting) // Got a block xfer waiting? | 672 | { // Is total data waiting up to size limit? |
670 | { | 673 | unsigned int dwTotal = |
671 | int iReturn; | 674 | pArea->aBlocks[0].dwSize + |
672 | dev_info(&pdx->interface->dev, "*** RWM_Complete *** pending transfer will now be set up!!!"); | 675 | pArea->aBlocks[1].dwSize; |
673 | iReturn = ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard, pdx->rDMAInfo.wIdent, pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize); | 676 | iWakeUp = (dwTotal >= pArea->dwEventSz); |
674 | 677 | } else { | |
675 | if (iReturn) | 678 | unsigned int transEnd = |
676 | dev_err(&pdx->interface->dev, "RWM_Complete rw setup failed %d", iReturn); | 679 | pdx->StagedOffset + |
677 | } | 680 | pdx->StagedLength; |
678 | } | 681 | unsigned int eventEnd = |
679 | 682 | pArea->dwEventSt + pArea->dwEventSz; | |
680 | } | 683 | iWakeUp = (pdx->StagedOffset < eventEnd) |
681 | else // Here for more to do | 684 | && (transEnd > pArea->dwEventSt); |
682 | StageChunk(pdx); // fire off the next bit | 685 | } |
683 | 686 | ||
684 | // While we hold the stagedLock, see if we should reallow character input ints | 687 | if (iWakeUp) { |
685 | // Don't allow if cancelled, or if a new block has started or if there is a waiting block. | 688 | dev_dbg(&pdx->interface->dev, |
686 | // This feels wrong as we should ask which spin lock protects dwDMAFlag. | 689 | "About to set event to notify app"); |
687 | bRestartCharInput = !bCancel && (pdx->dwDMAFlag == MODE_CHAR) && !pdx->bXFerWaiting; | 690 | wake_up_interruptible(&pArea->wqEvent); // wake up waiting processes |
688 | 691 | ++pArea->iWakeUp; // increment wakeup count | |
689 | spin_unlock(&pdx->stagedLock); // Finally release the lock again | 692 | } |
690 | 693 | } | |
691 | // This is not correct as dwDMAFlag is protected by the staged lock, but it is treated | 694 | } |
692 | // in Allowi as if it were protected by the char lock. In any case, most systems will | 695 | |
693 | // not be upset by char input during DMA... sigh. Needs sorting out. | 696 | pdx->dwDMAFlag = MODE_CHAR; // Switch back to char mode before ReadWriteMem call |
694 | if (bRestartCharInput) // may be out of date, but... | 697 | |
695 | Allowi(pdx, true); // ...Allowi tests a lock too. | 698 | if (!bCancel) // Don't look for waiting transfer if cancelled |
696 | dev_dbg(&pdx->interface->dev, "%s done", __func__); | 699 | { |
700 | // If we have a transfer waiting, kick it off | ||
701 | if (pdx->bXFerWaiting) // Got a block xfer waiting? | ||
702 | { | ||
703 | int iReturn; | ||
704 | dev_info(&pdx->interface->dev, | ||
705 | "*** RWM_Complete *** pending transfer will now be set up!!!"); | ||
706 | iReturn = | ||
707 | ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard, | ||
708 | pdx->rDMAInfo.wIdent, | ||
709 | pdx->rDMAInfo.dwOffset, | ||
710 | pdx->rDMAInfo.dwSize); | ||
711 | |||
712 | if (iReturn) | ||
713 | dev_err(&pdx->interface->dev, | ||
714 | "RWM_Complete rw setup failed %d", | ||
715 | iReturn); | ||
716 | } | ||
717 | } | ||
718 | |||
719 | } else // Here for more to do | ||
720 | StageChunk(pdx); // fire off the next bit | ||
721 | |||
722 | // While we hold the stagedLock, see if we should reallow character input ints | ||
723 | // Don't allow if cancelled, or if a new block has started or if there is a waiting block. | ||
724 | // This feels wrong as we should ask which spin lock protects dwDMAFlag. | ||
725 | bRestartCharInput = !bCancel && (pdx->dwDMAFlag == MODE_CHAR) | ||
726 | && !pdx->bXFerWaiting; | ||
727 | |||
728 | spin_unlock(&pdx->stagedLock); // Finally release the lock again | ||
729 | |||
730 | // This is not correct as dwDMAFlag is protected by the staged lock, but it is treated | ||
731 | // in Allowi as if it were protected by the char lock. In any case, most systems will | ||
732 | // not be upset by char input during DMA... sigh. Needs sorting out. | ||
733 | if (bRestartCharInput) // may be out of date, but... | ||
734 | Allowi(pdx, true); // ...Allowi tests a lock too. | ||
735 | dev_dbg(&pdx->interface->dev, "%s done", __func__); | ||
697 | } | 736 | } |
698 | 737 | ||
699 | /**************************************************************************** | 738 | /**************************************************************************** |
@@ -704,46 +743,50 @@ static void staged_callback(struct urb* pUrb) | |||
704 | ** The calling code must have acquired the staging spinlock before calling | 743 | ** The calling code must have acquired the staging spinlock before calling |
705 | ** this function, and is responsible for releasing it. We are at callback level. | 744 | ** this function, and is responsible for releasing it. We are at callback level. |
706 | ****************************************************************************/ | 745 | ****************************************************************************/ |
707 | static int StageChunk(DEVICE_EXTENSION *pdx) | 746 | static int StageChunk(DEVICE_EXTENSION * pdx) |
708 | { | 747 | { |
709 | int iReturn = U14ERR_NOERROR; | 748 | int iReturn = U14ERR_NOERROR; |
710 | unsigned int ChunkSize; | 749 | unsigned int ChunkSize; |
711 | int nPipe = pdx->StagedRead ? 3 : 2; // The pipe number to use for reads or writes | 750 | int nPipe = pdx->StagedRead ? 3 : 2; // The pipe number to use for reads or writes |
712 | if (pdx->nPipes == 3) nPipe--; // Adjust for the 3-pipe case | 751 | if (pdx->nPipes == 3) |
713 | if (nPipe < 0) // and trap case that should never happen | 752 | nPipe--; // Adjust for the 3-pipe case |
714 | return U14ERR_FAIL; | 753 | if (nPipe < 0) // and trap case that should never happen |
715 | 754 | return U14ERR_FAIL; | |
716 | if (!CanAcceptIoRequests(pdx)) // got sudden remove? | 755 | |
717 | { | 756 | if (!CanAcceptIoRequests(pdx)) // got sudden remove? |
718 | dev_info(&pdx->interface->dev, "%s sudden remove, giving up", __func__); | 757 | { |
719 | return U14ERR_FAIL; // could do with a better error | 758 | dev_info(&pdx->interface->dev, "%s sudden remove, giving up", |
720 | } | 759 | __func__); |
721 | 760 | return U14ERR_FAIL; // could do with a better error | |
722 | ChunkSize = (pdx->StagedLength - pdx->StagedDone); // transfer length remaining | 761 | } |
723 | if (ChunkSize > STAGED_SZ) // make sure to keep legal | 762 | |
724 | ChunkSize = STAGED_SZ; // limit to max allowed | 763 | ChunkSize = (pdx->StagedLength - pdx->StagedDone); // transfer length remaining |
725 | 764 | if (ChunkSize > STAGED_SZ) // make sure to keep legal | |
726 | if (!pdx->StagedRead) // if writing... | 765 | ChunkSize = STAGED_SZ; // limit to max allowed |
727 | CopyUserSpace(pdx, ChunkSize); // ...copy data into the buffer | 766 | |
728 | 767 | if (!pdx->StagedRead) // if writing... | |
729 | usb_fill_bulk_urb(pdx->pStagedUrb, pdx->udev, | 768 | CopyUserSpace(pdx, ChunkSize); // ...copy data into the buffer |
730 | pdx->StagedRead ? usb_rcvbulkpipe(pdx->udev, pdx->epAddr[nPipe]): | 769 | |
731 | usb_sndbulkpipe(pdx->udev, pdx->epAddr[nPipe]), | 770 | usb_fill_bulk_urb(pdx->pStagedUrb, pdx->udev, |
732 | pdx->pCoherStagedIO, ChunkSize, staged_callback, pdx); | 771 | pdx->StagedRead ? usb_rcvbulkpipe(pdx->udev, |
733 | pdx->pStagedUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 772 | pdx-> |
734 | usb_anchor_urb(pdx->pStagedUrb, &pdx->submitted); // in case we need to kill it | 773 | epAddr[nPipe]) : |
735 | iReturn = usb_submit_urb(pdx->pStagedUrb, GFP_ATOMIC); | 774 | usb_sndbulkpipe(pdx->udev, pdx->epAddr[nPipe]), |
736 | if (iReturn) | 775 | pdx->pCoherStagedIO, ChunkSize, staged_callback, pdx); |
737 | { | 776 | pdx->pStagedUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
738 | usb_unanchor_urb(pdx->pStagedUrb); // kill it | 777 | usb_anchor_urb(pdx->pStagedUrb, &pdx->submitted); // in case we need to kill it |
739 | pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later | 778 | iReturn = usb_submit_urb(pdx->pStagedUrb, GFP_ATOMIC); |
740 | dev_err(&pdx->interface->dev, "%s submit urb failed, code %d", __func__, iReturn); | 779 | if (iReturn) { |
741 | } | 780 | usb_unanchor_urb(pdx->pStagedUrb); // kill it |
742 | else | 781 | pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later |
743 | pdx->bStagedUrbPending = true; // Set the flag for staged URB pending | 782 | dev_err(&pdx->interface->dev, "%s submit urb failed, code %d", |
744 | dev_dbg(&pdx->interface->dev, "%s done so far:%d, this size:%d", __func__, pdx->StagedDone, ChunkSize); | 783 | __func__, iReturn); |
745 | 784 | } else | |
746 | return iReturn; | 785 | pdx->bStagedUrbPending = true; // Set the flag for staged URB pending |
786 | dev_dbg(&pdx->interface->dev, "%s done so far:%d, this size:%d", | ||
787 | __func__, pdx->StagedDone, ChunkSize); | ||
788 | |||
789 | return iReturn; | ||
747 | } | 790 | } |
748 | 791 | ||
749 | /*************************************************************************** | 792 | /*************************************************************************** |
@@ -763,85 +806,95 @@ static int StageChunk(DEVICE_EXTENSION *pdx) | |||
763 | ** transfer. | 806 | ** transfer. |
764 | ** dwLen - the number of bytes to transfer. | 807 | ** dwLen - the number of bytes to transfer. |
765 | */ | 808 | */ |
766 | int ReadWriteMem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent, | 809 | int ReadWriteMem(DEVICE_EXTENSION * pdx, bool Read, unsigned short wIdent, |
767 | unsigned int dwOffs, unsigned int dwLen) | 810 | unsigned int dwOffs, unsigned int dwLen) |
768 | { | 811 | { |
769 | TRANSAREA* pArea = &pdx->rTransDef[wIdent]; // Transfer area info | 812 | TRANSAREA *pArea = &pdx->rTransDef[wIdent]; // Transfer area info |
770 | 813 | ||
771 | if (!CanAcceptIoRequests(pdx)) // Are we in a state to accept new requests? | 814 | if (!CanAcceptIoRequests(pdx)) // Are we in a state to accept new requests? |
772 | { | 815 | { |
773 | dev_err(&pdx->interface->dev, "%s can't accept requests", __func__); | 816 | dev_err(&pdx->interface->dev, "%s can't accept requests", |
774 | return U14ERR_FAIL; | 817 | __func__); |
775 | } | 818 | return U14ERR_FAIL; |
776 | 819 | } | |
777 | dev_dbg(&pdx->interface->dev, "%s xfer %d bytes to %s, offset %d, area %d", | 820 | |
778 | __func__, dwLen, Read ? "host" : "1401", dwOffs, wIdent); | 821 | dev_dbg(&pdx->interface->dev, |
779 | 822 | "%s xfer %d bytes to %s, offset %d, area %d", __func__, dwLen, | |
780 | // Amazingly, we can get an escape sequence back before the current staged Urb is done, so we | 823 | Read ? "host" : "1401", dwOffs, wIdent); |
781 | // have to check for this situation and, if so, wait until all is OK. | 824 | |
782 | if (pdx->bStagedUrbPending) | 825 | // Amazingly, we can get an escape sequence back before the current staged Urb is done, so we |
783 | { | 826 | // have to check for this situation and, if so, wait until all is OK. |
784 | pdx->bXFerWaiting = true; // Flag we are waiting | 827 | if (pdx->bStagedUrbPending) { |
785 | dev_info(&pdx->interface->dev, "%s xfer is waiting, as previous staged pending", __func__); | 828 | pdx->bXFerWaiting = true; // Flag we are waiting |
786 | return U14ERR_NOERROR; | 829 | dev_info(&pdx->interface->dev, |
787 | } | 830 | "%s xfer is waiting, as previous staged pending", |
788 | 831 | __func__); | |
789 | if (dwLen == 0) // allow 0-len read or write; just return success | 832 | return U14ERR_NOERROR; |
790 | { | 833 | } |
791 | dev_dbg(&pdx->interface->dev, "%s OK; zero-len read/write request", __func__); | 834 | |
792 | return U14ERR_NOERROR; | 835 | if (dwLen == 0) // allow 0-len read or write; just return success |
793 | } | 836 | { |
794 | 837 | dev_dbg(&pdx->interface->dev, | |
795 | if ((pArea->bCircular) && // Circular transfer? | 838 | "%s OK; zero-len read/write request", __func__); |
796 | (pArea->bCircToHost) && (Read)) // In a supported direction | 839 | return U14ERR_NOERROR; |
797 | { // If so, we sort out offset ourself | 840 | } |
798 | bool bWait = false; // Flag for transfer having to wait | 841 | |
799 | 842 | if ((pArea->bCircular) && // Circular transfer? | |
800 | dev_dbg(&pdx->interface->dev, "Circular buffers are %d at %d and %d at %d", | 843 | (pArea->bCircToHost) && (Read)) // In a supported direction |
801 | pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset, pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset); | 844 | { // If so, we sort out offset ourself |
802 | if (pArea->aBlocks[1].dwSize > 0) // Using the second block already? | 845 | bool bWait = false; // Flag for transfer having to wait |
803 | { | 846 | |
804 | dwOffs = pArea->aBlocks[1].dwOffset + pArea->aBlocks[1].dwSize; // take offset from that | 847 | dev_dbg(&pdx->interface->dev, |
805 | bWait = (dwOffs + dwLen) > pArea->aBlocks[0].dwOffset; // Wait if will overwrite block 0? | 848 | "Circular buffers are %d at %d and %d at %d", |
806 | bWait |= (dwOffs + dwLen) > pArea->dwLength; // or if it overflows the buffer | 849 | pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset, |
807 | } | 850 | pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset); |
808 | else // Area 1 not in use, try to use area 0 | 851 | if (pArea->aBlocks[1].dwSize > 0) // Using the second block already? |
809 | { | 852 | { |
810 | if (pArea->aBlocks[0].dwSize == 0) // Reset block 0 if not in use | 853 | dwOffs = pArea->aBlocks[1].dwOffset + pArea->aBlocks[1].dwSize; // take offset from that |
811 | pArea->aBlocks[0].dwOffset = 0; | 854 | bWait = (dwOffs + dwLen) > pArea->aBlocks[0].dwOffset; // Wait if will overwrite block 0? |
812 | dwOffs = pArea->aBlocks[0].dwOffset + pArea->aBlocks[0].dwSize; | 855 | bWait |= (dwOffs + dwLen) > pArea->dwLength; // or if it overflows the buffer |
813 | if ((dwOffs+dwLen) > pArea->dwLength) // Off the end of the buffer? | 856 | } else // Area 1 not in use, try to use area 0 |
814 | { | 857 | { |
815 | pArea->aBlocks[1].dwOffset = 0; // Set up to use second block | 858 | if (pArea->aBlocks[0].dwSize == 0) // Reset block 0 if not in use |
816 | dwOffs = 0; | 859 | pArea->aBlocks[0].dwOffset = 0; |
817 | bWait = (dwOffs + dwLen) > pArea->aBlocks[0].dwOffset; // Wait if will overwrite block 0? | 860 | dwOffs = |
818 | bWait |= (dwOffs + dwLen) > pArea->dwLength; // or if it overflows the buffer | 861 | pArea->aBlocks[0].dwOffset + |
819 | } | 862 | pArea->aBlocks[0].dwSize; |
820 | } | 863 | if ((dwOffs + dwLen) > pArea->dwLength) // Off the end of the buffer? |
821 | 864 | { | |
822 | if (bWait) // This transfer will have to wait? | 865 | pArea->aBlocks[1].dwOffset = 0; // Set up to use second block |
823 | { | 866 | dwOffs = 0; |
824 | pdx->bXFerWaiting = true; // Flag we are waiting | 867 | bWait = (dwOffs + dwLen) > pArea->aBlocks[0].dwOffset; // Wait if will overwrite block 0? |
825 | dev_dbg(&pdx->interface->dev, "%s xfer waiting for circular buffer space", __func__); | 868 | bWait |= (dwOffs + dwLen) > pArea->dwLength; // or if it overflows the buffer |
826 | return U14ERR_NOERROR; | 869 | } |
827 | } | 870 | } |
828 | 871 | ||
829 | dev_dbg(&pdx->interface->dev, "%s circular xfer, %d bytes starting at %d", __func__, dwLen, dwOffs); | 872 | if (bWait) // This transfer will have to wait? |
830 | } | 873 | { |
831 | 874 | pdx->bXFerWaiting = true; // Flag we are waiting | |
832 | // Save the parameters for the read\write transfer | 875 | dev_dbg(&pdx->interface->dev, |
833 | pdx->StagedRead = Read; // Save the parameters for this read | 876 | "%s xfer waiting for circular buffer space", |
834 | pdx->StagedId = wIdent; // ID allows us to get transfer area info | 877 | __func__); |
835 | pdx->StagedOffset = dwOffs; // The area within the transfer area | 878 | return U14ERR_NOERROR; |
836 | pdx->StagedLength = dwLen; | 879 | } |
837 | pdx->StagedDone = 0; // Initialise the byte count | 880 | |
838 | pdx->dwDMAFlag = MODE_LINEAR; // Set DMA mode flag at this point | 881 | dev_dbg(&pdx->interface->dev, |
839 | pdx->bXFerWaiting = false; // Clearly not a transfer waiting now | 882 | "%s circular xfer, %d bytes starting at %d", __func__, |
883 | dwLen, dwOffs); | ||
884 | } | ||
885 | // Save the parameters for the read\write transfer | ||
886 | pdx->StagedRead = Read; // Save the parameters for this read | ||
887 | pdx->StagedId = wIdent; // ID allows us to get transfer area info | ||
888 | pdx->StagedOffset = dwOffs; // The area within the transfer area | ||
889 | pdx->StagedLength = dwLen; | ||
890 | pdx->StagedDone = 0; // Initialise the byte count | ||
891 | pdx->dwDMAFlag = MODE_LINEAR; // Set DMA mode flag at this point | ||
892 | pdx->bXFerWaiting = false; // Clearly not a transfer waiting now | ||
840 | 893 | ||
841 | // KeClearEvent(&pdx->StagingDoneEvent); // Clear the transfer done event | 894 | // KeClearEvent(&pdx->StagingDoneEvent); // Clear the transfer done event |
842 | StageChunk(pdx); // fire off the first chunk | 895 | StageChunk(pdx); // fire off the first chunk |
843 | 896 | ||
844 | return U14ERR_NOERROR; | 897 | return U14ERR_NOERROR; |
845 | } | 898 | } |
846 | 899 | ||
847 | /**************************************************************************** | 900 | /**************************************************************************** |
@@ -852,20 +905,21 @@ int ReadWriteMem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent, | |||
852 | ** data we return FALSE. Used as part of decoding a DMA request. | 905 | ** data we return FALSE. Used as part of decoding a DMA request. |
853 | ** | 906 | ** |
854 | ****************************************************************************/ | 907 | ****************************************************************************/ |
855 | static bool ReadChar(unsigned char* pChar, char* pBuf, unsigned int* pdDone, unsigned int dGot) | 908 | static bool ReadChar(unsigned char *pChar, char *pBuf, unsigned int *pdDone, |
909 | unsigned int dGot) | ||
856 | { | 910 | { |
857 | bool bRead = false; | 911 | bool bRead = false; |
858 | unsigned int dDone = *pdDone; | 912 | unsigned int dDone = *pdDone; |
859 | 913 | ||
860 | if (dDone < dGot) // If there is more data | 914 | if (dDone < dGot) // If there is more data |
861 | { | 915 | { |
862 | *pChar = (unsigned char)pBuf[dDone];// Extract the next char | 916 | *pChar = (unsigned char)pBuf[dDone]; // Extract the next char |
863 | dDone++; // Increment the done count | 917 | dDone++; // Increment the done count |
864 | *pdDone = dDone; | 918 | *pdDone = dDone; |
865 | bRead = true; // and flag success | 919 | bRead = true; // and flag success |
866 | } | 920 | } |
867 | 921 | ||
868 | return bRead; | 922 | return bRead; |
869 | } | 923 | } |
870 | 924 | ||
871 | #ifdef NOTUSED | 925 | #ifdef NOTUSED |
@@ -876,12 +930,14 @@ static bool ReadChar(unsigned char* pChar, char* pBuf, unsigned int* pdDone, uns | |||
876 | ** Reads a word from the 1401, just uses ReadChar twice; passes on any error | 930 | ** Reads a word from the 1401, just uses ReadChar twice; passes on any error |
877 | ** | 931 | ** |
878 | *****************************************************************************/ | 932 | *****************************************************************************/ |
879 | static bool ReadWord(unsigned short* pWord, char* pBuf, unsigned int* pdDone, unsigned int dGot) | 933 | static bool ReadWord(unsigned short *pWord, char *pBuf, unsigned int *pdDone, |
934 | unsigned int dGot) | ||
880 | { | 935 | { |
881 | if (ReadChar((unsigned char*)pWord, pBuf, pdDone, dGot)) | 936 | if (ReadChar((unsigned char *)pWord, pBuf, pdDone, dGot)) |
882 | return ReadChar(((unsigned char*)pWord)+1, pBuf, pdDone, dGot); | 937 | return ReadChar(((unsigned char *)pWord) + 1, pBuf, pdDone, |
883 | else | 938 | dGot); |
884 | return false; | 939 | else |
940 | return false; | ||
885 | } | 941 | } |
886 | #endif | 942 | #endif |
887 | 943 | ||
@@ -895,39 +951,35 @@ static bool ReadWord(unsigned short* pWord, char* pBuf, unsigned int* pdDone, un | |||
895 | ** to indicate three byte total. | 951 | ** to indicate three byte total. |
896 | ** | 952 | ** |
897 | *****************************************************************************/ | 953 | *****************************************************************************/ |
898 | static bool ReadHuff(volatile unsigned int* pDWord, char* pBuf, unsigned int* pdDone, unsigned int dGot) | 954 | static bool ReadHuff(volatile unsigned int *pDWord, char *pBuf, |
955 | unsigned int *pdDone, unsigned int dGot) | ||
899 | { | 956 | { |
900 | unsigned char ucData; /* for each read to ReadChar */ | 957 | unsigned char ucData; /* for each read to ReadChar */ |
901 | bool bReturn = true; /* assume we will succeed */ | 958 | bool bReturn = true; /* assume we will succeed */ |
902 | unsigned int dwData = 0; /* Accumulator for the data */ | 959 | unsigned int dwData = 0; /* Accumulator for the data */ |
903 | 960 | ||
904 | if (ReadChar(&ucData, pBuf, pdDone, dGot)) | 961 | if (ReadChar(&ucData, pBuf, pdDone, dGot)) { |
905 | { | 962 | dwData = ucData; /* copy the data */ |
906 | dwData = ucData; /* copy the data */ | 963 | if ((dwData & 0x00000080) != 0) { /* Bit set for more data ? */ |
907 | if ((dwData & 0x00000080) != 0) /* Bit set for more data ? */ | 964 | dwData &= 0x0000007F; /* Clear the relevant bit */ |
908 | { | 965 | if (ReadChar(&ucData, pBuf, pdDone, dGot)) { |
909 | dwData &= 0x0000007F; /* Clear the relevant bit */ | 966 | dwData = (dwData << 8) | ucData; |
910 | if (ReadChar(&ucData, pBuf, pdDone, dGot)) | 967 | if ((dwData & 0x00004000) != 0) { /* three byte sequence ? */ |
911 | { | 968 | dwData &= 0x00003FFF; /* Clear the relevant bit */ |
912 | dwData = (dwData << 8) | ucData; | 969 | if (ReadChar |
913 | if ((dwData & 0x00004000) != 0) /* three byte sequence ? */ | 970 | (&ucData, pBuf, pdDone, dGot)) |
914 | { | 971 | dwData = (dwData << 8) | ucData; |
915 | dwData &= 0x00003FFF; /* Clear the relevant bit */ | 972 | else |
916 | if (ReadChar(&ucData, pBuf, pdDone, dGot)) | 973 | bReturn = false; |
917 | dwData = (dwData << 8) | ucData; | 974 | } |
918 | else | 975 | } else |
919 | bReturn = false; | 976 | bReturn = false; /* couldn't read data */ |
920 | } | 977 | } |
921 | } | 978 | } else |
922 | else | 979 | bReturn = false; |
923 | bReturn = false; /* couldn't read data */ | 980 | |
924 | } | 981 | *pDWord = dwData; /* return the data */ |
925 | } | 982 | return bReturn; |
926 | else | ||
927 | bReturn = false; | ||
928 | |||
929 | *pDWord = dwData; /* return the data */ | ||
930 | return bReturn; | ||
931 | } | 983 | } |
932 | 984 | ||
933 | /*************************************************************************** | 985 | /*************************************************************************** |
@@ -944,66 +996,77 @@ static bool ReadHuff(volatile unsigned int* pDWord, char* pBuf, unsigned int* pd | |||
944 | ** we start handling the data at offset zero. | 996 | ** we start handling the data at offset zero. |
945 | ** | 997 | ** |
946 | *****************************************************************************/ | 998 | *****************************************************************************/ |
947 | static bool ReadDMAInfo(volatile DMADESC* pDmaDesc, DEVICE_EXTENSION *pdx, | 999 | static bool ReadDMAInfo(volatile DMADESC * pDmaDesc, DEVICE_EXTENSION * pdx, |
948 | char* pBuf, unsigned int dwCount) | 1000 | char *pBuf, unsigned int dwCount) |
949 | { | 1001 | { |
950 | bool bResult = false; // assume we won't succeed | 1002 | bool bResult = false; // assume we won't succeed |
951 | unsigned char ucData; | 1003 | unsigned char ucData; |
952 | unsigned int dDone = 0; // We haven't parsed anything so far | 1004 | unsigned int dDone = 0; // We haven't parsed anything so far |
953 | 1005 | ||
954 | dev_dbg(&pdx->interface->dev, "%s", __func__); | 1006 | dev_dbg(&pdx->interface->dev, "%s", __func__); |
955 | 1007 | ||
956 | if (ReadChar(&ucData, pBuf, &dDone, dwCount)) | 1008 | if (ReadChar(&ucData, pBuf, &dDone, dwCount)) { |
957 | { | 1009 | unsigned char ucTransCode = (ucData & 0x0F); // get code for transfer type |
958 | unsigned char ucTransCode = (ucData & 0x0F); // get code for transfer type | 1010 | unsigned short wIdent = ((ucData >> 4) & 0x07); // and area identifier |
959 | unsigned short wIdent = ((ucData >> 4) & 0x07); // and area identifier | 1011 | |
960 | 1012 | // fill in the structure we were given | |
961 | // fill in the structure we were given | 1013 | pDmaDesc->wTransType = ucTransCode; // type of transfer |
962 | pDmaDesc->wTransType = ucTransCode; // type of transfer | 1014 | pDmaDesc->wIdent = wIdent; // area to use |
963 | pDmaDesc->wIdent = wIdent; // area to use | 1015 | pDmaDesc->dwSize = 0; // initialise other bits |
964 | pDmaDesc->dwSize = 0; // initialise other bits | 1016 | pDmaDesc->dwOffset = 0; |
965 | pDmaDesc->dwOffset = 0; | 1017 | |
966 | 1018 | dev_dbg(&pdx->interface->dev, "%s type: %d ident: %d", __func__, | |
967 | dev_dbg(&pdx->interface->dev, "%s type: %d ident: %d", __func__, pDmaDesc->wTransType, pDmaDesc->wIdent); | 1019 | pDmaDesc->wTransType, pDmaDesc->wIdent); |
968 | 1020 | ||
969 | pDmaDesc->bOutWard = (ucTransCode != TM_EXTTOHOST); // set transfer direction | 1021 | pDmaDesc->bOutWard = (ucTransCode != TM_EXTTOHOST); // set transfer direction |
970 | 1022 | ||
971 | switch (ucTransCode) | 1023 | switch (ucTransCode) { |
972 | { | 1024 | case TM_EXTTOHOST: // Extended linear transfer modes (the only ones!) |
973 | case TM_EXTTOHOST: // Extended linear transfer modes (the only ones!) | 1025 | case TM_EXTTO1401: |
974 | case TM_EXTTO1401: | 1026 | { |
975 | { | 1027 | bResult = |
976 | bResult = ReadHuff(&(pDmaDesc->dwOffset), pBuf, &dDone, dwCount) && | 1028 | ReadHuff(&(pDmaDesc->dwOffset), pBuf, |
977 | ReadHuff(&(pDmaDesc->dwSize), pBuf, &dDone, dwCount); | 1029 | &dDone, dwCount) |
978 | if (bResult) | 1030 | && ReadHuff(&(pDmaDesc->dwSize), pBuf, |
979 | { | 1031 | &dDone, dwCount); |
980 | dev_dbg(&pdx->interface->dev, "%s xfer offset & size %d %d", | 1032 | if (bResult) { |
981 | __func__, pDmaDesc->dwOffset, pDmaDesc->dwSize); | 1033 | dev_dbg(&pdx->interface->dev, |
982 | 1034 | "%s xfer offset & size %d %d", | |
983 | if ((wIdent >= MAX_TRANSAREAS) || // Illegal area number, or... | 1035 | __func__, pDmaDesc->dwOffset, |
984 | (!pdx->rTransDef[wIdent].bUsed) || // area not set up, or... | 1036 | pDmaDesc->dwSize); |
985 | (pDmaDesc->dwOffset > pdx->rTransDef[wIdent].dwLength) || // range/size | 1037 | |
986 | ((pDmaDesc->dwOffset + pDmaDesc->dwSize) > (pdx->rTransDef[wIdent].dwLength))) | 1038 | if ((wIdent >= MAX_TRANSAREAS) || // Illegal area number, or... |
987 | { | 1039 | (!pdx->rTransDef[wIdent].bUsed) || // area not set up, or... |
988 | bResult = false; // bad parameter(s) | 1040 | (pDmaDesc->dwOffset > pdx->rTransDef[wIdent].dwLength) || // range/size |
989 | dev_dbg(&pdx->interface->dev, "%s bad param - id %d, bUsed %d, offset %d, size %d, area length %d", | 1041 | ((pDmaDesc->dwOffset + |
990 | __func__, wIdent, pdx->rTransDef[wIdent].bUsed, pDmaDesc->dwOffset, pDmaDesc->dwSize, | 1042 | pDmaDesc->dwSize) > |
991 | pdx->rTransDef[wIdent].dwLength); | 1043 | (pdx->rTransDef[wIdent]. |
992 | } | 1044 | dwLength))) { |
993 | } | 1045 | bResult = false; // bad parameter(s) |
994 | break; | 1046 | dev_dbg(&pdx->interface->dev, |
995 | } | 1047 | "%s bad param - id %d, bUsed %d, offset %d, size %d, area length %d", |
996 | default: | 1048 | __func__, wIdent, |
997 | break; | 1049 | pdx->rTransDef[wIdent]. |
998 | } | 1050 | bUsed, |
999 | } | 1051 | pDmaDesc->dwOffset, |
1000 | else | 1052 | pDmaDesc->dwSize, |
1001 | bResult = false; | 1053 | pdx->rTransDef[wIdent]. |
1002 | 1054 | dwLength); | |
1003 | if (!bResult) // now check parameters for validity | 1055 | } |
1004 | dev_err(&pdx->interface->dev, "%s error reading Esc sequence", __func__); | 1056 | } |
1005 | 1057 | break; | |
1006 | return bResult; | 1058 | } |
1059 | default: | ||
1060 | break; | ||
1061 | } | ||
1062 | } else | ||
1063 | bResult = false; | ||
1064 | |||
1065 | if (!bResult) // now check parameters for validity | ||
1066 | dev_err(&pdx->interface->dev, "%s error reading Esc sequence", | ||
1067 | __func__); | ||
1068 | |||
1069 | return bResult; | ||
1007 | } | 1070 | } |
1008 | 1071 | ||
1009 | /**************************************************************************** | 1072 | /**************************************************************************** |
@@ -1020,122 +1083,130 @@ static bool ReadDMAInfo(volatile DMADESC* pDmaDesc, DEVICE_EXTENSION *pdx, | |||
1020 | ** this is known to be at least 2 or we will not be called. | 1083 | ** this is known to be at least 2 or we will not be called. |
1021 | ** | 1084 | ** |
1022 | ****************************************************************************/ | 1085 | ****************************************************************************/ |
1023 | static int Handle1401Esc(DEVICE_EXTENSION* pdx, char* pCh, unsigned int dwCount) | 1086 | static int Handle1401Esc(DEVICE_EXTENSION * pdx, char *pCh, |
1087 | unsigned int dwCount) | ||
1024 | { | 1088 | { |
1025 | int iReturn = U14ERR_FAIL; | 1089 | int iReturn = U14ERR_FAIL; |
1026 | 1090 | ||
1027 | // I have no idea what this next test is about. '?' is 0x3f, which is area 3, code | 1091 | // I have no idea what this next test is about. '?' is 0x3f, which is area 3, code |
1028 | // 15. At the moment, this is not used, so it does no harm, but unless someone can | 1092 | // 15. At the moment, this is not used, so it does no harm, but unless someone can |
1029 | // tell me what this is for, it should be removed from this and the Windows driver. | 1093 | // tell me what this is for, it should be removed from this and the Windows driver. |
1030 | if (pCh[0] == '?') // Is this an information response | 1094 | if (pCh[0] == '?') // Is this an information response |
1031 | { // Parse and save the information | 1095 | { // Parse and save the information |
1032 | } | 1096 | } else { |
1033 | else | 1097 | spin_lock(&pdx->stagedLock); // Lock others out |
1034 | { | 1098 | |
1035 | spin_lock(&pdx->stagedLock); // Lock others out | 1099 | if (ReadDMAInfo(&pdx->rDMAInfo, pdx, pCh, dwCount)) // Get DMA parameters |
1036 | 1100 | { | |
1037 | if (ReadDMAInfo(&pdx->rDMAInfo, pdx, pCh, dwCount)) // Get DMA parameters | 1101 | unsigned short wTransType = pdx->rDMAInfo.wTransType; // check transfer type |
1038 | { | 1102 | |
1039 | unsigned short wTransType = pdx->rDMAInfo.wTransType; // check transfer type | 1103 | dev_dbg(&pdx->interface->dev, |
1040 | 1104 | "%s xfer to %s, offset %d, length %d", __func__, | |
1041 | dev_dbg(&pdx->interface->dev, "%s xfer to %s, offset %d, length %d", __func__, | 1105 | pdx->rDMAInfo.bOutWard ? "1401" : "host", |
1042 | pdx->rDMAInfo.bOutWard ? "1401" : "host", | 1106 | pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize); |
1043 | pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize); | 1107 | |
1044 | 1108 | if (pdx->bXFerWaiting) // Check here for badly out of kilter... | |
1045 | if (pdx->bXFerWaiting) // Check here for badly out of kilter... | 1109 | { // This can never happen, really |
1046 | { // This can never happen, really | 1110 | dev_err(&pdx->interface->dev, |
1047 | dev_err(&pdx->interface->dev, "ERROR: DMA setup while transfer still waiting"); | 1111 | "ERROR: DMA setup while transfer still waiting"); |
1048 | spin_unlock(&pdx->stagedLock); | 1112 | spin_unlock(&pdx->stagedLock); |
1049 | } | 1113 | } else { |
1050 | else | 1114 | if ((wTransType == TM_EXTTOHOST) |
1051 | { | 1115 | || (wTransType == TM_EXTTO1401)) { |
1052 | if ((wTransType == TM_EXTTOHOST) || (wTransType == TM_EXTTO1401)) | 1116 | iReturn = |
1053 | { | 1117 | ReadWriteMem(pdx, |
1054 | iReturn = ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard, pdx->rDMAInfo.wIdent, pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize); | 1118 | !pdx->rDMAInfo. |
1055 | if (iReturn != U14ERR_NOERROR) | 1119 | bOutWard, |
1056 | dev_err(&pdx->interface->dev, "%s ReadWriteMem() failed %d", __func__, iReturn); | 1120 | pdx->rDMAInfo.wIdent, |
1057 | } | 1121 | pdx->rDMAInfo.dwOffset, |
1058 | else // This covers non-linear transfer setup | 1122 | pdx->rDMAInfo.dwSize); |
1059 | dev_err(&pdx->interface->dev, "%s Unknown block xfer type %d", __func__, wTransType); | 1123 | if (iReturn != U14ERR_NOERROR) |
1060 | } | 1124 | dev_err(&pdx->interface->dev, |
1061 | } | 1125 | "%s ReadWriteMem() failed %d", |
1062 | else // Failed to read parameters | 1126 | __func__, iReturn); |
1063 | dev_err(&pdx->interface->dev, "%s ReadDMAInfo() fail", __func__); | 1127 | } else // This covers non-linear transfer setup |
1064 | 1128 | dev_err(&pdx->interface->dev, | |
1065 | spin_unlock(&pdx->stagedLock); // OK here | 1129 | "%s Unknown block xfer type %d", |
1066 | } | 1130 | __func__, wTransType); |
1067 | 1131 | } | |
1068 | dev_dbg(&pdx->interface->dev, "%s returns %d", __func__, iReturn); | 1132 | } else // Failed to read parameters |
1069 | 1133 | dev_err(&pdx->interface->dev, "%s ReadDMAInfo() fail", | |
1070 | return iReturn; | 1134 | __func__); |
1135 | |||
1136 | spin_unlock(&pdx->stagedLock); // OK here | ||
1137 | } | ||
1138 | |||
1139 | dev_dbg(&pdx->interface->dev, "%s returns %d", __func__, iReturn); | ||
1140 | |||
1141 | return iReturn; | ||
1071 | } | 1142 | } |
1072 | 1143 | ||
1073 | /**************************************************************************** | 1144 | /**************************************************************************** |
1074 | ** Callback for the character read complete or error | 1145 | ** Callback for the character read complete or error |
1075 | ****************************************************************************/ | 1146 | ****************************************************************************/ |
1076 | static void ced_readchar_callback(struct urb* pUrb) | 1147 | static void ced_readchar_callback(struct urb *pUrb) |
1077 | { | 1148 | { |
1078 | DEVICE_EXTENSION *pdx = pUrb->context; | 1149 | DEVICE_EXTENSION *pdx = pUrb->context; |
1079 | int nGot = pUrb->actual_length; // what we transferred | 1150 | int nGot = pUrb->actual_length; // what we transferred |
1080 | 1151 | ||
1081 | if (pUrb->status) // Do we have a problem to handle? | 1152 | if (pUrb->status) // Do we have a problem to handle? |
1082 | { | 1153 | { |
1083 | int nPipe = pdx->nPipes == 4 ? 1 : 0; // The pipe number to use for error | 1154 | int nPipe = pdx->nPipes == 4 ? 1 : 0; // The pipe number to use for error |
1084 | // sync/async unlink faults aren't errors... just saying device removed or stopped | 1155 | // sync/async unlink faults aren't errors... just saying device removed or stopped |
1085 | if (!(pUrb->status == -ENOENT || pUrb->status == -ECONNRESET || pUrb->status == -ESHUTDOWN)) | 1156 | if (! |
1086 | { | 1157 | (pUrb->status == -ENOENT || pUrb->status == -ECONNRESET |
1087 | dev_err(&pdx->interface->dev, "%s - nonzero write bulk status received: %d", __func__, pUrb->status); | 1158 | || pUrb->status == -ESHUTDOWN)) { |
1088 | } | 1159 | dev_err(&pdx->interface->dev, |
1089 | else | 1160 | "%s - nonzero write bulk status received: %d", |
1090 | dev_dbg(&pdx->interface->dev, "%s - 0 chars pUrb->status=%d (shutdown?)", __func__, pUrb->status); | 1161 | __func__, pUrb->status); |
1091 | 1162 | } else | |
1092 | spin_lock(&pdx->err_lock); | 1163 | dev_dbg(&pdx->interface->dev, |
1093 | pdx->errors = pUrb->status; | 1164 | "%s - 0 chars pUrb->status=%d (shutdown?)", |
1094 | spin_unlock(&pdx->err_lock); | 1165 | __func__, pUrb->status); |
1095 | nGot = 0; // and tidy up again if so | 1166 | |
1096 | 1167 | spin_lock(&pdx->err_lock); | |
1097 | spin_lock(&pdx->charInLock); // already at irq level | 1168 | pdx->errors = pUrb->status; |
1098 | pdx->bPipeError[nPipe] = 1; // Flag an error for later | 1169 | spin_unlock(&pdx->err_lock); |
1099 | } | 1170 | nGot = 0; // and tidy up again if so |
1100 | else | 1171 | |
1101 | { | 1172 | spin_lock(&pdx->charInLock); // already at irq level |
1102 | if ((nGot > 1) && ((pdx->pCoherCharIn[0] & 0x7f) == 0x1b)) // Esc sequence? | 1173 | pdx->bPipeError[nPipe] = 1; // Flag an error for later |
1103 | { | 1174 | } else { |
1104 | Handle1401Esc(pdx, &pdx->pCoherCharIn[1], nGot-1); // handle it | 1175 | if ((nGot > 1) && ((pdx->pCoherCharIn[0] & 0x7f) == 0x1b)) // Esc sequence? |
1105 | spin_lock(&pdx->charInLock); // already at irq level | 1176 | { |
1106 | } | 1177 | Handle1401Esc(pdx, &pdx->pCoherCharIn[1], nGot - 1); // handle it |
1107 | else | 1178 | spin_lock(&pdx->charInLock); // already at irq level |
1108 | { | 1179 | } else { |
1109 | spin_lock(&pdx->charInLock); // already at irq level | 1180 | spin_lock(&pdx->charInLock); // already at irq level |
1110 | if (nGot > 0) | 1181 | if (nGot > 0) { |
1111 | { | 1182 | unsigned int i; |
1112 | unsigned int i; | 1183 | if (nGot < INBUF_SZ) { |
1113 | if (nGot < INBUF_SZ) | 1184 | pdx->pCoherCharIn[nGot] = 0; // tidy the string |
1114 | { | 1185 | dev_dbg(&pdx->interface->dev, |
1115 | pdx->pCoherCharIn[nGot] = 0; // tidy the string | 1186 | "%s got %d chars >%s<", |
1116 | dev_dbg(&pdx->interface->dev, "%s got %d chars >%s<", __func__, nGot, pdx->pCoherCharIn); | 1187 | __func__, nGot, |
1117 | } | 1188 | pdx->pCoherCharIn); |
1118 | 1189 | } | |
1119 | // We know that whatever we read must fit in the input buffer | 1190 | // We know that whatever we read must fit in the input buffer |
1120 | for (i = 0; i < nGot; i++) | 1191 | for (i = 0; i < nGot; i++) { |
1121 | { | 1192 | pdx->inputBuffer[pdx->dwInBuffPut++] = |
1122 | pdx->inputBuffer[pdx->dwInBuffPut++] = pdx->pCoherCharIn[i] & 0x7F; | 1193 | pdx->pCoherCharIn[i] & 0x7F; |
1123 | if (pdx->dwInBuffPut >= INBUF_SZ) | 1194 | if (pdx->dwInBuffPut >= INBUF_SZ) |
1124 | pdx->dwInBuffPut = 0; | 1195 | pdx->dwInBuffPut = 0; |
1125 | } | 1196 | } |
1126 | 1197 | ||
1127 | if ((pdx->dwNumInput + nGot) <= INBUF_SZ) | 1198 | if ((pdx->dwNumInput + nGot) <= INBUF_SZ) |
1128 | pdx->dwNumInput += nGot; // Adjust the buffer count accordingly | 1199 | pdx->dwNumInput += nGot; // Adjust the buffer count accordingly |
1129 | } | 1200 | } else |
1130 | else | 1201 | dev_dbg(&pdx->interface->dev, "%s read ZLP", |
1131 | dev_dbg(&pdx->interface->dev, "%s read ZLP", __func__); | 1202 | __func__); |
1132 | } | 1203 | } |
1133 | } | 1204 | } |
1134 | 1205 | ||
1135 | pdx->bReadCharsPending = false; // No longer have a pending read | 1206 | pdx->bReadCharsPending = false; // No longer have a pending read |
1136 | spin_unlock(&pdx->charInLock); // already at irq level | 1207 | spin_unlock(&pdx->charInLock); // already at irq level |
1137 | 1208 | ||
1138 | Allowi(pdx, true); // see if we can do the next one | 1209 | Allowi(pdx, true); // see if we can do the next one |
1139 | } | 1210 | } |
1140 | 1211 | ||
1141 | /**************************************************************************** | 1212 | /**************************************************************************** |
@@ -1145,48 +1216,50 @@ static void ced_readchar_callback(struct urb* pUrb) | |||
1145 | ** we can pick up any inward transfers. This can be called in multiple contexts | 1216 | ** we can pick up any inward transfers. This can be called in multiple contexts |
1146 | ** so we use the irqsave version of the spinlock. | 1217 | ** so we use the irqsave version of the spinlock. |
1147 | ****************************************************************************/ | 1218 | ****************************************************************************/ |
1148 | int Allowi(DEVICE_EXTENSION* pdx, bool bInCallback) | 1219 | int Allowi(DEVICE_EXTENSION * pdx, bool bInCallback) |
1149 | { | 1220 | { |
1150 | int iReturn = U14ERR_NOERROR; | 1221 | int iReturn = U14ERR_NOERROR; |
1151 | unsigned long flags; | 1222 | unsigned long flags; |
1152 | spin_lock_irqsave(&pdx->charInLock, flags); // can be called in multiple contexts | 1223 | spin_lock_irqsave(&pdx->charInLock, flags); // can be called in multiple contexts |
1153 | 1224 | ||
1154 | // We don't want char input running while DMA is in progress as we know that this | 1225 | // We don't want char input running while DMA is in progress as we know that this |
1155 | // can cause sequencing problems for the 2270. So don't. It will also allow the | 1226 | // can cause sequencing problems for the 2270. So don't. It will also allow the |
1156 | // ERR response to get back to the host code too early on some PCs, even if there | 1227 | // ERR response to get back to the host code too early on some PCs, even if there |
1157 | // is no actual driver failure, so we don't allow this at all. | 1228 | // is no actual driver failure, so we don't allow this at all. |
1158 | if (!pdx->bInDrawDown && // stop input if | 1229 | if (!pdx->bInDrawDown && // stop input if |
1159 | !pdx->bReadCharsPending && // If no read request outstanding | 1230 | !pdx->bReadCharsPending && // If no read request outstanding |
1160 | (pdx->dwNumInput < (INBUF_SZ/2)) && // and there is some space | 1231 | (pdx->dwNumInput < (INBUF_SZ / 2)) && // and there is some space |
1161 | (pdx->dwDMAFlag == MODE_CHAR) && // not doing any DMA | 1232 | (pdx->dwDMAFlag == MODE_CHAR) && // not doing any DMA |
1162 | (!pdx->bXFerWaiting) && // no xfer waiting to start | 1233 | (!pdx->bXFerWaiting) && // no xfer waiting to start |
1163 | (CanAcceptIoRequests(pdx))) // and activity is generally OK | 1234 | (CanAcceptIoRequests(pdx))) // and activity is generally OK |
1164 | { // then off we go | 1235 | { // then off we go |
1165 | unsigned int nMax = INBUF_SZ-pdx->dwNumInput; // max we could read | 1236 | unsigned int nMax = INBUF_SZ - pdx->dwNumInput; // max we could read |
1166 | int nPipe = pdx->nPipes == 4 ? 1 : 0; // The pipe number to use | 1237 | int nPipe = pdx->nPipes == 4 ? 1 : 0; // The pipe number to use |
1167 | 1238 | ||
1168 | dev_dbg(&pdx->interface->dev, "%s %d chars in input buffer", __func__, pdx->dwNumInput); | 1239 | dev_dbg(&pdx->interface->dev, "%s %d chars in input buffer", |
1169 | 1240 | __func__, pdx->dwNumInput); | |
1170 | usb_fill_int_urb(pdx->pUrbCharIn, pdx->udev, | 1241 | |
1171 | usb_rcvintpipe(pdx->udev, pdx->epAddr[nPipe]), | 1242 | usb_fill_int_urb(pdx->pUrbCharIn, pdx->udev, |
1172 | pdx->pCoherCharIn, nMax, ced_readchar_callback, | 1243 | usb_rcvintpipe(pdx->udev, pdx->epAddr[nPipe]), |
1173 | pdx, pdx->bInterval); | 1244 | pdx->pCoherCharIn, nMax, ced_readchar_callback, |
1174 | pdx->pUrbCharIn->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; // short xfers are OK by default | 1245 | pdx, pdx->bInterval); |
1175 | usb_anchor_urb(pdx->pUrbCharIn, &pdx->submitted); // in case we need to kill it | 1246 | pdx->pUrbCharIn->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; // short xfers are OK by default |
1176 | iReturn = usb_submit_urb(pdx->pUrbCharIn, bInCallback ? GFP_ATOMIC : GFP_KERNEL); | 1247 | usb_anchor_urb(pdx->pUrbCharIn, &pdx->submitted); // in case we need to kill it |
1177 | if (iReturn) | 1248 | iReturn = |
1178 | { | 1249 | usb_submit_urb(pdx->pUrbCharIn, |
1179 | usb_unanchor_urb(pdx->pUrbCharIn); // remove from list of active Urbs | 1250 | bInCallback ? GFP_ATOMIC : GFP_KERNEL); |
1180 | pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later | 1251 | if (iReturn) { |
1181 | dev_err(&pdx->interface->dev,"%s submit urb failed: %d", __func__, iReturn); | 1252 | usb_unanchor_urb(pdx->pUrbCharIn); // remove from list of active Urbs |
1182 | } | 1253 | pdx->bPipeError[nPipe] = 1; // Flag an error to be handled later |
1183 | else | 1254 | dev_err(&pdx->interface->dev, |
1184 | pdx->bReadCharsPending = true; // Flag that we are active here | 1255 | "%s submit urb failed: %d", __func__, iReturn); |
1185 | } | 1256 | } else |
1186 | 1257 | pdx->bReadCharsPending = true; // Flag that we are active here | |
1187 | spin_unlock_irqrestore(&pdx->charInLock, flags); | 1258 | } |
1188 | 1259 | ||
1189 | return iReturn; | 1260 | spin_unlock_irqrestore(&pdx->charInLock, flags); |
1261 | |||
1262 | return iReturn; | ||
1190 | 1263 | ||
1191 | } | 1264 | } |
1192 | 1265 | ||
@@ -1198,147 +1271,147 @@ int Allowi(DEVICE_EXTENSION* pdx, bool bInCallback) | |||
1198 | ** enough for a 64-bit pointer. | 1271 | ** enough for a 64-bit pointer. |
1199 | *****************************************************************************/ | 1272 | *****************************************************************************/ |
1200 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) | 1273 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) |
1201 | static long ced_ioctl(struct file * file, unsigned int cmd, unsigned long ulArg) | 1274 | static long ced_ioctl(struct file *file, unsigned int cmd, unsigned long ulArg) |
1202 | #else | 1275 | #else |
1203 | static int ced_ioctl(struct inode * node, struct file * file, unsigned int cmd, unsigned long ulArg) | 1276 | static int ced_ioctl(struct inode *node, struct file *file, unsigned int cmd, |
1277 | unsigned long ulArg) | ||
1204 | #endif | 1278 | #endif |
1205 | { | 1279 | { |
1206 | int err = 0; | 1280 | int err = 0; |
1207 | DEVICE_EXTENSION *pdx = file->private_data; | 1281 | DEVICE_EXTENSION *pdx = file->private_data; |
1208 | if (!CanAcceptIoRequests(pdx)) // check we still exist | 1282 | if (!CanAcceptIoRequests(pdx)) // check we still exist |
1209 | return -ENODEV; | 1283 | return -ENODEV; |
1210 | 1284 | ||
1211 | // Check that access is allowed, where is is needed. Anything that would have an indeterminate | 1285 | // Check that access is allowed, where is is needed. Anything that would have an indeterminate |
1212 | // size will be checked by the specific command. | 1286 | // size will be checked by the specific command. |
1213 | if (_IOC_DIR(cmd) & _IOC_READ) // read from point of view of user... | 1287 | if (_IOC_DIR(cmd) & _IOC_READ) // read from point of view of user... |
1214 | err = !access_ok(VERIFY_WRITE, (void __user *)ulArg, _IOC_SIZE(cmd)); // is kernel write | 1288 | err = !access_ok(VERIFY_WRITE, (void __user *)ulArg, _IOC_SIZE(cmd)); // is kernel write |
1215 | else if (_IOC_DIR(cmd) & _IOC_WRITE) // and write from point of view of user... | 1289 | else if (_IOC_DIR(cmd) & _IOC_WRITE) // and write from point of view of user... |
1216 | err = !access_ok(VERIFY_READ, (void __user *)ulArg, _IOC_SIZE(cmd)); // is kernel read | 1290 | err = !access_ok(VERIFY_READ, (void __user *)ulArg, _IOC_SIZE(cmd)); // is kernel read |
1217 | if (err) | 1291 | if (err) |
1218 | return -EFAULT; | 1292 | return -EFAULT; |
1219 | 1293 | ||
1220 | switch (_IOC_NR(cmd)) | 1294 | switch (_IOC_NR(cmd)) { |
1221 | { | 1295 | case _IOC_NR(IOCTL_CED_SENDSTRING(0)): |
1222 | case _IOC_NR(IOCTL_CED_SENDSTRING(0)): | 1296 | return SendString(pdx, (const char __user *)ulArg, |
1223 | return SendString(pdx, (const char __user*)ulArg, _IOC_SIZE(cmd)); | 1297 | _IOC_SIZE(cmd)); |
1224 | 1298 | ||
1225 | case _IOC_NR(IOCTL_CED_RESET1401): | 1299 | case _IOC_NR(IOCTL_CED_RESET1401): |
1226 | return Reset1401(pdx); | 1300 | return Reset1401(pdx); |
1227 | 1301 | ||
1228 | case _IOC_NR(IOCTL_CED_GETCHAR): | 1302 | case _IOC_NR(IOCTL_CED_GETCHAR): |
1229 | return GetChar(pdx); | 1303 | return GetChar(pdx); |
1230 | 1304 | ||
1231 | case _IOC_NR(IOCTL_CED_SENDCHAR): | 1305 | case _IOC_NR(IOCTL_CED_SENDCHAR): |
1232 | return SendChar(pdx, (char)ulArg); | 1306 | return SendChar(pdx, (char)ulArg); |
1233 | 1307 | ||
1234 | case _IOC_NR(IOCTL_CED_STAT1401): | 1308 | case _IOC_NR(IOCTL_CED_STAT1401): |
1235 | return Stat1401(pdx); | 1309 | return Stat1401(pdx); |
1236 | 1310 | ||
1237 | case _IOC_NR(IOCTL_CED_LINECOUNT): | 1311 | case _IOC_NR(IOCTL_CED_LINECOUNT): |
1238 | return LineCount(pdx); | 1312 | return LineCount(pdx); |
1239 | 1313 | ||
1240 | case _IOC_NR(IOCTL_CED_GETSTRING(0)): | 1314 | case _IOC_NR(IOCTL_CED_GETSTRING(0)): |
1241 | return GetString(pdx, (char __user*)ulArg, _IOC_SIZE(cmd)); | 1315 | return GetString(pdx, (char __user *)ulArg, _IOC_SIZE(cmd)); |
1242 | 1316 | ||
1243 | case _IOC_NR(IOCTL_CED_SETTRANSFER): | 1317 | case _IOC_NR(IOCTL_CED_SETTRANSFER): |
1244 | return SetTransfer(pdx, (TRANSFERDESC __user*)ulArg); | 1318 | return SetTransfer(pdx, (TRANSFERDESC __user *) ulArg); |
1245 | 1319 | ||
1246 | case _IOC_NR(IOCTL_CED_UNSETTRANSFER): | 1320 | case _IOC_NR(IOCTL_CED_UNSETTRANSFER): |
1247 | return UnsetTransfer(pdx, (int)ulArg); | 1321 | return UnsetTransfer(pdx, (int)ulArg); |
1248 | 1322 | ||
1249 | case _IOC_NR(IOCTL_CED_SETEVENT): | 1323 | case _IOC_NR(IOCTL_CED_SETEVENT): |
1250 | return SetEvent(pdx, (TRANSFEREVENT __user*)ulArg); | 1324 | return SetEvent(pdx, (TRANSFEREVENT __user *) ulArg); |
1251 | 1325 | ||
1252 | case _IOC_NR(IOCTL_CED_GETOUTBUFSPACE): | 1326 | case _IOC_NR(IOCTL_CED_GETOUTBUFSPACE): |
1253 | return GetOutBufSpace(pdx); | 1327 | return GetOutBufSpace(pdx); |
1254 | 1328 | ||
1255 | case _IOC_NR(IOCTL_CED_GETBASEADDRESS): | 1329 | case _IOC_NR(IOCTL_CED_GETBASEADDRESS): |
1256 | return -1; | 1330 | return -1; |
1257 | 1331 | ||
1258 | case _IOC_NR(IOCTL_CED_GETDRIVERREVISION): | 1332 | case _IOC_NR(IOCTL_CED_GETDRIVERREVISION): |
1259 | return (2<<24)|(DRIVERMAJREV<<16) | DRIVERMINREV; // USB | MAJOR | MINOR | 1333 | return (2 << 24) | (DRIVERMAJREV << 16) | DRIVERMINREV; // USB | MAJOR | MINOR |
1260 | 1334 | ||
1261 | case _IOC_NR(IOCTL_CED_GETTRANSFER): | 1335 | case _IOC_NR(IOCTL_CED_GETTRANSFER): |
1262 | return GetTransfer(pdx, (TGET_TX_BLOCK __user*)ulArg); | 1336 | return GetTransfer(pdx, (TGET_TX_BLOCK __user *) ulArg); |
1263 | 1337 | ||
1264 | case _IOC_NR(IOCTL_CED_KILLIO1401): | 1338 | case _IOC_NR(IOCTL_CED_KILLIO1401): |
1265 | return KillIO1401(pdx); | 1339 | return KillIO1401(pdx); |
1266 | 1340 | ||
1267 | case _IOC_NR(IOCTL_CED_STATEOF1401): | 1341 | case _IOC_NR(IOCTL_CED_STATEOF1401): |
1268 | return StateOf1401(pdx); | 1342 | return StateOf1401(pdx); |
1269 | 1343 | ||
1270 | case _IOC_NR(IOCTL_CED_GRAB1401): | 1344 | case _IOC_NR(IOCTL_CED_GRAB1401): |
1271 | case _IOC_NR(IOCTL_CED_FREE1401): | 1345 | case _IOC_NR(IOCTL_CED_FREE1401): |
1272 | return U14ERR_NOERROR; | 1346 | return U14ERR_NOERROR; |
1273 | 1347 | ||
1274 | case _IOC_NR(IOCTL_CED_STARTSELFTEST): | 1348 | case _IOC_NR(IOCTL_CED_STARTSELFTEST): |
1275 | return StartSelfTest(pdx); | 1349 | return StartSelfTest(pdx); |
1276 | 1350 | ||
1277 | case _IOC_NR(IOCTL_CED_CHECKSELFTEST): | 1351 | case _IOC_NR(IOCTL_CED_CHECKSELFTEST): |
1278 | return CheckSelfTest(pdx, (TGET_SELFTEST __user*)ulArg); | 1352 | return CheckSelfTest(pdx, (TGET_SELFTEST __user *) ulArg); |
1279 | 1353 | ||
1280 | case _IOC_NR(IOCTL_CED_TYPEOF1401): | 1354 | case _IOC_NR(IOCTL_CED_TYPEOF1401): |
1281 | return TypeOf1401(pdx); | 1355 | return TypeOf1401(pdx); |
1282 | 1356 | ||
1283 | case _IOC_NR(IOCTL_CED_TRANSFERFLAGS): | 1357 | case _IOC_NR(IOCTL_CED_TRANSFERFLAGS): |
1284 | return TransferFlags(pdx); | 1358 | return TransferFlags(pdx); |
1285 | 1359 | ||
1286 | case _IOC_NR(IOCTL_CED_DBGPEEK): | 1360 | case _IOC_NR(IOCTL_CED_DBGPEEK): |
1287 | return DbgPeek(pdx, (TDBGBLOCK __user*)ulArg); | 1361 | return DbgPeek(pdx, (TDBGBLOCK __user *) ulArg); |
1288 | 1362 | ||
1289 | case _IOC_NR(IOCTL_CED_DBGPOKE): | 1363 | case _IOC_NR(IOCTL_CED_DBGPOKE): |
1290 | return DbgPoke(pdx, (TDBGBLOCK __user*)ulArg); | 1364 | return DbgPoke(pdx, (TDBGBLOCK __user *) ulArg); |
1291 | 1365 | ||
1292 | case _IOC_NR(IOCTL_CED_DBGRAMPDATA): | 1366 | case _IOC_NR(IOCTL_CED_DBGRAMPDATA): |
1293 | return DbgRampData(pdx, (TDBGBLOCK __user*)ulArg); | 1367 | return DbgRampData(pdx, (TDBGBLOCK __user *) ulArg); |
1294 | 1368 | ||
1295 | case _IOC_NR(IOCTL_CED_DBGRAMPADDR): | 1369 | case _IOC_NR(IOCTL_CED_DBGRAMPADDR): |
1296 | return DbgRampAddr(pdx, (TDBGBLOCK __user*)ulArg); | 1370 | return DbgRampAddr(pdx, (TDBGBLOCK __user *) ulArg); |
1297 | 1371 | ||
1298 | case _IOC_NR(IOCTL_CED_DBGGETDATA): | 1372 | case _IOC_NR(IOCTL_CED_DBGGETDATA): |
1299 | return DbgGetData(pdx, (TDBGBLOCK __user*)ulArg); | 1373 | return DbgGetData(pdx, (TDBGBLOCK __user *) ulArg); |
1300 | 1374 | ||
1301 | case _IOC_NR(IOCTL_CED_DBGSTOPLOOP): | 1375 | case _IOC_NR(IOCTL_CED_DBGSTOPLOOP): |
1302 | return DbgStopLoop(pdx); | 1376 | return DbgStopLoop(pdx); |
1303 | 1377 | ||
1304 | case _IOC_NR(IOCTL_CED_FULLRESET): | 1378 | case _IOC_NR(IOCTL_CED_FULLRESET): |
1305 | pdx->bForceReset = true; // Set a flag for a full reset | 1379 | pdx->bForceReset = true; // Set a flag for a full reset |
1306 | break; | 1380 | break; |
1307 | 1381 | ||
1308 | case _IOC_NR(IOCTL_CED_SETCIRCULAR): | 1382 | case _IOC_NR(IOCTL_CED_SETCIRCULAR): |
1309 | return SetCircular(pdx, (TRANSFERDESC __user*)ulArg); | 1383 | return SetCircular(pdx, (TRANSFERDESC __user *) ulArg); |
1310 | 1384 | ||
1311 | case _IOC_NR(IOCTL_CED_GETCIRCBLOCK): | 1385 | case _IOC_NR(IOCTL_CED_GETCIRCBLOCK): |
1312 | return GetCircBlock(pdx, (TCIRCBLOCK __user*)ulArg); | 1386 | return GetCircBlock(pdx, (TCIRCBLOCK __user *) ulArg); |
1313 | 1387 | ||
1314 | case _IOC_NR(IOCTL_CED_FREECIRCBLOCK): | 1388 | case _IOC_NR(IOCTL_CED_FREECIRCBLOCK): |
1315 | return FreeCircBlock(pdx, (TCIRCBLOCK __user*)ulArg); | 1389 | return FreeCircBlock(pdx, (TCIRCBLOCK __user *) ulArg); |
1316 | 1390 | ||
1317 | case _IOC_NR(IOCTL_CED_WAITEVENT): | 1391 | case _IOC_NR(IOCTL_CED_WAITEVENT): |
1318 | return WaitEvent(pdx, (int)(ulArg & 0xff), (int)(ulArg >> 8)); | 1392 | return WaitEvent(pdx, (int)(ulArg & 0xff), (int)(ulArg >> 8)); |
1319 | 1393 | ||
1320 | case _IOC_NR(IOCTL_CED_TESTEVENT): | 1394 | case _IOC_NR(IOCTL_CED_TESTEVENT): |
1321 | return TestEvent(pdx, (int)ulArg); | 1395 | return TestEvent(pdx, (int)ulArg); |
1322 | 1396 | ||
1323 | default: | 1397 | default: |
1324 | return U14ERR_NO_SUCH_FN; | 1398 | return U14ERR_NO_SUCH_FN; |
1325 | } | 1399 | } |
1326 | return U14ERR_NOERROR; | 1400 | return U14ERR_NOERROR; |
1327 | } | 1401 | } |
1328 | 1402 | ||
1329 | static const struct file_operations ced_fops = | 1403 | static const struct file_operations ced_fops = { |
1330 | { | 1404 | .owner = THIS_MODULE, |
1331 | .owner = THIS_MODULE, | 1405 | .read = ced_read, |
1332 | .read = ced_read, | 1406 | .write = ced_write, |
1333 | .write = ced_write, | 1407 | .open = ced_open, |
1334 | .open = ced_open, | 1408 | .release = ced_release, |
1335 | .release = ced_release, | 1409 | .flush = ced_flush, |
1336 | .flush = ced_flush, | 1410 | .llseek = noop_llseek, |
1337 | .llseek = noop_llseek, | ||
1338 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) | 1411 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) |
1339 | .unlocked_ioctl = ced_ioctl, | 1412 | .unlocked_ioctl = ced_ioctl, |
1340 | #else | 1413 | #else |
1341 | .ioctl = ced_ioctl, | 1414 | .ioctl = ced_ioctl, |
1342 | #endif | 1415 | #endif |
1343 | }; | 1416 | }; |
1344 | 1417 | ||
@@ -1346,245 +1419,250 @@ static const struct file_operations ced_fops = | |||
1346 | * usb class driver info in order to get a minor number from the usb core, | 1419 | * usb class driver info in order to get a minor number from the usb core, |
1347 | * and to have the device registered with the driver core | 1420 | * and to have the device registered with the driver core |
1348 | */ | 1421 | */ |
1349 | static struct usb_class_driver ced_class = | 1422 | static struct usb_class_driver ced_class = { |
1350 | { | 1423 | .name = "cedusb%d", |
1351 | .name = "cedusb%d", | 1424 | .fops = &ced_fops, |
1352 | .fops = &ced_fops, | 1425 | .minor_base = USB_CED_MINOR_BASE, |
1353 | .minor_base = USB_CED_MINOR_BASE, | ||
1354 | }; | 1426 | }; |
1355 | 1427 | ||
1356 | // Check that the device that matches a 1401 vendor and product ID is OK to use and | 1428 | // Check that the device that matches a 1401 vendor and product ID is OK to use and |
1357 | // initialise our DEVICE_EXTENSION. | 1429 | // initialise our DEVICE_EXTENSION. |
1358 | static int ced_probe(struct usb_interface *interface, const struct usb_device_id *id) | 1430 | static int ced_probe(struct usb_interface *interface, |
1431 | const struct usb_device_id *id) | ||
1359 | { | 1432 | { |
1360 | DEVICE_EXTENSION *pdx; | 1433 | DEVICE_EXTENSION *pdx; |
1361 | struct usb_host_interface *iface_desc; | 1434 | struct usb_host_interface *iface_desc; |
1362 | struct usb_endpoint_descriptor *endpoint; | 1435 | struct usb_endpoint_descriptor *endpoint; |
1363 | int i, bcdDevice; | 1436 | int i, bcdDevice; |
1364 | int retval = -ENOMEM; | 1437 | int retval = -ENOMEM; |
1365 | 1438 | ||
1366 | // allocate memory for our device extension and initialize it | 1439 | // allocate memory for our device extension and initialize it |
1367 | pdx = kzalloc(sizeof(*pdx), GFP_KERNEL); | 1440 | pdx = kzalloc(sizeof(*pdx), GFP_KERNEL); |
1368 | if (!pdx) | 1441 | if (!pdx) { |
1369 | { | 1442 | dev_err(&interface->dev, "Out of memory\n"); |
1370 | dev_err(&interface->dev, "Out of memory\n"); | 1443 | goto error; |
1371 | goto error; | 1444 | } |
1372 | } | 1445 | |
1373 | 1446 | for (i = 0; i < MAX_TRANSAREAS; ++i) // Initialise the wait queues | |
1374 | for (i=0; i<MAX_TRANSAREAS; ++i) // Initialise the wait queues | 1447 | { |
1375 | { | 1448 | init_waitqueue_head(&pdx->rTransDef[i].wqEvent); |
1376 | init_waitqueue_head(&pdx->rTransDef[i].wqEvent); | 1449 | } |
1377 | } | 1450 | |
1378 | 1451 | // Put initialises for our stuff here. Note that all of *pdx is zero, so | |
1379 | // Put initialises for our stuff here. Note that all of *pdx is zero, so | 1452 | // no need to explicitly zero it. |
1380 | // no need to explicitly zero it. | 1453 | spin_lock_init(&pdx->charOutLock); |
1381 | spin_lock_init(&pdx->charOutLock); | 1454 | spin_lock_init(&pdx->charInLock); |
1382 | spin_lock_init(&pdx->charInLock); | 1455 | spin_lock_init(&pdx->stagedLock); |
1383 | spin_lock_init(&pdx->stagedLock); | 1456 | |
1384 | 1457 | // Initialises from the skeleton stuff | |
1385 | // Initialises from the skeleton stuff | 1458 | kref_init(&pdx->kref); |
1386 | kref_init(&pdx->kref); | 1459 | mutex_init(&pdx->io_mutex); |
1387 | mutex_init(&pdx->io_mutex); | 1460 | spin_lock_init(&pdx->err_lock); |
1388 | spin_lock_init(&pdx->err_lock); | 1461 | init_usb_anchor(&pdx->submitted); |
1389 | init_usb_anchor(&pdx->submitted); | 1462 | |
1390 | 1463 | pdx->udev = usb_get_dev(interface_to_usbdev(interface)); | |
1391 | pdx->udev = usb_get_dev(interface_to_usbdev(interface)); | 1464 | pdx->interface = interface; |
1392 | pdx->interface = interface; | 1465 | |
1393 | 1466 | // Attempt to identify the device | |
1394 | // Attempt to identify the device | 1467 | bcdDevice = pdx->udev->descriptor.bcdDevice; |
1395 | bcdDevice = pdx->udev->descriptor.bcdDevice; | 1468 | i = (bcdDevice >> 8); |
1396 | i = (bcdDevice >> 8); | 1469 | if (i == 0) |
1397 | if (i == 0) | 1470 | pdx->s1401Type = TYPEU1401; |
1398 | pdx->s1401Type = TYPEU1401; | 1471 | else if ((i >= 1) && (i <= 23)) |
1399 | else if ((i>=1) && (i<=23)) | 1472 | pdx->s1401Type = i + 2; |
1400 | pdx->s1401Type = i+2; | 1473 | else { |
1401 | else | 1474 | dev_err(&interface->dev, "%s Unknown device. bcdDevice = %d", |
1402 | { | 1475 | __func__, bcdDevice); |
1403 | dev_err(&interface->dev, "%s Unknown device. bcdDevice = %d", __func__, bcdDevice); | 1476 | goto error; |
1404 | goto error; | 1477 | } |
1405 | } | 1478 | // set up the endpoint information. We only care about the number of EP as |
1406 | // set up the endpoint information. We only care about the number of EP as | 1479 | // we know that we are dealing with a 1401 device. |
1407 | // we know that we are dealing with a 1401 device. | 1480 | iface_desc = interface->cur_altsetting; |
1408 | iface_desc = interface->cur_altsetting; | 1481 | pdx->nPipes = iface_desc->desc.bNumEndpoints; |
1409 | pdx->nPipes = iface_desc->desc.bNumEndpoints; | 1482 | dev_info(&interface->dev, "1401Type=%d with %d End Points", |
1410 | dev_info(&interface->dev, "1401Type=%d with %d End Points", pdx->s1401Type, pdx->nPipes); | 1483 | pdx->s1401Type, pdx->nPipes); |
1411 | if ((pdx->nPipes < 3) || (pdx->nPipes > 4)) | 1484 | if ((pdx->nPipes < 3) || (pdx->nPipes > 4)) |
1412 | goto error; | 1485 | goto error; |
1413 | 1486 | ||
1414 | // Allocate the URBs we hold for performing transfers | 1487 | // Allocate the URBs we hold for performing transfers |
1415 | pdx->pUrbCharOut = usb_alloc_urb(0, GFP_KERNEL); // character output URB | 1488 | pdx->pUrbCharOut = usb_alloc_urb(0, GFP_KERNEL); // character output URB |
1416 | pdx->pUrbCharIn = usb_alloc_urb(0, GFP_KERNEL); // character input URB | 1489 | pdx->pUrbCharIn = usb_alloc_urb(0, GFP_KERNEL); // character input URB |
1417 | pdx->pStagedUrb = usb_alloc_urb(0, GFP_KERNEL); // block transfer URB | 1490 | pdx->pStagedUrb = usb_alloc_urb(0, GFP_KERNEL); // block transfer URB |
1418 | if (!pdx->pUrbCharOut || !pdx->pUrbCharIn || !pdx->pStagedUrb) | 1491 | if (!pdx->pUrbCharOut || !pdx->pUrbCharIn || !pdx->pStagedUrb) { |
1419 | { | 1492 | dev_err(&interface->dev, "%s URB alloc failed", __func__); |
1420 | dev_err(&interface->dev, "%s URB alloc failed", __func__); | 1493 | goto error; |
1421 | goto error; | 1494 | } |
1422 | } | 1495 | |
1423 | 1496 | pdx->pCoherStagedIO = | |
1424 | pdx->pCoherStagedIO = usb_alloc_coherent(pdx->udev, STAGED_SZ, GFP_KERNEL, &pdx->pStagedUrb->transfer_dma); | 1497 | usb_alloc_coherent(pdx->udev, STAGED_SZ, GFP_KERNEL, |
1425 | pdx->pCoherCharOut = usb_alloc_coherent(pdx->udev, OUTBUF_SZ, GFP_KERNEL, &pdx->pUrbCharOut->transfer_dma); | 1498 | &pdx->pStagedUrb->transfer_dma); |
1426 | pdx->pCoherCharIn = usb_alloc_coherent(pdx->udev, INBUF_SZ, GFP_KERNEL, &pdx->pUrbCharIn->transfer_dma); | 1499 | pdx->pCoherCharOut = |
1427 | if (!pdx->pCoherCharOut || !pdx->pCoherCharIn || !pdx->pCoherStagedIO) | 1500 | usb_alloc_coherent(pdx->udev, OUTBUF_SZ, GFP_KERNEL, |
1428 | { | 1501 | &pdx->pUrbCharOut->transfer_dma); |
1429 | dev_err(&interface->dev, "%s Coherent buffer alloc failed", __func__); | 1502 | pdx->pCoherCharIn = |
1430 | goto error; | 1503 | usb_alloc_coherent(pdx->udev, INBUF_SZ, GFP_KERNEL, |
1431 | } | 1504 | &pdx->pUrbCharIn->transfer_dma); |
1432 | 1505 | if (!pdx->pCoherCharOut || !pdx->pCoherCharIn || !pdx->pCoherStagedIO) { | |
1433 | for (i = 0; i < pdx->nPipes; ++i) | 1506 | dev_err(&interface->dev, "%s Coherent buffer alloc failed", |
1434 | { | 1507 | __func__); |
1435 | endpoint = &iface_desc->endpoint[i].desc; | 1508 | goto error; |
1436 | pdx->epAddr[i] = endpoint->bEndpointAddress; | 1509 | } |
1437 | dev_info(&interface->dev, "Pipe %d, ep address %02x", i, pdx->epAddr[i]); | 1510 | |
1438 | if (((pdx->nPipes==3) && (i==0)) || // if char input end point | 1511 | for (i = 0; i < pdx->nPipes; ++i) { |
1439 | ((pdx->nPipes==4) && (i==1))) | 1512 | endpoint = &iface_desc->endpoint[i].desc; |
1440 | { | 1513 | pdx->epAddr[i] = endpoint->bEndpointAddress; |
1441 | pdx->bInterval = endpoint->bInterval; // save the endpoint interrupt interval | 1514 | dev_info(&interface->dev, "Pipe %d, ep address %02x", i, |
1442 | dev_info(&interface->dev, "Pipe %d, bInterval = %d", i, pdx->bInterval); | 1515 | pdx->epAddr[i]); |
1443 | } | 1516 | if (((pdx->nPipes == 3) && (i == 0)) || // if char input end point |
1444 | 1517 | ((pdx->nPipes == 4) && (i == 1))) { | |
1445 | // Detect USB2 by checking last ep size (64 if USB1) | 1518 | pdx->bInterval = endpoint->bInterval; // save the endpoint interrupt interval |
1446 | if (i == pdx->nPipes-1) // if this is the last ep (bulk) | 1519 | dev_info(&interface->dev, "Pipe %d, bInterval = %d", i, |
1447 | { | 1520 | pdx->bInterval); |
1448 | pdx->bIsUSB2 = le16_to_cpu(endpoint->wMaxPacketSize) > 64; | 1521 | } |
1449 | dev_info(&pdx->interface->dev, "USB%d", pdx->bIsUSB2 + 1); | 1522 | // Detect USB2 by checking last ep size (64 if USB1) |
1450 | } | 1523 | if (i == pdx->nPipes - 1) // if this is the last ep (bulk) |
1451 | } | 1524 | { |
1452 | 1525 | pdx->bIsUSB2 = | |
1453 | /* save our data pointer in this interface device */ | 1526 | le16_to_cpu(endpoint->wMaxPacketSize) > 64; |
1454 | usb_set_intfdata(interface, pdx); | 1527 | dev_info(&pdx->interface->dev, "USB%d", |
1455 | 1528 | pdx->bIsUSB2 + 1); | |
1456 | /* we can register the device now, as it is ready */ | 1529 | } |
1457 | retval = usb_register_dev(interface, &ced_class); | 1530 | } |
1458 | if (retval) | 1531 | |
1459 | { | 1532 | /* save our data pointer in this interface device */ |
1460 | /* something prevented us from registering this driver */ | 1533 | usb_set_intfdata(interface, pdx); |
1461 | dev_err(&interface->dev, "Not able to get a minor for this device.\n"); | 1534 | |
1462 | usb_set_intfdata(interface, NULL); | 1535 | /* we can register the device now, as it is ready */ |
1463 | goto error; | 1536 | retval = usb_register_dev(interface, &ced_class); |
1464 | } | 1537 | if (retval) { |
1465 | 1538 | /* something prevented us from registering this driver */ | |
1466 | /* let the user know what node this device is now attached to */ | 1539 | dev_err(&interface->dev, |
1467 | dev_info(&interface->dev, | 1540 | "Not able to get a minor for this device.\n"); |
1468 | "USB CEDUSB device now attached to cedusb #%d", | 1541 | usb_set_intfdata(interface, NULL); |
1469 | interface->minor); | 1542 | goto error; |
1470 | return 0; | 1543 | } |
1544 | |||
1545 | /* let the user know what node this device is now attached to */ | ||
1546 | dev_info(&interface->dev, | ||
1547 | "USB CEDUSB device now attached to cedusb #%d", | ||
1548 | interface->minor); | ||
1549 | return 0; | ||
1471 | 1550 | ||
1472 | error: | 1551 | error: |
1473 | if (pdx) | 1552 | if (pdx) |
1474 | kref_put(&pdx->kref, ced_delete); // frees allocated memory | 1553 | kref_put(&pdx->kref, ced_delete); // frees allocated memory |
1475 | return retval; | 1554 | return retval; |
1476 | } | 1555 | } |
1477 | 1556 | ||
1478 | static void ced_disconnect(struct usb_interface *interface) | 1557 | static void ced_disconnect(struct usb_interface *interface) |
1479 | { | 1558 | { |
1480 | DEVICE_EXTENSION *pdx = usb_get_intfdata(interface); | 1559 | DEVICE_EXTENSION *pdx = usb_get_intfdata(interface); |
1481 | int minor = interface->minor; // save for message at the end | 1560 | int minor = interface->minor; // save for message at the end |
1482 | int i; | 1561 | int i; |
1483 | 1562 | ||
1484 | usb_set_intfdata(interface, NULL); // remove the pdx from the interface | 1563 | usb_set_intfdata(interface, NULL); // remove the pdx from the interface |
1485 | usb_deregister_dev(interface, &ced_class); // give back our minor device number | 1564 | usb_deregister_dev(interface, &ced_class); // give back our minor device number |
1486 | 1565 | ||
1487 | mutex_lock(&pdx->io_mutex); // stop more I/O starting while... | 1566 | mutex_lock(&pdx->io_mutex); // stop more I/O starting while... |
1488 | ced_draw_down(pdx); // ...wait for then kill any io | 1567 | ced_draw_down(pdx); // ...wait for then kill any io |
1489 | for (i=0; i<MAX_TRANSAREAS; ++i) | 1568 | for (i = 0; i < MAX_TRANSAREAS; ++i) { |
1490 | { | 1569 | int iErr = ClearArea(pdx, i); // ...release any used memory |
1491 | int iErr = ClearArea(pdx, i); // ...release any used memory | 1570 | if (iErr == U14ERR_UNLOCKFAIL) |
1492 | if (iErr == U14ERR_UNLOCKFAIL) | 1571 | dev_err(&pdx->interface->dev, "%s Area %d was in used", |
1493 | dev_err(&pdx->interface->dev, "%s Area %d was in used", __func__, i); | 1572 | __func__, i); |
1494 | } | 1573 | } |
1495 | pdx->interface = NULL; // ...we kill off link to interface | 1574 | pdx->interface = NULL; // ...we kill off link to interface |
1496 | mutex_unlock(&pdx->io_mutex); | 1575 | mutex_unlock(&pdx->io_mutex); |
1497 | 1576 | ||
1498 | usb_kill_anchored_urbs(&pdx->submitted); | 1577 | usb_kill_anchored_urbs(&pdx->submitted); |
1499 | 1578 | ||
1500 | kref_put(&pdx->kref, ced_delete); // decrement our usage count | 1579 | kref_put(&pdx->kref, ced_delete); // decrement our usage count |
1501 | 1580 | ||
1502 | dev_info(&interface->dev, "USB cedusb #%d now disconnected", minor); | 1581 | dev_info(&interface->dev, "USB cedusb #%d now disconnected", minor); |
1503 | } | 1582 | } |
1504 | 1583 | ||
1505 | // Wait for all the urbs we know of to be done with, then kill off any that | 1584 | // Wait for all the urbs we know of to be done with, then kill off any that |
1506 | // are left. NBNB we will need to have a mechanism to stop circular xfers | 1585 | // are left. NBNB we will need to have a mechanism to stop circular xfers |
1507 | // from trying to fire off more urbs. We will wait up to 3 seconds for Urbs | 1586 | // from trying to fire off more urbs. We will wait up to 3 seconds for Urbs |
1508 | // to be done. | 1587 | // to be done. |
1509 | void ced_draw_down(DEVICE_EXTENSION *pdx) | 1588 | void ced_draw_down(DEVICE_EXTENSION * pdx) |
1510 | { | 1589 | { |
1511 | int time; | 1590 | int time; |
1512 | dev_dbg(&pdx->interface->dev,"%s called", __func__); | 1591 | dev_dbg(&pdx->interface->dev, "%s called", __func__); |
1513 | 1592 | ||
1514 | pdx->bInDrawDown = true; | 1593 | pdx->bInDrawDown = true; |
1515 | time = usb_wait_anchor_empty_timeout(&pdx->submitted, 3000); | 1594 | time = usb_wait_anchor_empty_timeout(&pdx->submitted, 3000); |
1516 | if (!time) // if we timed out we kill the urbs | 1595 | if (!time) // if we timed out we kill the urbs |
1517 | { | 1596 | { |
1518 | usb_kill_anchored_urbs(&pdx->submitted); | 1597 | usb_kill_anchored_urbs(&pdx->submitted); |
1519 | dev_err(&pdx->interface->dev,"%s timed out", __func__); | 1598 | dev_err(&pdx->interface->dev, "%s timed out", __func__); |
1520 | } | 1599 | } |
1521 | pdx->bInDrawDown = false; | 1600 | pdx->bInDrawDown = false; |
1522 | } | 1601 | } |
1523 | 1602 | ||
1524 | static int ced_suspend(struct usb_interface *intf, pm_message_t message) | 1603 | static int ced_suspend(struct usb_interface *intf, pm_message_t message) |
1525 | { | 1604 | { |
1526 | DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); | 1605 | DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); |
1527 | if (!pdx) | 1606 | if (!pdx) |
1528 | return 0; | 1607 | return 0; |
1529 | ced_draw_down(pdx); | 1608 | ced_draw_down(pdx); |
1530 | 1609 | ||
1531 | dev_dbg(&pdx->interface->dev,"%s called", __func__); | 1610 | dev_dbg(&pdx->interface->dev, "%s called", __func__); |
1532 | return 0; | 1611 | return 0; |
1533 | } | 1612 | } |
1534 | 1613 | ||
1535 | static int ced_resume(struct usb_interface *intf) | 1614 | static int ced_resume(struct usb_interface *intf) |
1536 | { | 1615 | { |
1537 | DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); | 1616 | DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); |
1538 | if (!pdx) | 1617 | if (!pdx) |
1539 | return 0; | 1618 | return 0; |
1540 | dev_dbg(&pdx->interface->dev,"%s called", __func__); | 1619 | dev_dbg(&pdx->interface->dev, "%s called", __func__); |
1541 | return 0; | 1620 | return 0; |
1542 | } | 1621 | } |
1543 | 1622 | ||
1544 | static int ced_pre_reset(struct usb_interface *intf) | 1623 | static int ced_pre_reset(struct usb_interface *intf) |
1545 | { | 1624 | { |
1546 | DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); | 1625 | DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); |
1547 | dev_dbg(&pdx->interface->dev, "%s", __func__); | 1626 | dev_dbg(&pdx->interface->dev, "%s", __func__); |
1548 | mutex_lock(&pdx->io_mutex); | 1627 | mutex_lock(&pdx->io_mutex); |
1549 | ced_draw_down(pdx); | 1628 | ced_draw_down(pdx); |
1550 | return 0; | 1629 | return 0; |
1551 | } | 1630 | } |
1552 | 1631 | ||
1553 | static int ced_post_reset(struct usb_interface *intf) | 1632 | static int ced_post_reset(struct usb_interface *intf) |
1554 | { | 1633 | { |
1555 | DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); | 1634 | DEVICE_EXTENSION *pdx = usb_get_intfdata(intf); |
1556 | dev_dbg(&pdx->interface->dev, "%s", __func__); | 1635 | dev_dbg(&pdx->interface->dev, "%s", __func__); |
1557 | 1636 | ||
1558 | /* we are sure no URBs are active - no locking needed */ | 1637 | /* we are sure no URBs are active - no locking needed */ |
1559 | pdx->errors = -EPIPE; | 1638 | pdx->errors = -EPIPE; |
1560 | mutex_unlock(&pdx->io_mutex); | 1639 | mutex_unlock(&pdx->io_mutex); |
1561 | 1640 | ||
1562 | return 0; | 1641 | return 0; |
1563 | } | 1642 | } |
1564 | 1643 | ||
1565 | static struct usb_driver ced_driver = | 1644 | static struct usb_driver ced_driver = { |
1566 | { | 1645 | .name = "cedusb", |
1567 | .name = "cedusb", | 1646 | .probe = ced_probe, |
1568 | .probe = ced_probe, | 1647 | .disconnect = ced_disconnect, |
1569 | .disconnect = ced_disconnect, | 1648 | .suspend = ced_suspend, |
1570 | .suspend = ced_suspend, | 1649 | .resume = ced_resume, |
1571 | .resume = ced_resume, | 1650 | .pre_reset = ced_pre_reset, |
1572 | .pre_reset = ced_pre_reset, | 1651 | .post_reset = ced_post_reset, |
1573 | .post_reset = ced_post_reset, | 1652 | .id_table = ced_table, |
1574 | .id_table = ced_table, | 1653 | .supports_autosuspend = 1, |
1575 | .supports_autosuspend = 1, | ||
1576 | }; | 1654 | }; |
1577 | 1655 | ||
1578 | static int __init usb_skel_init(void) | 1656 | static int __init usb_skel_init(void) |
1579 | { | 1657 | { |
1580 | /* register this driver with the USB subsystem */ | 1658 | /* register this driver with the USB subsystem */ |
1581 | return usb_register(&ced_driver); | 1659 | return usb_register(&ced_driver); |
1582 | } | 1660 | } |
1583 | 1661 | ||
1584 | static void __exit usb_skel_exit(void) | 1662 | static void __exit usb_skel_exit(void) |
1585 | { | 1663 | { |
1586 | /* deregister this driver with the USB subsystem */ | 1664 | /* deregister this driver with the USB subsystem */ |
1587 | usb_deregister(&ced_driver); | 1665 | usb_deregister(&ced_driver); |
1588 | } | 1666 | } |
1589 | 1667 | ||
1590 | module_init(usb_skel_init); | 1668 | module_init(usb_skel_init); |