aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-floppy.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-floppy.c')
-rw-r--r--drivers/ide/ide-floppy.c156
1 files changed, 64 insertions, 92 deletions
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 317ec62c33d4..7ae662334835 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -61,50 +61,6 @@
61 */ 61 */
62#define IDEFLOPPY_PC_DELAY (HZ/20) /* default delay for ZIP 100 (50ms) */ 62#define IDEFLOPPY_PC_DELAY (HZ/20) /* default delay for ZIP 100 (50ms) */
63 63
64/* Error code returned in rq->errors to the higher part of the driver. */
65#define IDEFLOPPY_ERROR_GENERAL 101
66
67/*
68 * Used to finish servicing a request. For read/write requests, we will call
69 * ide_end_request to pass to the next buffer.
70 */
71static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs)
72{
73 struct ide_disk_obj *floppy = drive->driver_data;
74 struct request *rq = drive->hwif->rq;
75 int error;
76
77 ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
78
79 switch (uptodate) {
80 case 0:
81 error = IDEFLOPPY_ERROR_GENERAL;
82 break;
83
84 case 1:
85 error = 0;
86 break;
87
88 default:
89 error = uptodate;
90 }
91
92 if (error)
93 floppy->failed_pc = NULL;
94 /* Why does this happen? */
95 if (!rq)
96 return 0;
97 if (!blk_special_request(rq)) {
98 /* our real local end request function */
99 ide_end_request(drive, uptodate, nsecs);
100 return 0;
101 }
102 rq->errors = error;
103 /* fixme: need to move this local also */
104 ide_end_drive_cmd(drive, 0, 0);
105 return 0;
106}
107
108static void idefloppy_update_buffers(ide_drive_t *drive, 64static void idefloppy_update_buffers(ide_drive_t *drive,
109 struct ide_atapi_pc *pc) 65 struct ide_atapi_pc *pc)
110{ 66{
@@ -112,22 +68,23 @@ static void idefloppy_update_buffers(ide_drive_t *drive,
112 struct bio *bio = rq->bio; 68 struct bio *bio = rq->bio;
113 69
114 while ((bio = rq->bio) != NULL) 70 while ((bio = rq->bio) != NULL)
115 ide_floppy_end_request(drive, 1, 0); 71 ide_complete_rq(drive, 0, ide_rq_bytes(rq));
116} 72}
117 73
118static void ide_floppy_callback(ide_drive_t *drive, int dsc) 74static int ide_floppy_callback(ide_drive_t *drive, int dsc)
119{ 75{
120 struct ide_disk_obj *floppy = drive->driver_data; 76 struct ide_disk_obj *floppy = drive->driver_data;
121 struct ide_atapi_pc *pc = drive->pc; 77 struct ide_atapi_pc *pc = drive->pc;
78 struct request *rq = pc->rq;
122 int uptodate = pc->error ? 0 : 1; 79 int uptodate = pc->error ? 0 : 1;
123 80
124 ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); 81 ide_debug_log(IDE_DBG_FUNC, "enter");
125 82
126 if (floppy->failed_pc == pc) 83 if (drive->failed_pc == pc)
127 floppy->failed_pc = NULL; 84 drive->failed_pc = NULL;
128 85
129 if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 || 86 if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 ||
130 (pc->rq && blk_pc_request(pc->rq))) 87 (rq && blk_pc_request(rq)))
131 uptodate = 1; /* FIXME */ 88 uptodate = 1; /* FIXME */
132 else if (pc->c[0] == GPCMD_REQUEST_SENSE) { 89 else if (pc->c[0] == GPCMD_REQUEST_SENSE) {
133 u8 *buf = pc->buf; 90 u8 *buf = pc->buf;
@@ -139,19 +96,22 @@ static void ide_floppy_callback(ide_drive_t *drive, int dsc)
139 floppy->progress_indication = buf[15] & 0x80 ? 96 floppy->progress_indication = buf[15] & 0x80 ?
140 (u16)get_unaligned((u16 *)&buf[16]) : 0x10000; 97 (u16)get_unaligned((u16 *)&buf[16]) : 0x10000;
141 98
142 if (floppy->failed_pc) 99 if (drive->failed_pc)
143 ide_debug_log(IDE_DBG_PC, "pc = %x, ", 100 ide_debug_log(IDE_DBG_PC, "pc = %x",
144 floppy->failed_pc->c[0]); 101 drive->failed_pc->c[0]);
145 102
146 ide_debug_log(IDE_DBG_SENSE, "sense key = %x, asc = %x," 103 ide_debug_log(IDE_DBG_SENSE, "sense key = %x, asc = %x,"
147 "ascq = %x\n", floppy->sense_key, 104 "ascq = %x", floppy->sense_key,
148 floppy->asc, floppy->ascq); 105 floppy->asc, floppy->ascq);
149 } else 106 } else
150 printk(KERN_ERR PFX "Error in REQUEST SENSE itself - " 107 printk(KERN_ERR PFX "Error in REQUEST SENSE itself - "
151 "Aborting request!\n"); 108 "Aborting request!\n");
152 } 109 }
153 110
154 ide_floppy_end_request(drive, uptodate, 0); 111 if (blk_special_request(rq))
112 rq->errors = uptodate ? 0 : IDE_DRV_ERROR_GENERAL;
113
114 return uptodate;
155} 115}
156 116
157static void ide_floppy_report_error(struct ide_disk_obj *floppy, 117static void ide_floppy_report_error(struct ide_disk_obj *floppy,
@@ -170,14 +130,15 @@ static void ide_floppy_report_error(struct ide_disk_obj *floppy,
170 130
171} 131}
172 132
173static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, 133static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive,
174 struct ide_atapi_pc *pc) 134 struct ide_cmd *cmd,
135 struct ide_atapi_pc *pc)
175{ 136{
176 struct ide_disk_obj *floppy = drive->driver_data; 137 struct ide_disk_obj *floppy = drive->driver_data;
177 138
178 if (floppy->failed_pc == NULL && 139 if (drive->failed_pc == NULL &&
179 pc->c[0] != GPCMD_REQUEST_SENSE) 140 pc->c[0] != GPCMD_REQUEST_SENSE)
180 floppy->failed_pc = pc; 141 drive->failed_pc = pc;
181 142
182 /* Set the current packet command */ 143 /* Set the current packet command */
183 drive->pc = pc; 144 drive->pc = pc;
@@ -186,18 +147,18 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
186 if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR)) 147 if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR))
187 ide_floppy_report_error(floppy, pc); 148 ide_floppy_report_error(floppy, pc);
188 /* Giving up */ 149 /* Giving up */
189 pc->error = IDEFLOPPY_ERROR_GENERAL; 150 pc->error = IDE_DRV_ERROR_GENERAL;
190 151
191 floppy->failed_pc = NULL; 152 drive->failed_pc = NULL;
192 drive->pc_callback(drive, 0); 153 drive->pc_callback(drive, 0);
193 return ide_stopped; 154 return ide_stopped;
194 } 155 }
195 156
196 ide_debug_log(IDE_DBG_FUNC, "%s: Retry #%d\n", __func__, pc->retries); 157 ide_debug_log(IDE_DBG_FUNC, "retry #%d", pc->retries);
197 158
198 pc->retries++; 159 pc->retries++;
199 160
200 return ide_issue_pc(drive); 161 return ide_issue_pc(drive, cmd);
201} 162}
202 163
203void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) 164void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)
@@ -242,8 +203,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
242 int blocks = rq->nr_sectors / floppy->bs_factor; 203 int blocks = rq->nr_sectors / floppy->bs_factor;
243 int cmd = rq_data_dir(rq); 204 int cmd = rq_data_dir(rq);
244 205
245 ide_debug_log(IDE_DBG_FUNC, "%s: block: %d, blocks: %d\n", __func__, 206 ide_debug_log(IDE_DBG_FUNC, "block: %d, blocks: %d", block, blocks);
246 block, blocks);
247 207
248 ide_init_pc(pc); 208 ide_init_pc(pc);
249 pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10; 209 pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10;
@@ -285,34 +245,34 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
285{ 245{
286 struct ide_disk_obj *floppy = drive->driver_data; 246 struct ide_disk_obj *floppy = drive->driver_data;
287 ide_hwif_t *hwif = drive->hwif; 247 ide_hwif_t *hwif = drive->hwif;
248 struct ide_cmd cmd;
288 struct ide_atapi_pc *pc; 249 struct ide_atapi_pc *pc;
289 250
290 ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, " 251 if (drive->debug_mask & IDE_DBG_RQ)
291 "errors: %d\n", 252 blk_dump_rq_flags(rq, (rq->rq_disk
292 __func__, rq->rq_disk ? rq->rq_disk->disk_name : "?", 253 ? rq->rq_disk->disk_name
293 rq->cmd[0], rq->cmd_type, rq->errors); 254 : "dev?"));
294
295 ide_debug_log(IDE_DBG_FUNC, "%s: sector: %ld, nr_sectors: %ld, "
296 "current_nr_sectors: %d\n",
297 __func__, (long)rq->sector, rq->nr_sectors,
298 rq->current_nr_sectors);
299 255
300 if (rq->errors >= ERROR_MAX) { 256 if (rq->errors >= ERROR_MAX) {
301 if (floppy->failed_pc) 257 if (drive->failed_pc) {
302 ide_floppy_report_error(floppy, floppy->failed_pc); 258 ide_floppy_report_error(floppy, drive->failed_pc);
303 else 259 drive->failed_pc = NULL;
260 } else
304 printk(KERN_ERR PFX "%s: I/O error\n", drive->name); 261 printk(KERN_ERR PFX "%s: I/O error\n", drive->name);
305 262
306 ide_floppy_end_request(drive, 0, 0); 263 if (blk_special_request(rq)) {
307 return ide_stopped; 264 rq->errors = 0;
265 ide_complete_rq(drive, 0, blk_rq_bytes(rq));
266 return ide_stopped;
267 } else
268 goto out_end;
308 } 269 }
309 if (blk_fs_request(rq)) { 270 if (blk_fs_request(rq)) {
310 if (((long)rq->sector % floppy->bs_factor) || 271 if (((long)rq->sector % floppy->bs_factor) ||
311 (rq->nr_sectors % floppy->bs_factor)) { 272 (rq->nr_sectors % floppy->bs_factor)) {
312 printk(KERN_ERR PFX "%s: unsupported r/w rq size\n", 273 printk(KERN_ERR PFX "%s: unsupported r/w rq size\n",
313 drive->name); 274 drive->name);
314 ide_floppy_end_request(drive, 0, 0); 275 goto out_end;
315 return ide_stopped;
316 } 276 }
317 pc = &floppy->queued_pc; 277 pc = &floppy->queued_pc;
318 idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); 278 idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block);
@@ -323,21 +283,33 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
323 idefloppy_blockpc_cmd(floppy, pc, rq); 283 idefloppy_blockpc_cmd(floppy, pc, rq);
324 } else { 284 } else {
325 blk_dump_rq_flags(rq, PFX "unsupported command in queue"); 285 blk_dump_rq_flags(rq, PFX "unsupported command in queue");
326 ide_floppy_end_request(drive, 0, 0); 286 goto out_end;
327 return ide_stopped;
328 } 287 }
329 288
289 memset(&cmd, 0, sizeof(cmd));
290
291 if (rq_data_dir(rq))
292 cmd.tf_flags |= IDE_TFLAG_WRITE;
293
294 cmd.rq = rq;
295
330 if (blk_fs_request(rq) || pc->req_xfer) { 296 if (blk_fs_request(rq) || pc->req_xfer) {
331 ide_init_sg_cmd(drive, rq); 297 ide_init_sg_cmd(&cmd, rq->nr_sectors << 9);
332 ide_map_sg(drive, rq); 298 ide_map_sg(drive, &cmd);
333 } 299 }
334 300
335 pc->sg = hwif->sg_table; 301 pc->sg = hwif->sg_table;
336 pc->sg_cnt = hwif->sg_nents; 302 pc->sg_cnt = cmd.sg_nents;
337 303
338 pc->rq = rq; 304 pc->rq = rq;
339 305
340 return idefloppy_issue_pc(drive, pc); 306 return ide_floppy_issue_pc(drive, &cmd, pc);
307out_end:
308 drive->failed_pc = NULL;
309 if (blk_fs_request(rq) == 0 && rq->errors == 0)
310 rq->errors = -EIO;
311 ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
312 return ide_stopped;
341} 313}
342 314
343/* 315/*
@@ -438,8 +410,9 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
438 length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]); 410 length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]);
439 411
440 ide_debug_log(IDE_DBG_PROBE, "Descriptor %d: %dkB, %d blocks, " 412 ide_debug_log(IDE_DBG_PROBE, "Descriptor %d: %dkB, %d blocks, "
441 "%d sector size\n", 413 "%d sector size",
442 i, blocks * length / 1024, blocks, length); 414 i, blocks * length / 1024,
415 blocks, length);
443 416
444 if (i) 417 if (i)
445 continue; 418 continue;
@@ -495,8 +468,8 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
495 "in drive\n", drive->name); 468 "in drive\n", drive->name);
496 break; 469 break;
497 } 470 }
498 ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d\n", 471 ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d",
499 pc.buf[desc_start + 4] & 0x03); 472 pc.buf[desc_start + 4] & 0x03);
500 } 473 }
501 474
502 /* Clik! disk does not support get_flexible_disk_page */ 475 /* Clik! disk does not support get_flexible_disk_page */
@@ -575,6 +548,5 @@ const struct ide_disk_ops ide_atapi_disk_ops = {
575 .init_media = ide_floppy_init_media, 548 .init_media = ide_floppy_init_media,
576 .set_doorlock = ide_set_media_lock, 549 .set_doorlock = ide_set_media_lock,
577 .do_request = ide_floppy_do_request, 550 .do_request = ide_floppy_do_request,
578 .end_request = ide_floppy_end_request,
579 .ioctl = ide_floppy_ioctl, 551 .ioctl = ide_floppy_ioctl,
580}; 552};