diff options
| -rw-r--r-- | drivers/block/ub.c | 211 |
1 files changed, 170 insertions, 41 deletions
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 685f061e69b2..a026567f5d18 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | * -- Exterminate P3 printks | 23 | * -- Exterminate P3 printks |
| 24 | * -- Resove XXX's | 24 | * -- Resove XXX's |
| 25 | * -- Redo "benh's retries", perhaps have spin-up code to handle them. V:D=? | 25 | * -- Redo "benh's retries", perhaps have spin-up code to handle them. V:D=? |
| 26 | * -- CLEAR, CLR2STS, CLRRS seem to be ripe for refactoring. | ||
| 26 | */ | 27 | */ |
| 27 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
| 28 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| @@ -38,6 +39,73 @@ | |||
| 38 | #define UB_MAJOR 180 | 39 | #define UB_MAJOR 180 |
| 39 | 40 | ||
| 40 | /* | 41 | /* |
| 42 | * The command state machine is the key model for understanding of this driver. | ||
| 43 | * | ||
| 44 | * The general rule is that all transitions are done towards the bottom | ||
| 45 | * of the diagram, thus preventing any loops. | ||
| 46 | * | ||
| 47 | * An exception to that is how the STAT state is handled. A counter allows it | ||
| 48 | * to be re-entered along the path marked with [C]. | ||
| 49 | * | ||
| 50 | * +--------+ | ||
| 51 | * ! INIT ! | ||
| 52 | * +--------+ | ||
| 53 | * ! | ||
| 54 | * ub_scsi_cmd_start fails ->--------------------------------------\ | ||
| 55 | * ! ! | ||
| 56 | * V ! | ||
| 57 | * +--------+ ! | ||
| 58 | * ! CMD ! ! | ||
| 59 | * +--------+ ! | ||
| 60 | * ! +--------+ ! | ||
| 61 | * was -EPIPE -->-------------------------------->! CLEAR ! ! | ||
| 62 | * ! +--------+ ! | ||
| 63 | * ! ! ! | ||
| 64 | * was error -->------------------------------------- ! --------->\ | ||
| 65 | * ! ! ! | ||
| 66 | * /--<-- cmd->dir == NONE ? ! ! | ||
| 67 | * ! ! ! ! | ||
| 68 | * ! V ! ! | ||
| 69 | * ! +--------+ ! ! | ||
| 70 | * ! ! DATA ! ! ! | ||
| 71 | * ! +--------+ ! ! | ||
| 72 | * ! ! +---------+ ! ! | ||
| 73 | * ! was -EPIPE -->--------------->! CLR2STS ! ! ! | ||
| 74 | * ! ! +---------+ ! ! | ||
| 75 | * ! ! ! ! ! | ||
| 76 | * ! ! was error -->---- ! --------->\ | ||
| 77 | * ! was error -->--------------------- ! ------------- ! --------->\ | ||
| 78 | * ! ! ! ! ! | ||
| 79 | * ! V ! ! ! | ||
| 80 | * \--->+--------+ ! ! ! | ||
| 81 | * ! STAT !<--------------------------/ ! ! | ||
| 82 | * /--->+--------+ ! ! | ||
| 83 | * ! ! ! ! | ||
| 84 | * [C] was -EPIPE -->-----------\ ! ! | ||
| 85 | * ! ! ! ! ! | ||
| 86 | * +<---- len == 0 ! ! ! | ||
| 87 | * ! ! ! ! ! | ||
| 88 | * ! was error -->--------------------------------------!---------->\ | ||
| 89 | * ! ! ! ! ! | ||
| 90 | * +<---- bad CSW ! ! ! | ||
| 91 | * +<---- bad tag ! ! ! | ||
| 92 | * ! ! V ! ! | ||
| 93 | * ! ! +--------+ ! ! | ||
| 94 | * ! ! ! CLRRS ! ! ! | ||
| 95 | * ! ! +--------+ ! ! | ||
| 96 | * ! ! ! ! ! | ||
| 97 | * \------- ! --------------------[C]--------\ ! ! | ||
| 98 | * ! ! ! ! | ||
| 99 | * cmd->error---\ +--------+ ! ! | ||
| 100 | * ! +--------------->! SENSE !<----------/ ! | ||
| 101 | * STAT_FAIL----/ +--------+ ! | ||
| 102 | * ! ! V | ||
| 103 | * ! V +--------+ | ||
| 104 | * \--------------------------------\--------------------->! DONE ! | ||
| 105 | * +--------+ | ||
| 106 | */ | ||
| 107 | |||
| 108 | /* | ||
| 41 | * Definitions which have to be scattered once we understand the layout better. | 109 | * Definitions which have to be scattered once we understand the layout better. |
| 42 | */ | 110 | */ |
| 43 | 111 | ||
| @@ -91,8 +159,6 @@ struct bulk_cs_wrap { | |||
| 91 | 159 | ||
| 92 | #define US_BULK_CS_WRAP_LEN 13 | 160 | #define US_BULK_CS_WRAP_LEN 13 |
| 93 | #define US_BULK_CS_SIGN 0x53425355 /* spells out 'USBS' */ | 161 | #define US_BULK_CS_SIGN 0x53425355 /* spells out 'USBS' */ |
| 94 | /* This is for Olympus Camedia digital cameras */ | ||
| 95 | #define US_BULK_CS_OLYMPUS_SIGN 0x55425355 /* spells out 'USBU' */ | ||
| 96 | #define US_BULK_STAT_OK 0 | 162 | #define US_BULK_STAT_OK 0 |
| 97 | #define US_BULK_STAT_FAIL 1 | 163 | #define US_BULK_STAT_FAIL 1 |
| 98 | #define US_BULK_STAT_PHASE 2 | 164 | #define US_BULK_STAT_PHASE 2 |
| @@ -135,6 +201,7 @@ enum ub_scsi_cmd_state { | |||
| 135 | UB_CMDST_CLR2STS, /* Clearing before requesting status */ | 201 | UB_CMDST_CLR2STS, /* Clearing before requesting status */ |
| 136 | UB_CMDST_STAT, /* Status phase */ | 202 | UB_CMDST_STAT, /* Status phase */ |
| 137 | UB_CMDST_CLEAR, /* Clearing a stall (halt, actually) */ | 203 | UB_CMDST_CLEAR, /* Clearing a stall (halt, actually) */ |
| 204 | UB_CMDST_CLRRS, /* Clearing before retrying status */ | ||
| 138 | UB_CMDST_SENSE, /* Sending Request Sense */ | 205 | UB_CMDST_SENSE, /* Sending Request Sense */ |
| 139 | UB_CMDST_DONE /* Final state */ | 206 | UB_CMDST_DONE /* Final state */ |
| 140 | }; | 207 | }; |
| @@ -146,6 +213,7 @@ static char *ub_scsi_cmd_stname[] = { | |||
| 146 | "c2s", | 213 | "c2s", |
| 147 | "sts", | 214 | "sts", |
| 148 | "clr", | 215 | "clr", |
| 216 | "crs", | ||
| 149 | "Sen", | 217 | "Sen", |
| 150 | "fin" | 218 | "fin" |
| 151 | }; | 219 | }; |
| @@ -316,6 +384,7 @@ struct ub_dev { | |||
| 316 | struct urb work_urb; | 384 | struct urb work_urb; |
| 317 | struct timer_list work_timer; | 385 | struct timer_list work_timer; |
| 318 | int last_pipe; /* What might need clearing */ | 386 | int last_pipe; /* What might need clearing */ |
| 387 | __le32 signature; /* Learned signature */ | ||
| 319 | struct bulk_cb_wrap work_bcb; | 388 | struct bulk_cb_wrap work_bcb; |
| 320 | struct bulk_cs_wrap work_bcs; | 389 | struct bulk_cs_wrap work_bcs; |
| 321 | struct usb_ctrlrequest work_cr; | 390 | struct usb_ctrlrequest work_cr; |
| @@ -339,8 +408,9 @@ static void ub_scsi_action(unsigned long _dev); | |||
| 339 | static void ub_scsi_dispatch(struct ub_dev *sc); | 408 | static void ub_scsi_dispatch(struct ub_dev *sc); |
| 340 | static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd); | 409 | static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd); |
| 341 | static void ub_state_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int rc); | 410 | static void ub_state_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int rc); |
| 342 | static void __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd); | 411 | static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd); |
| 343 | static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd); | 412 | static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd); |
| 413 | static void ub_state_stat_counted(struct ub_dev *sc, struct ub_scsi_cmd *cmd); | ||
| 344 | static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd); | 414 | static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd); |
| 345 | static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, | 415 | static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, |
| 346 | int stalled_pipe); | 416 | int stalled_pipe); |
| @@ -1085,6 +1155,28 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1085 | 1155 | ||
| 1086 | ub_state_stat(sc, cmd); | 1156 | ub_state_stat(sc, cmd); |
| 1087 | 1157 | ||
| 1158 | } else if (cmd->state == UB_CMDST_CLRRS) { | ||
| 1159 | if (urb->status == -EPIPE) { | ||
| 1160 | /* | ||
| 1161 | * STALL while clearning STALL. | ||
| 1162 | * The control pipe clears itself - nothing to do. | ||
| 1163 | * XXX Might try to reset the device here and retry. | ||
| 1164 | */ | ||
| 1165 | printk(KERN_NOTICE "%s: stall on control pipe\n", | ||
| 1166 | sc->name); | ||
| 1167 | goto Bad_End; | ||
| 1168 | } | ||
| 1169 | |||
| 1170 | /* | ||
| 1171 | * We ignore the result for the halt clear. | ||
| 1172 | */ | ||
| 1173 | |||
| 1174 | /* reset the endpoint toggle */ | ||
| 1175 | usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe), | ||
| 1176 | usb_pipeout(sc->last_pipe), 0); | ||
| 1177 | |||
| 1178 | ub_state_stat_counted(sc, cmd); | ||
| 1179 | |||
| 1088 | } else if (cmd->state == UB_CMDST_CMD) { | 1180 | } else if (cmd->state == UB_CMDST_CMD) { |
| 1089 | if (urb->status == -EPIPE) { | 1181 | if (urb->status == -EPIPE) { |
| 1090 | rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); | 1182 | rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); |
| @@ -1190,52 +1282,57 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1190 | */ | 1282 | */ |
| 1191 | goto Bad_End; | 1283 | goto Bad_End; |
| 1192 | } | 1284 | } |
| 1193 | cmd->state = UB_CMDST_CLEAR; | 1285 | |
| 1286 | /* | ||
| 1287 | * Having a stall when getting CSW is an error, so | ||
| 1288 | * make sure uppper levels are not oblivious to it. | ||
| 1289 | */ | ||
| 1290 | cmd->error = -EIO; /* A cheap trick... */ | ||
| 1291 | |||
| 1292 | cmd->state = UB_CMDST_CLRRS; | ||
| 1194 | ub_cmdtr_state(sc, cmd); | 1293 | ub_cmdtr_state(sc, cmd); |
| 1195 | return; | 1294 | return; |
| 1196 | } | 1295 | } |
| 1296 | if (urb->status == -EOVERFLOW) { | ||
| 1297 | /* | ||
| 1298 | * XXX We are screwed here. Retrying is pointless, | ||
| 1299 | * because the pipelined data will not get in until | ||
| 1300 | * we read with a big enough buffer. We must reset XXX. | ||
| 1301 | */ | ||
| 1302 | goto Bad_End; | ||
| 1303 | } | ||
| 1197 | if (urb->status != 0) | 1304 | if (urb->status != 0) |
| 1198 | goto Bad_End; | 1305 | goto Bad_End; |
| 1199 | 1306 | ||
| 1200 | if (urb->actual_length == 0) { | 1307 | if (urb->actual_length == 0) { |
| 1201 | /* | 1308 | ub_state_stat_counted(sc, cmd); |
| 1202 | * Some broken devices add unnecessary zero-length | ||
| 1203 | * packets to the end of their data transfers. | ||
| 1204 | * Such packets show up as 0-length CSWs. If we | ||
| 1205 | * encounter such a thing, try to read the CSW again. | ||
| 1206 | */ | ||
| 1207 | if (++cmd->stat_count >= 4) { | ||
| 1208 | printk(KERN_NOTICE "%s: unable to get CSW\n", | ||
| 1209 | sc->name); | ||
| 1210 | goto Bad_End; | ||
| 1211 | } | ||
| 1212 | __ub_state_stat(sc, cmd); | ||
| 1213 | return; | 1309 | return; |
| 1214 | } | 1310 | } |
| 1215 | 1311 | ||
| 1216 | /* | 1312 | /* |
| 1217 | * Check the returned Bulk protocol status. | 1313 | * Check the returned Bulk protocol status. |
| 1314 | * The status block has to be validated first. | ||
| 1218 | */ | 1315 | */ |
| 1219 | 1316 | ||
| 1220 | bcs = &sc->work_bcs; | 1317 | bcs = &sc->work_bcs; |
| 1221 | rc = le32_to_cpu(bcs->Residue); | 1318 | |
| 1222 | if (rc != cmd->len - cmd->act_len) { | 1319 | if (sc->signature == cpu_to_le32(0)) { |
| 1223 | /* | 1320 | /* |
| 1224 | * It is all right to transfer less, the caller has | 1321 | * This is the first reply, so do not perform the check. |
| 1225 | * to check. But it's not all right if the device | 1322 | * Instead, remember the signature the device uses |
| 1226 | * counts disagree with our counts. | 1323 | * for future checks. But do not allow a nul. |
| 1227 | */ | 1324 | */ |
| 1228 | /* P3 */ printk("%s: resid %d len %d act %d\n", | 1325 | sc->signature = bcs->Signature; |
| 1229 | sc->name, rc, cmd->len, cmd->act_len); | 1326 | if (sc->signature == cpu_to_le32(0)) { |
| 1230 | goto Bad_End; | 1327 | ub_state_stat_counted(sc, cmd); |
| 1231 | } | 1328 | return; |
| 1232 | 1329 | } | |
| 1233 | #if 0 | 1330 | } else { |
| 1234 | if (bcs->Signature != cpu_to_le32(US_BULK_CS_SIGN) && | 1331 | if (bcs->Signature != sc->signature) { |
| 1235 | bcs->Signature != cpu_to_le32(US_BULK_CS_OLYMPUS_SIGN)) { | 1332 | ub_state_stat_counted(sc, cmd); |
| 1236 | /* Windows ignores signatures, so do we. */ | 1333 | return; |
| 1334 | } | ||
| 1237 | } | 1335 | } |
| 1238 | #endif | ||
| 1239 | 1336 | ||
| 1240 | if (bcs->Tag != cmd->tag) { | 1337 | if (bcs->Tag != cmd->tag) { |
| 1241 | /* | 1338 | /* |
| @@ -1245,16 +1342,22 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1245 | * commands and reply at commands we timed out before. | 1342 | * commands and reply at commands we timed out before. |
| 1246 | * Without flushing these replies we loop forever. | 1343 | * Without flushing these replies we loop forever. |
| 1247 | */ | 1344 | */ |
| 1248 | if (++cmd->stat_count >= 4) { | 1345 | ub_state_stat_counted(sc, cmd); |
| 1249 | printk(KERN_NOTICE "%s: " | ||
| 1250 | "tag mismatch orig 0x%x reply 0x%x\n", | ||
| 1251 | sc->name, cmd->tag, bcs->Tag); | ||
| 1252 | goto Bad_End; | ||
| 1253 | } | ||
| 1254 | __ub_state_stat(sc, cmd); | ||
| 1255 | return; | 1346 | return; |
| 1256 | } | 1347 | } |
| 1257 | 1348 | ||
| 1349 | rc = le32_to_cpu(bcs->Residue); | ||
| 1350 | if (rc != cmd->len - cmd->act_len) { | ||
| 1351 | /* | ||
| 1352 | * It is all right to transfer less, the caller has | ||
| 1353 | * to check. But it's not all right if the device | ||
| 1354 | * counts disagree with our counts. | ||
| 1355 | */ | ||
| 1356 | /* P3 */ printk("%s: resid %d len %d act %d\n", | ||
| 1357 | sc->name, rc, cmd->len, cmd->act_len); | ||
| 1358 | goto Bad_End; | ||
| 1359 | } | ||
| 1360 | |||
| 1258 | switch (bcs->Status) { | 1361 | switch (bcs->Status) { |
| 1259 | case US_BULK_STAT_OK: | 1362 | case US_BULK_STAT_OK: |
| 1260 | break; | 1363 | break; |
| @@ -1272,6 +1375,10 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1272 | } | 1375 | } |
| 1273 | 1376 | ||
| 1274 | /* Not zeroing error to preserve a babble indicator */ | 1377 | /* Not zeroing error to preserve a babble indicator */ |
| 1378 | if (cmd->error != 0) { | ||
| 1379 | ub_state_sense(sc, cmd); | ||
| 1380 | return; | ||
| 1381 | } | ||
| 1275 | cmd->state = UB_CMDST_DONE; | 1382 | cmd->state = UB_CMDST_DONE; |
| 1276 | ub_cmdtr_state(sc, cmd); | 1383 | ub_cmdtr_state(sc, cmd); |
| 1277 | ub_cmdq_pop(sc); | 1384 | ub_cmdq_pop(sc); |
| @@ -1310,7 +1417,7 @@ static void ub_state_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int rc) | |||
| 1310 | * Factorization helper for the command state machine: | 1417 | * Factorization helper for the command state machine: |
| 1311 | * Submit a CSW read. | 1418 | * Submit a CSW read. |
| 1312 | */ | 1419 | */ |
| 1313 | static void __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | 1420 | static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd) |
| 1314 | { | 1421 | { |
| 1315 | int rc; | 1422 | int rc; |
| 1316 | 1423 | ||
| @@ -1328,11 +1435,12 @@ static void __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1328 | /* XXX Clear stalls */ | 1435 | /* XXX Clear stalls */ |
| 1329 | ub_complete(&sc->work_done); | 1436 | ub_complete(&sc->work_done); |
| 1330 | ub_state_done(sc, cmd, rc); | 1437 | ub_state_done(sc, cmd, rc); |
| 1331 | return; | 1438 | return -1; |
| 1332 | } | 1439 | } |
| 1333 | 1440 | ||
| 1334 | sc->work_timer.expires = jiffies + UB_STAT_TIMEOUT; | 1441 | sc->work_timer.expires = jiffies + UB_STAT_TIMEOUT; |
| 1335 | add_timer(&sc->work_timer); | 1442 | add_timer(&sc->work_timer); |
| 1443 | return 0; | ||
| 1336 | } | 1444 | } |
| 1337 | 1445 | ||
| 1338 | /* | 1446 | /* |
| @@ -1341,7 +1449,9 @@ static void __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1341 | */ | 1449 | */ |
| 1342 | static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | 1450 | static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd) |
| 1343 | { | 1451 | { |
| 1344 | __ub_state_stat(sc, cmd); | 1452 | |
| 1453 | if (__ub_state_stat(sc, cmd) != 0) | ||
| 1454 | return; | ||
| 1345 | 1455 | ||
| 1346 | cmd->stat_count = 0; | 1456 | cmd->stat_count = 0; |
| 1347 | cmd->state = UB_CMDST_STAT; | 1457 | cmd->state = UB_CMDST_STAT; |
| @@ -1350,6 +1460,25 @@ static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
| 1350 | 1460 | ||
| 1351 | /* | 1461 | /* |
| 1352 | * Factorization helper for the command state machine: | 1462 | * Factorization helper for the command state machine: |
| 1463 | * Submit a CSW read and go to STAT state with counter (along [C] path). | ||
| 1464 | */ | ||
| 1465 | static void ub_state_stat_counted(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | ||
| 1466 | { | ||
| 1467 | |||
| 1468 | if (++cmd->stat_count >= 4) { | ||
| 1469 | ub_state_sense(sc, cmd); | ||
| 1470 | return; | ||
| 1471 | } | ||
| 1472 | |||
| 1473 | if (__ub_state_stat(sc, cmd) != 0) | ||
| 1474 | return; | ||
| 1475 | |||
| 1476 | cmd->state = UB_CMDST_STAT; | ||
| 1477 | ub_cmdtr_state(sc, cmd); | ||
| 1478 | } | ||
| 1479 | |||
| 1480 | /* | ||
| 1481 | * Factorization helper for the command state machine: | ||
| 1353 | * Submit a REQUEST SENSE and go to SENSE state. | 1482 | * Submit a REQUEST SENSE and go to SENSE state. |
| 1354 | */ | 1483 | */ |
| 1355 | static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | 1484 | static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd) |
