static void idefloppy_create_rw_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc, struct request *rq, unsigned long sector) { struct ide_disk_obj *floppy = drive->driver_data; int block = sector / floppy->bs_factor; int blocks = rq->nr_sectors / floppy->bs_factor; int cmd = rq_data_dir(rq); 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; put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]); put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]); memcpy(rq->cmd, pc->c, 12); pc->rq = rq; if (rq->cmd_flags & REQ_RW) pc->flags |= PC_FLAG_WRITING; pc->buf = NULL; pc->req_xfer = pc->buf_size = blocks * floppy->block_size; pc->flags |= PC_FLAG_DMA_OK; }
/* * Called when an error was detected during the last packet command. * We queue a request sense packet command at the head of the request * queue. */ void ide_retry_pc(ide_drive_t *drive) { struct request *failed_rq = drive->hwif->rq; struct request *sense_rq = &drive->sense_rq; struct ide_atapi_pc *pc = &drive->request_sense_pc; (void)ide_read_error(drive); /* init pc from sense_rq */ ide_init_pc(pc); memcpy(pc->c, sense_rq->cmd, 12); if (drive->media == ide_tape) drive->atapi_flags |= IDE_AFLAG_IGNORE_DSC; /* * Push back the failed request and put request sense on top * of it. The failed command will be retried after sense data * is acquired. */ drive->hwif->rq = NULL; ide_requeue_and_plug(drive, failed_rq); if (ide_queue_sense_rq(drive, pc)) { blk_start_request(failed_rq); ide_complete_rq(drive, -EIO, blk_rq_bytes(failed_rq)); } }
void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) { ide_init_pc(pc); pc->c[0] = GPCMD_READ_FORMAT_CAPACITIES; pc->c[7] = 255; pc->c[8] = 255; pc->req_xfer = 255; }
int ide_do_test_unit_ready(ide_drive_t *drive, struct gendisk *disk) { struct ide_atapi_pc pc; ide_init_pc(&pc); pc.c[0] = TEST_UNIT_READY; return ide_queue_pc_tail(drive, disk, &pc, NULL, 0); }
static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy, struct ide_atapi_pc *pc, struct request *rq) { ide_init_pc(pc); memcpy(pc->c, rq->cmd, sizeof(pc->c)); pc->rq = rq; if (blk_rq_bytes(rq)) { pc->flags |= PC_FLAG_DMA_OK; if (rq_data_dir(rq) == WRITE) pc->flags |= PC_FLAG_WRITING; } }
void ide_create_request_sense_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc) { ide_init_pc(pc); pc->c[0] = REQUEST_SENSE; if (drive->media == ide_floppy) { pc->c[4] = 255; pc->req_xfer = 18; } else { pc->c[4] = 20; pc->req_xfer = 20; } }
int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on) { struct ide_atapi_pc pc; if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) return 0; ide_init_pc(&pc); pc.c[0] = ALLOW_MEDIUM_REMOVAL; pc.c[4] = on; return ide_queue_pc_tail(drive, disk, &pc, NULL, 0); }
int ide_do_start_stop(ide_drive_t *drive, struct gendisk *disk, int start) { struct ide_atapi_pc pc; ide_init_pc(&pc); pc.c[0] = START_STOP; pc.c[4] = start; if (drive->media == ide_tape) pc.flags |= PC_FLAG_WAIT_FOR_DSC; return ide_queue_pc_tail(drive, disk, &pc, NULL, 0); }
static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy, struct ide_atapi_pc *pc, struct request *rq) { ide_init_pc(pc); memcpy(pc->c, rq->cmd, sizeof(pc->c)); pc->rq = rq; if (rq->data_len && rq_data_dir(rq) == WRITE) pc->flags |= PC_FLAG_WRITING; pc->buf = rq->data; if (rq->bio) pc->flags |= PC_FLAG_DMA_OK; /* * possibly problematic, doesn't look like ide-floppy correctly * handled scattered requests if dma fails... */ pc->req_xfer = pc->buf_size = rq->data_len; }
void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code) { u16 length = 8; ide_init_pc(pc); pc->c[0] = GPCMD_MODE_SENSE_10; pc->c[1] = 0; pc->c[2] = page_code; switch (page_code) { case IDEFLOPPY_CAPABILITIES_PAGE: length += 12; break; case IDEFLOPPY_FLEXIBLE_DISK_PAGE: length += 32; break; default: printk(KERN_ERR PFX "unsupported page code in %s\n", __func__); } put_unaligned(cpu_to_be16(length), (u16 *) &pc->c[7]); pc->req_xfer = length; }