Hi Bart, here's a first go at converting ide-floppy to using rq->cmd for packet commands. The code below is pretty rough and from what i can tell needs to be hammered a lot more, for it raises a lot of issues: 1. The command control (pc->callback, request type, etc) is still done using the pc pointer passed to all the functions prior to issuing the command. This, imho, can be done a lot cleaner and easier. What is the rationale here, do we want ide_atapi_pc removed in the long run and get by only with rq's as is the case with ide-cd? 2. I end up allocating all the requests on the stack just like the respective ide_atapi_pc structs and don't use the heap allocation facilities. I guess this will get resolved after we've decided on allocation scheme for the rq structs... In the meantime, the stack is probably gonna blow with additional sizeof(struct request). 3. idefloppy_queue_pc_{head,tail} turn into simple wrappers which begs for merging them but this is trivial. 4.Made rq->cmd_type = REQ_TYPE_ATA_PC from REQ_TYPE_SPECIAL but i guess the final goal is REQ_TYPE_BLOCK_PC. Will have to see how is this handled in the block layer and whether we're ready to do that. 5. This change is less intrusive but begs for a lot of simplification afterwards similar to ide-cd, which will probably get rid of all those create_.*_cmd() helpers. 6. Only compile-tested. Proper testing follows... -- commit 8359f6f7122e87c30467ff73895399b82610b835 Author: Borislav Petkov <petkovbb@xxxxxxxxx> Date: Tue Feb 12 10:06:55 2008 +0100 ide-floppy: use rq->cmd for preparing and sending packet cmds to the drive ... similar to the way it is done in ide-cd. Signed-off-by: Borislav Petkov <petkovbb@xxxxxxxxx> diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index bf1ef60..ab125ad 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -297,16 +297,9 @@ static void idefloppy_update_buffers(ide_drive_t *drive, * the current request so that it will be processed immediately, on the next * pass through the driver. */ -static void idefloppy_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc, - struct request *rq) +static void idefloppy_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc) { - struct ide_floppy_obj *floppy = drive->driver_data; - - ide_init_drive_cmd(rq); - rq->buffer = (char *) pc; - rq->cmd_type = REQ_TYPE_SPECIAL; - rq->rq_disk = floppy->disk; - (void) ide_do_drive_cmd(drive, rq, ide_preempt); + (void)ide_do_drive_cmd(drive, pc->rq, ide_preempt); } static struct ide_atapi_pc *idefloppy_next_pc_storage(ide_drive_t *drive) @@ -344,7 +337,7 @@ static void idefloppy_request_sense_callback(ide_drive_t *drive) if (floppy->failed_pc) debug_log("pc = %x, sense key = %x, asc = %x," " ascq = %x\n", - floppy->failed_pc->c[0], + floppy->failed_pc->rq->cmd[0], floppy->sense_key, floppy->asc, floppy->ascq); @@ -375,7 +368,6 @@ static void idefloppy_pc_callback(ide_drive_t *drive) static void idefloppy_init_pc(struct ide_atapi_pc *pc) { - memset(pc->c, 0, 12); pc->retries = 0; pc->flags = 0; pc->req_xfer = 0; @@ -384,11 +376,25 @@ static void idefloppy_init_pc(struct ide_atapi_pc *pc) pc->idefloppy_callback = &idefloppy_pc_callback; } -static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc) +void ide_floppy_init_rq(ide_drive_t *drive, struct request *rq) +{ + struct ide_floppy_obj *floppy = drive->driver_data; + + ide_init_drive_cmd(rq); + rq->cmd_type = REQ_TYPE_ATA_PC; + rq->rq_disk = floppy->disk; +} + +static void idefloppy_create_request_sense_cmd(ide_drive_t *drive, + struct ide_atapi_pc *pc) { + struct request *rq = pc->rq; + idefloppy_init_pc(pc); - pc->c[0] = GPCMD_REQUEST_SENSE; - pc->c[4] = 255; + ide_floppy_init_rq(drive, rq); + + rq->cmd[0] = GPCMD_REQUEST_SENSE; + rq->cmd[4] = 255; pc->req_xfer = 18; pc->idefloppy_callback = &idefloppy_request_sense_callback; } @@ -405,8 +411,8 @@ static void idefloppy_retry_pc(ide_drive_t *drive) (void)ide_read_error(drive); pc = idefloppy_next_pc_storage(drive); rq = idefloppy_next_rq_storage(drive); - idefloppy_create_request_sense_cmd(pc); - idefloppy_queue_pc_head(drive, pc, rq); + idefloppy_create_request_sense_cmd(drive, pc); + idefloppy_queue_pc_head(drive, pc); } /* The usual interrupt handler called during a packet command. */ @@ -452,7 +458,7 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) /* Error detected */ debug_log("%s: I/O error\n", drive->name); rq->errors++; - if (pc->c[0] == GPCMD_REQUEST_SENSE) { + if (rq->cmd[0] == GPCMD_REQUEST_SENSE) { printk(KERN_ERR "ide-floppy: I/O error in " "request sense command\n"); return ide_do_reset(drive); @@ -544,8 +550,9 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) static ide_startstop_t idefloppy_transfer_pc(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - ide_startstop_t startstop; idefloppy_floppy_t *floppy = drive->driver_data; + struct request *rq = floppy->pc->rq; + ide_startstop_t startstop; u8 ireason; if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { @@ -563,7 +570,7 @@ static ide_startstop_t idefloppy_transfer_pc(ide_drive_t *drive) /* Set the interrupt routine */ ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* Send the actual packet */ - HWIF(drive)->atapi_output_bytes(drive, floppy->pc->c, 12); + HWIF(drive)->atapi_output_bytes(drive, rq->cmd, 12); return ide_started; } @@ -583,7 +590,7 @@ static int idefloppy_transfer_pc2(ide_drive_t *drive) idefloppy_floppy_t *floppy = drive->driver_data; /* Send the actual packet */ - HWIF(drive)->atapi_output_bytes(drive, floppy->pc->c, 12); + HWIF(drive)->atapi_output_bytes(drive, floppy->pc->rq->cmd, 12); /* Timeout for the packet command */ return IDEFLOPPY_WAIT_CMD; } @@ -631,7 +638,7 @@ static void ide_floppy_report_error(idefloppy_floppy_t *floppy, printk(KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, " "asc = %2x, ascq = %2x\n", - floppy->drive->name, pc->c[0], floppy->sense_key, + floppy->drive->name, pc->rq->cmd[0], floppy->sense_key, floppy->asc, floppy->ascq); } @@ -642,11 +649,11 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, idefloppy_floppy_t *floppy = drive->driver_data; ide_hwif_t *hwif = drive->hwif; ide_handler_t *pkt_xfer_routine; + struct request *rq = pc->rq; u16 bcount; u8 dma; - if (floppy->failed_pc == NULL && - pc->c[0] != GPCMD_REQUEST_SENSE) + if (floppy->failed_pc == NULL && rq->cmd[0] != GPCMD_REQUEST_SENSE) floppy->failed_pc = pc; /* Set the current packet command */ floppy->pc = pc; @@ -719,30 +726,44 @@ static void idefloppy_rw_callback(ide_drive_t *drive) return; } -static void idefloppy_create_prevent_cmd(struct ide_atapi_pc *pc, int prevent) +static void idefloppy_create_prevent_cmd(ide_drive_t *drive, + struct ide_atapi_pc *pc, int prevent) { + struct request *rq = pc->rq; + debug_log("creating prevent removal command, prevent = %d\n", prevent); idefloppy_init_pc(pc); - pc->c[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; - pc->c[4] = prevent; + ide_floppy_init_rq(drive, rq); + + rq->cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; + rq->cmd[4] = prevent; } -static void idefloppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) +static void idefloppy_create_read_capacity_cmd(ide_drive_t *drive, + struct ide_atapi_pc *pc) { + struct request *rq = pc->rq; + idefloppy_init_pc(pc); - pc->c[0] = GPCMD_READ_FORMAT_CAPACITIES; - pc->c[7] = 255; - pc->c[8] = 255; + ide_floppy_init_rq(drive, rq); + + rq->cmd[0] = GPCMD_READ_FORMAT_CAPACITIES; + rq->cmd[7] = 255; + rq->cmd[8] = 255; pc->req_xfer = 255; } -static void idefloppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b, - int l, int flags) +static void idefloppy_create_format_unit_cmd(ide_drive_t *drive, + struct ide_atapi_pc *pc, int b, int l, int flags) { + struct request *rq = pc->rq; + idefloppy_init_pc(pc); - pc->c[0] = GPCMD_FORMAT_UNIT; - pc->c[1] = 0x17; + ide_floppy_init_rq(drive, rq); + + rq->cmd[0] = GPCMD_FORMAT_UNIT; + rq->cmd[1] = 0x17; memset(pc->buf, 0, 12); pc->buf[1] = 0xA2; @@ -759,15 +780,18 @@ static void idefloppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b, } /* A mode sense command is used to "sense" floppy parameters. */ -static void idefloppy_create_mode_sense_cmd(struct ide_atapi_pc *pc, - u8 page_code, u8 type) +static void idefloppy_create_mode_sense_cmd(ide_drive_t *drive, + struct ide_atapi_pc *pc, u8 page_code, u8 type) { u16 length = 8; /* sizeof(Mode Parameter Header) = 8 Bytes */ + struct request *rq = pc->rq; idefloppy_init_pc(pc); - pc->c[0] = GPCMD_MODE_SENSE_10; - pc->c[1] = 0; - pc->c[2] = page_code + (type << 6); + ide_floppy_init_rq(drive, rq); + + rq->cmd[0] = GPCMD_MODE_SENSE_10; + rq->cmd[1] = 0; + rq->cmd[2] = page_code + (type << 6); switch (page_code) { case IDEFLOPPY_CAPABILITIES_PAGE: @@ -777,24 +801,32 @@ static void idefloppy_create_mode_sense_cmd(struct ide_atapi_pc *pc, length += 32; break; default: - printk(KERN_ERR "ide-floppy: unsupported page code " - "in create_mode_sense_cmd\n"); + printk(KERN_ERR "ide-floppy: unsupported page code %s\n", + __func__); } - put_unaligned(cpu_to_be16(length), (u16 *) &pc->c[7]); + put_unaligned(cpu_to_be16(length), (u16 *) &rq->cmd[7]); pc->req_xfer = length; } -static void idefloppy_create_start_stop_cmd(struct ide_atapi_pc *pc, int start) +static void idefloppy_create_start_stop_cmd(ide_drive_t *drive, + struct ide_atapi_pc *pc, int start) { + struct request *rq = pc->rq; + idefloppy_init_pc(pc); - pc->c[0] = GPCMD_START_STOP_UNIT; - pc->c[4] = start; + ide_floppy_init_rq(drive, rq); + + rq->cmd[0] = GPCMD_START_STOP_UNIT; + rq->cmd[4] = start; } -static void idefloppy_create_test_unit_ready_cmd(struct ide_atapi_pc *pc) +static void idefloppy_create_test_unit_ready_cmd(ide_drive_t *drive, + struct ide_atapi_pc *pc) { idefloppy_init_pc(pc); - pc->c[0] = GPCMD_TEST_UNIT_READY; + ide_floppy_init_rq(drive, pc->rq); + + pc->rq->cmd[0] = GPCMD_TEST_UNIT_READY; } static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, @@ -809,9 +841,11 @@ static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, block, blocks); idefloppy_init_pc(pc); - pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10; - put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]); - put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]); + ide_floppy_init_rq(floppy->drive, rq); + + rq->cmd[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10; + put_unaligned(cpu_to_be16(blocks), (unsigned short *)&rq->cmd[7]); + put_unaligned(cpu_to_be32(block), (unsigned int *) &rq->cmd[2]); pc->idefloppy_callback = &idefloppy_rw_callback; pc->rq = rq; @@ -827,8 +861,8 @@ static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, struct ide_atapi_pc *pc, struct request *rq) { idefloppy_init_pc(pc); + pc->idefloppy_callback = &idefloppy_rw_callback; - memcpy(pc->c, rq->cmd, sizeof(pc->c)); pc->rq = rq; pc->b_count = rq->data_len; if (rq->data_len && rq_data_dir(rq) == WRITE) @@ -898,15 +932,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, */ static int idefloppy_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc) { - struct ide_floppy_obj *floppy = drive->driver_data; - struct request rq; - - ide_init_drive_cmd(&rq); - rq.buffer = (char *) pc; - rq.cmd_type = REQ_TYPE_SPECIAL; - rq.rq_disk = floppy->disk; - - return ide_do_drive_cmd(drive, &rq, ide_wait); + return ide_do_drive_cmd(drive, pc->rq, ide_wait); } /* @@ -917,13 +943,17 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; struct ide_atapi_pc pc; + struct request rq; + u8 *page; int capacity, lba_capacity; u16 transfer_rate, sector_size, cyls, rpm; u8 heads, sectors; - idefloppy_create_mode_sense_cmd(&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE, - MODE_SENSE_CURRENT); + pc.rq = &rq; + + idefloppy_create_mode_sense_cmd(drive, &pc, + IDEFLOPPY_FLEXIBLE_DISK_PAGE, MODE_SENSE_CURRENT); if (idefloppy_queue_pc_tail(drive, &pc)) { printk(KERN_ERR "ide-floppy: Can't get flexible disk page" @@ -969,9 +999,12 @@ static int idefloppy_get_sfrp_bit(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; struct ide_atapi_pc pc; + struct request rq; + + pc.rq = &rq; floppy->srfp = 0; - idefloppy_create_mode_sense_cmd(&pc, IDEFLOPPY_CAPABILITIES_PAGE, + idefloppy_create_mode_sense_cmd(drive, &pc, IDEFLOPPY_CAPABILITIES_PAGE, MODE_SENSE_CURRENT); pc.flags |= PC_FLAG_SUPPRESS_ERROR; @@ -990,17 +1023,20 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; struct ide_atapi_pc pc; + struct request rq; u8 *cap_desc; u8 header_len, desc_cnt; int i, rc = 1, blocks, length; + pc.rq = &rq; + drive->bios_cyl = 0; drive->bios_head = drive->bios_sect = 0; floppy->blocks = 0; floppy->bs_factor = 1; set_capacity(floppy->disk, 0); - idefloppy_create_read_capacity_cmd(&pc); + idefloppy_create_read_capacity_cmd(drive, &pc); if (idefloppy_queue_pc_tail(drive, &pc)) { printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n"); return 1; @@ -1102,6 +1138,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) { struct ide_atapi_pc pc; + struct request rq; u8 header_len, desc_cnt; int i, blocks, length, u_array_size, u_index; int __user *argp; @@ -1112,7 +1149,9 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) if (u_array_size <= 0) return (-EINVAL); - idefloppy_create_read_capacity_cmd(&pc); + pc.rq = &rq; + + idefloppy_create_read_capacity_cmd(drive, &pc); if (idefloppy_queue_pc_tail(drive, &pc)) { printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n"); return (-EIO); @@ -1167,10 +1206,13 @@ static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg) { idefloppy_floppy_t *floppy = drive->driver_data; struct ide_atapi_pc pc; + struct request rq; int progress_indication = 0x10000; + pc.rq = &rq; + if (floppy->srfp) { - idefloppy_create_request_sense_cmd(&pc); + idefloppy_create_request_sense_cmd(drive, &pc); if (idefloppy_queue_pc_tail(drive, &pc)) return (-EIO); @@ -1373,8 +1415,11 @@ static int idefloppy_open(struct inode *inode, struct file *filp) struct ide_floppy_obj *floppy; ide_drive_t *drive; struct ide_atapi_pc pc; + struct request rq; int ret = 0; + pc.rq = &rq; + debug_log("Reached %s\n", __func__); floppy = ide_floppy_get(disk); @@ -1389,9 +1434,9 @@ static int idefloppy_open(struct inode *inode, struct file *filp) floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS; /* Just in case */ - idefloppy_create_test_unit_ready_cmd(&pc); + idefloppy_create_test_unit_ready_cmd(drive, &pc); if (idefloppy_queue_pc_tail(drive, &pc)) { - idefloppy_create_start_stop_cmd(&pc, 1); + idefloppy_create_start_stop_cmd(drive, &pc, 1); (void) idefloppy_queue_pc_tail(drive, &pc); } @@ -1414,7 +1459,7 @@ static int idefloppy_open(struct inode *inode, struct file *filp) floppy->flags |= IDEFLOPPY_FLAG_MEDIA_CHANGED; /* IOMEGA Clik! drives do not support lock/unlock commands */ if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE)) { - idefloppy_create_prevent_cmd(&pc, 1); + idefloppy_create_prevent_cmd(drive, &pc, 1); (void) idefloppy_queue_pc_tail(drive, &pc); } check_disk_change(inode->i_bdev); @@ -1436,13 +1481,16 @@ static int idefloppy_release(struct inode *inode, struct file *filp) struct ide_floppy_obj *floppy = ide_floppy_g(disk); ide_drive_t *drive = floppy->drive; struct ide_atapi_pc pc; + struct request rq; + + pc.rq = &rq; debug_log("Reached %s\n", __func__); if (floppy->openers == 1) { /* IOMEGA Clik! drives do not support lock/unlock commands */ if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE)) { - idefloppy_create_prevent_cmd(&pc, 0); + idefloppy_create_prevent_cmd(drive, &pc, 0); (void) idefloppy_queue_pc_tail(drive, &pc); } @@ -1481,12 +1529,12 @@ static int ide_floppy_lockdoor(idefloppy_floppy_t *floppy, if (cmd == CDROMEJECT) prevent = 0; - idefloppy_create_prevent_cmd(pc, prevent); + idefloppy_create_prevent_cmd(floppy->drive, pc, prevent); (void) idefloppy_queue_pc_tail(floppy->drive, pc); } if (cmd == CDROMEJECT) { - idefloppy_create_start_stop_cmd(pc, 2); + idefloppy_create_start_stop_cmd(floppy->drive, pc, 2); (void) idefloppy_queue_pc_tail(floppy->drive, pc); } @@ -1498,6 +1546,10 @@ static int ide_floppy_format_unit(idefloppy_floppy_t *floppy, { int blocks, length, flags, err = 0; struct ide_atapi_pc pc; + struct request rq; + ide_drive_t *drive = floppy->drive; + + pc.rq = &rq; if (floppy->openers > 1) { /* Don't format if someone is using the disk */ @@ -1529,10 +1581,10 @@ static int ide_floppy_format_unit(idefloppy_floppy_t *floppy, goto out; } - (void) idefloppy_get_sfrp_bit(floppy->drive); - idefloppy_create_format_unit_cmd(&pc, blocks, length, flags); + (void) idefloppy_get_sfrp_bit(drive); + idefloppy_create_format_unit_cmd(drive, &pc, blocks, length, flags); - if (idefloppy_queue_pc_tail(floppy->drive, &pc)) + if (idefloppy_queue_pc_tail(drive, &pc)) err = -EIO; out: @@ -1549,9 +1601,12 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file, struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk); ide_drive_t *drive = floppy->drive; struct ide_atapi_pc pc; + struct request rq; void __user *argp = (void __user *)arg; int err; + pc.rq = &rq; + switch (cmd) { case CDROMEJECT: /* fall through */ -- Regards/Gruß, Boris. - To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html