*/
#define IDEFLOPPY_PC_DELAY (HZ/20) /* default delay for ZIP 100 (50ms) */
-/* Error code returned in rq->errors to the higher part of the driver. */
-#define IDEFLOPPY_ERROR_GENERAL 101
-
-/*
- * Used to finish servicing a request. For read/write requests, we will call
- * ide_end_request to pass to the next buffer.
- */
-static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs)
-{
- struct ide_disk_obj *floppy = drive->driver_data;
- struct request *rq = HWGROUP(drive)->rq;
- int error;
-
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
-
- switch (uptodate) {
- case 0:
- error = IDEFLOPPY_ERROR_GENERAL;
- break;
-
- case 1:
- error = 0;
- break;
-
- default:
- error = uptodate;
- }
-
- if (error)
- floppy->failed_pc = NULL;
- /* Why does this happen? */
- if (!rq)
- return 0;
- if (!blk_special_request(rq)) {
- /* our real local end request function */
- ide_end_request(drive, uptodate, nsecs);
- return 0;
- }
- rq->errors = error;
- /* fixme: need to move this local also */
- ide_end_drive_cmd(drive, 0, 0);
- return 0;
-}
-
static void idefloppy_update_buffers(ide_drive_t *drive,
struct ide_atapi_pc *pc)
{
struct bio *bio = rq->bio;
while ((bio = rq->bio) != NULL)
- ide_floppy_end_request(drive, 1, 0);
+ ide_complete_rq(drive, 0, ide_rq_bytes(rq));
}
-static void ide_floppy_callback(ide_drive_t *drive, int dsc)
+static int ide_floppy_callback(ide_drive_t *drive, int dsc)
{
struct ide_disk_obj *floppy = drive->driver_data;
struct ide_atapi_pc *pc = drive->pc;
+ struct request *rq = pc->rq;
int uptodate = pc->error ? 0 : 1;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
- if (floppy->failed_pc == pc)
- floppy->failed_pc = NULL;
+ if (drive->failed_pc == pc)
+ drive->failed_pc = NULL;
if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 ||
- (pc->rq && blk_pc_request(pc->rq)))
+ (rq && blk_pc_request(rq)))
uptodate = 1; /* FIXME */
else if (pc->c[0] == GPCMD_REQUEST_SENSE) {
u8 *buf = pc->buf;
floppy->progress_indication = buf[15] & 0x80 ?
(u16)get_unaligned((u16 *)&buf[16]) : 0x10000;
- if (floppy->failed_pc)
- ide_debug_log(IDE_DBG_PC, "pc = %x, ",
- floppy->failed_pc->c[0]);
+ if (drive->failed_pc)
+ ide_debug_log(IDE_DBG_PC, "pc = %x",
+ drive->failed_pc->c[0]);
ide_debug_log(IDE_DBG_SENSE, "sense key = %x, asc = %x,"
- "ascq = %x\n", floppy->sense_key,
+ "ascq = %x", floppy->sense_key,
floppy->asc, floppy->ascq);
} else
printk(KERN_ERR PFX "Error in REQUEST SENSE itself - "
"Aborting request!\n");
}
- ide_floppy_end_request(drive, uptodate, 0);
+ if (blk_special_request(rq))
+ rq->errors = uptodate ? 0 : IDE_DRV_ERROR_GENERAL;
+
+ return uptodate;
}
static void ide_floppy_report_error(struct ide_disk_obj *floppy,
{
struct ide_disk_obj *floppy = drive->driver_data;
- if (floppy->failed_pc == NULL &&
+ if (drive->failed_pc == NULL &&
pc->c[0] != GPCMD_REQUEST_SENSE)
- floppy->failed_pc = pc;
+ drive->failed_pc = pc;
/* Set the current packet command */
drive->pc = pc;
if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR))
ide_floppy_report_error(floppy, pc);
/* Giving up */
- pc->error = IDEFLOPPY_ERROR_GENERAL;
+ pc->error = IDE_DRV_ERROR_GENERAL;
- floppy->failed_pc = NULL;
+ drive->failed_pc = NULL;
drive->pc_callback(drive, 0);
return ide_stopped;
}
- ide_debug_log(IDE_DBG_FUNC, "%s: Retry #%d\n", __func__, pc->retries);
+ ide_debug_log(IDE_DBG_FUNC, "retry #%d", pc->retries);
pc->retries++;
- return ide_issue_pc(drive, WAIT_FLOPPY_CMD, NULL);
+ return ide_issue_pc(drive);
}
void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)
int blocks = rq->nr_sectors / floppy->bs_factor;
int cmd = rq_data_dir(rq);
- ide_debug_log(IDE_DBG_FUNC, "%s: block: %d, blocks: %d\n", __func__,
- block, blocks);
+ ide_debug_log(IDE_DBG_FUNC, "block: %d, blocks: %d", block, blocks);
ide_init_pc(pc);
pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10;
{
struct ide_disk_obj *floppy = drive->driver_data;
ide_hwif_t *hwif = drive->hwif;
+ struct ide_cmd *cmd = &hwif->cmd;
struct ide_atapi_pc *pc;
- ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, "
- "errors: %d\n",
- __func__, rq->rq_disk ? rq->rq_disk->disk_name : "?",
- rq->cmd[0], rq->cmd_type, rq->errors);
-
- ide_debug_log(IDE_DBG_FUNC, "%s: sector: %ld, nr_sectors: %ld, "
- "current_nr_sectors: %d\n",
- __func__, (long)rq->sector, rq->nr_sectors,
- rq->current_nr_sectors);
+ if (drive->debug_mask & IDE_DBG_RQ)
+ blk_dump_rq_flags(rq, (rq->rq_disk
+ ? rq->rq_disk->disk_name
+ : "dev?"));
if (rq->errors >= ERROR_MAX) {
- if (floppy->failed_pc)
- ide_floppy_report_error(floppy, floppy->failed_pc);
- else
+ if (drive->failed_pc) {
+ ide_floppy_report_error(floppy, drive->failed_pc);
+ drive->failed_pc = NULL;
+ } else
printk(KERN_ERR PFX "%s: I/O error\n", drive->name);
- ide_floppy_end_request(drive, 0, 0);
- return ide_stopped;
+ if (blk_special_request(rq)) {
+ rq->errors = 0;
+ ide_complete_rq(drive, 0, blk_rq_bytes(rq));
+ return ide_stopped;
+ } else
+ goto out_end;
}
if (blk_fs_request(rq)) {
if (((long)rq->sector % floppy->bs_factor) ||
(rq->nr_sectors % floppy->bs_factor)) {
printk(KERN_ERR PFX "%s: unsupported r/w rq size\n",
drive->name);
- ide_floppy_end_request(drive, 0, 0);
- return ide_stopped;
+ goto out_end;
}
pc = &floppy->queued_pc;
idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block);
idefloppy_blockpc_cmd(floppy, pc, rq);
} else {
blk_dump_rq_flags(rq, PFX "unsupported command in queue");
- ide_floppy_end_request(drive, 0, 0);
- return ide_stopped;
+ goto out_end;
}
- ide_init_sg_cmd(drive, rq);
- ide_map_sg(drive, rq);
+ if (blk_fs_request(rq) || pc->req_xfer) {
+ ide_init_sg_cmd(cmd, rq->nr_sectors);
+ ide_map_sg(drive, rq);
+ }
pc->sg = hwif->sg_table;
- pc->sg_cnt = hwif->sg_nents;
+ pc->sg_cnt = cmd->sg_nents;
pc->rq = rq;
return idefloppy_issue_pc(drive, pc);
+out_end:
+ drive->failed_pc = NULL;
+ if (blk_fs_request(rq) == 0 && rq->errors == 0)
+ rq->errors = -EIO;
+ ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
+ return ide_stopped;
}
/*
* Look at the flexible disk page parameters. We ignore the CHS capacity
* parameters and use the LBA parameters instead.
*/
-static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
+static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive,
+ struct ide_atapi_pc *pc)
{
struct ide_disk_obj *floppy = drive->driver_data;
struct gendisk *disk = floppy->disk;
- struct ide_atapi_pc pc;
u8 *page;
int capacity, lba_capacity;
u16 transfer_rate, sector_size, cyls, rpm;
u8 heads, sectors;
- ide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE);
+ ide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE);
- if (ide_queue_pc_tail(drive, disk, &pc)) {
+ if (ide_queue_pc_tail(drive, disk, pc)) {
printk(KERN_ERR PFX "Can't get flexible disk page params\n");
return 1;
}
- if (pc.buf[3] & 0x80)
+ if (pc->buf[3] & 0x80)
drive->dev_flags |= IDE_DFLAG_WP;
else
drive->dev_flags &= ~IDE_DFLAG_WP;
set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP));
- page = &pc.buf[8];
+ page = &pc->buf[8];
- transfer_rate = be16_to_cpup((__be16 *)&pc.buf[8 + 2]);
- sector_size = be16_to_cpup((__be16 *)&pc.buf[8 + 6]);
- cyls = be16_to_cpup((__be16 *)&pc.buf[8 + 8]);
- rpm = be16_to_cpup((__be16 *)&pc.buf[8 + 28]);
- heads = pc.buf[8 + 4];
- sectors = pc.buf[8 + 5];
+ transfer_rate = be16_to_cpup((__be16 *)&pc->buf[8 + 2]);
+ sector_size = be16_to_cpup((__be16 *)&pc->buf[8 + 6]);
+ cyls = be16_to_cpup((__be16 *)&pc->buf[8 + 8]);
+ rpm = be16_to_cpup((__be16 *)&pc->buf[8 + 28]);
+ heads = pc->buf[8 + 4];
+ sectors = pc->buf[8 + 5];
capacity = cyls * heads * sectors * sector_size;
length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]);
ide_debug_log(IDE_DBG_PROBE, "Descriptor %d: %dkB, %d blocks, "
- "%d sector size\n",
- i, blocks * length / 1024, blocks, length);
+ "%d sector size",
+ i, blocks * length / 1024,
+ blocks, length);
if (i)
continue;
"in drive\n", drive->name);
break;
}
- ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d\n",
- pc.buf[desc_start + 4] & 0x03);
+ ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d",
+ pc.buf[desc_start + 4] & 0x03);
}
/* Clik! disk does not support get_flexible_disk_page */
if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE))
- (void) ide_floppy_get_flexible_disk_page(drive);
+ (void) ide_floppy_get_flexible_disk_page(drive, &pc);
return rc;
}
.init_media = ide_floppy_init_media,
.set_doorlock = ide_set_media_lock,
.do_request = ide_floppy_do_request,
- .end_request = ide_floppy_end_request,
.ioctl = ide_floppy_ioctl,
};