Skip to content

Commit 6003352

Browse files
committed
ide: convert to blk-mq
ide-disk and ide-cd tested as working just fine, ide-tape and ide-floppy haven't. But the latter don't require changes, so they should work without issue. Add helper function to insert a request from a work queue, since we cannot invoke the blk-mq request insertion from IRQ context. Cc: David Miller <davem@davemloft.net> Reviewed-by: Hannes Reinecke <hare@suse.com> Tested-by: Ming Lei <ming.lei@redhat.com> Reviewed-by: Omar Sandoval <osandov@fb.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent d0be122 commit 6003352

File tree

8 files changed

+239
-179
lines changed

8 files changed

+239
-179
lines changed

drivers/ide/ide-atapi.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ EXPORT_SYMBOL_GPL(ide_create_request_sense_cmd);
172172
void ide_prep_sense(ide_drive_t *drive, struct request *rq)
173173
{
174174
struct request_sense *sense = &drive->sense_data;
175-
struct request *sense_rq = drive->sense_rq;
176-
struct scsi_request *req = scsi_req(sense_rq);
175+
struct request *sense_rq;
176+
struct scsi_request *req;
177177
unsigned int cmd_len, sense_len;
178178
int err;
179179

@@ -196,9 +196,16 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq)
196196
if (ata_sense_request(rq) || drive->sense_rq_armed)
197197
return;
198198

199+
sense_rq = drive->sense_rq;
200+
if (!sense_rq) {
201+
sense_rq = blk_mq_alloc_request(drive->queue, REQ_OP_DRV_IN,
202+
BLK_MQ_REQ_RESERVED | BLK_MQ_REQ_NOWAIT);
203+
drive->sense_rq = sense_rq;
204+
}
205+
req = scsi_req(sense_rq);
206+
199207
memset(sense, 0, sizeof(*sense));
200208

201-
blk_rq_init(rq->q, sense_rq);
202209
scsi_req_init(req);
203210

204211
err = blk_rq_map_kern(drive->queue, sense_rq, sense, sense_len,
@@ -207,6 +214,8 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq)
207214
if (printk_ratelimit())
208215
printk(KERN_WARNING PFX "%s: failed to map sense "
209216
"buffer\n", drive->name);
217+
blk_mq_free_request(sense_rq);
218+
drive->sense_rq = NULL;
210219
return;
211220
}
212221

@@ -226,19 +235,21 @@ EXPORT_SYMBOL_GPL(ide_prep_sense);
226235

227236
int ide_queue_sense_rq(ide_drive_t *drive, void *special)
228237
{
238+
struct request *sense_rq = drive->sense_rq;
239+
229240
/* deferred failure from ide_prep_sense() */
230241
if (!drive->sense_rq_armed) {
231242
printk(KERN_WARNING PFX "%s: error queuing a sense request\n",
232243
drive->name);
233244
return -ENOMEM;
234245
}
235246

236-
drive->sense_rq->special = special;
247+
sense_rq->special = special;
237248
drive->sense_rq_armed = false;
238249

239250
drive->hwif->rq = NULL;
240251

241-
elv_add_request(drive->queue, drive->sense_rq, ELEVATOR_INSERT_FRONT);
252+
ide_insert_request_head(drive, sense_rq);
242253
return 0;
243254
}
244255
EXPORT_SYMBOL_GPL(ide_queue_sense_rq);
@@ -270,10 +281,8 @@ void ide_retry_pc(ide_drive_t *drive)
270281
*/
271282
drive->hwif->rq = NULL;
272283
ide_requeue_and_plug(drive, failed_rq);
273-
if (ide_queue_sense_rq(drive, pc)) {
274-
blk_start_request(failed_rq);
284+
if (ide_queue_sense_rq(drive, pc))
275285
ide_complete_rq(drive, BLK_STS_IOERR, blk_rq_bytes(failed_rq));
276-
}
277286
}
278287
EXPORT_SYMBOL_GPL(ide_retry_pc);
279288

drivers/ide/ide-cd.c

Lines changed: 94 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -258,11 +258,22 @@ static int ide_cd_breathe(ide_drive_t *drive, struct request *rq)
258258
/*
259259
* take a breather
260260
*/
261-
blk_delay_queue(drive->queue, 1);
261+
blk_mq_requeue_request(rq, false);
262+
blk_mq_delay_kick_requeue_list(drive->queue, 1);
262263
return 1;
263264
}
264265
}
265266

267+
static void ide_cd_free_sense(ide_drive_t *drive)
268+
{
269+
if (!drive->sense_rq)
270+
return;
271+
272+
blk_mq_free_request(drive->sense_rq);
273+
drive->sense_rq = NULL;
274+
drive->sense_rq_armed = false;
275+
}
276+
266277
/**
267278
* Returns:
268279
* 0: if the request should be continued.
@@ -516,6 +527,82 @@ static bool ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
516527
return false;
517528
}
518529

530+
/* standard prep_rq_fn that builds 10 byte cmds */
531+
static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq)
532+
{
533+
int hard_sect = queue_logical_block_size(q);
534+
long block = (long)blk_rq_pos(rq) / (hard_sect >> 9);
535+
unsigned long blocks = blk_rq_sectors(rq) / (hard_sect >> 9);
536+
struct scsi_request *req = scsi_req(rq);
537+
538+
if (rq_data_dir(rq) == READ)
539+
req->cmd[0] = GPCMD_READ_10;
540+
else
541+
req->cmd[0] = GPCMD_WRITE_10;
542+
543+
/*
544+
* fill in lba
545+
*/
546+
req->cmd[2] = (block >> 24) & 0xff;
547+
req->cmd[3] = (block >> 16) & 0xff;
548+
req->cmd[4] = (block >> 8) & 0xff;
549+
req->cmd[5] = block & 0xff;
550+
551+
/*
552+
* and transfer length
553+
*/
554+
req->cmd[7] = (blocks >> 8) & 0xff;
555+
req->cmd[8] = blocks & 0xff;
556+
req->cmd_len = 10;
557+
return BLKPREP_OK;
558+
}
559+
560+
/*
561+
* Most of the SCSI commands are supported directly by ATAPI devices.
562+
* This transform handles the few exceptions.
563+
*/
564+
static int ide_cdrom_prep_pc(struct request *rq)
565+
{
566+
u8 *c = scsi_req(rq)->cmd;
567+
568+
/* transform 6-byte read/write commands to the 10-byte version */
569+
if (c[0] == READ_6 || c[0] == WRITE_6) {
570+
c[8] = c[4];
571+
c[5] = c[3];
572+
c[4] = c[2];
573+
c[3] = c[1] & 0x1f;
574+
c[2] = 0;
575+
c[1] &= 0xe0;
576+
c[0] += (READ_10 - READ_6);
577+
scsi_req(rq)->cmd_len = 10;
578+
return BLKPREP_OK;
579+
}
580+
581+
/*
582+
* it's silly to pretend we understand 6-byte sense commands, just
583+
* reject with ILLEGAL_REQUEST and the caller should take the
584+
* appropriate action
585+
*/
586+
if (c[0] == MODE_SENSE || c[0] == MODE_SELECT) {
587+
scsi_req(rq)->result = ILLEGAL_REQUEST;
588+
return BLKPREP_KILL;
589+
}
590+
591+
return BLKPREP_OK;
592+
}
593+
594+
static int ide_cdrom_prep_fn(ide_drive_t *drive, struct request *rq)
595+
{
596+
if (!blk_rq_is_passthrough(rq)) {
597+
scsi_req_init(scsi_req(rq));
598+
599+
return ide_cdrom_prep_fs(drive->queue, rq);
600+
} else if (blk_rq_is_scsi(rq))
601+
return ide_cdrom_prep_pc(rq);
602+
603+
return 0;
604+
}
605+
519606
static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
520607
{
521608
ide_hwif_t *hwif = drive->hwif;
@@ -675,7 +762,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
675762
out_end:
676763
if (blk_rq_is_scsi(rq) && rc == 0) {
677764
scsi_req(rq)->resid_len = 0;
678-
blk_end_request_all(rq, BLK_STS_OK);
765+
blk_mq_end_request(rq, BLK_STS_OK);
679766
hwif->rq = NULL;
680767
} else {
681768
if (sense && uptodate)
@@ -705,6 +792,8 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
705792
if (sense && rc == 2)
706793
ide_error(drive, "request sense failure", stat);
707794
}
795+
796+
ide_cd_free_sense(drive);
708797
return ide_stopped;
709798
}
710799

@@ -729,7 +818,7 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
729818
* We may be retrying this request after an error. Fix up any
730819
* weirdness which might be present in the request packet.
731820
*/
732-
q->prep_rq_fn(q, rq);
821+
ide_cdrom_prep_fn(drive, rq);
733822
}
734823

735824
/* fs requests *must* be hardware frame aligned */
@@ -1323,82 +1412,6 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
13231412
return nslots;
13241413
}
13251414

1326-
/* standard prep_rq_fn that builds 10 byte cmds */
1327-
static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq)
1328-
{
1329-
int hard_sect = queue_logical_block_size(q);
1330-
long block = (long)blk_rq_pos(rq) / (hard_sect >> 9);
1331-
unsigned long blocks = blk_rq_sectors(rq) / (hard_sect >> 9);
1332-
struct scsi_request *req = scsi_req(rq);
1333-
1334-
q->initialize_rq_fn(rq);
1335-
1336-
if (rq_data_dir(rq) == READ)
1337-
req->cmd[0] = GPCMD_READ_10;
1338-
else
1339-
req->cmd[0] = GPCMD_WRITE_10;
1340-
1341-
/*
1342-
* fill in lba
1343-
*/
1344-
req->cmd[2] = (block >> 24) & 0xff;
1345-
req->cmd[3] = (block >> 16) & 0xff;
1346-
req->cmd[4] = (block >> 8) & 0xff;
1347-
req->cmd[5] = block & 0xff;
1348-
1349-
/*
1350-
* and transfer length
1351-
*/
1352-
req->cmd[7] = (blocks >> 8) & 0xff;
1353-
req->cmd[8] = blocks & 0xff;
1354-
req->cmd_len = 10;
1355-
return BLKPREP_OK;
1356-
}
1357-
1358-
/*
1359-
* Most of the SCSI commands are supported directly by ATAPI devices.
1360-
* This transform handles the few exceptions.
1361-
*/
1362-
static int ide_cdrom_prep_pc(struct request *rq)
1363-
{
1364-
u8 *c = scsi_req(rq)->cmd;
1365-
1366-
/* transform 6-byte read/write commands to the 10-byte version */
1367-
if (c[0] == READ_6 || c[0] == WRITE_6) {
1368-
c[8] = c[4];
1369-
c[5] = c[3];
1370-
c[4] = c[2];
1371-
c[3] = c[1] & 0x1f;
1372-
c[2] = 0;
1373-
c[1] &= 0xe0;
1374-
c[0] += (READ_10 - READ_6);
1375-
scsi_req(rq)->cmd_len = 10;
1376-
return BLKPREP_OK;
1377-
}
1378-
1379-
/*
1380-
* it's silly to pretend we understand 6-byte sense commands, just
1381-
* reject with ILLEGAL_REQUEST and the caller should take the
1382-
* appropriate action
1383-
*/
1384-
if (c[0] == MODE_SENSE || c[0] == MODE_SELECT) {
1385-
scsi_req(rq)->result = ILLEGAL_REQUEST;
1386-
return BLKPREP_KILL;
1387-
}
1388-
1389-
return BLKPREP_OK;
1390-
}
1391-
1392-
static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq)
1393-
{
1394-
if (!blk_rq_is_passthrough(rq))
1395-
return ide_cdrom_prep_fs(q, rq);
1396-
else if (blk_rq_is_scsi(rq))
1397-
return ide_cdrom_prep_pc(rq);
1398-
1399-
return 0;
1400-
}
1401-
14021415
struct cd_list_entry {
14031416
const char *id_model;
14041417
const char *id_firmware;
@@ -1508,7 +1521,7 @@ static int ide_cdrom_setup(ide_drive_t *drive)
15081521

15091522
ide_debug_log(IDE_DBG_PROBE, "enter");
15101523

1511-
blk_queue_prep_rq(q, ide_cdrom_prep_fn);
1524+
drive->prep_rq = ide_cdrom_prep_fn;
15121525
blk_queue_dma_alignment(q, 31);
15131526
blk_queue_update_dma_pad(q, 15);
15141527

@@ -1569,7 +1582,7 @@ static void ide_cd_release(struct device *dev)
15691582
if (devinfo->handle == drive)
15701583
unregister_cdrom(devinfo);
15711584
drive->driver_data = NULL;
1572-
blk_queue_prep_rq(drive->queue, NULL);
1585+
drive->prep_rq = NULL;
15731586
g->private_data = NULL;
15741587
put_disk(g);
15751588
kfree(info);

drivers/ide/ide-disk.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -427,9 +427,8 @@ static void ide_disk_unlock_native_capacity(ide_drive_t *drive)
427427
drive->dev_flags |= IDE_DFLAG_NOHPA; /* disable HPA on resume */
428428
}
429429

430-
static int idedisk_prep_fn(struct request_queue *q, struct request *rq)
430+
static int idedisk_prep_fn(ide_drive_t *drive, struct request *rq)
431431
{
432-
ide_drive_t *drive = q->queuedata;
433432
struct ide_cmd *cmd;
434433

435434
if (req_op(rq) != REQ_OP_FLUSH)
@@ -548,7 +547,7 @@ static void update_flush(ide_drive_t *drive)
548547

549548
if (barrier) {
550549
wc = true;
551-
blk_queue_prep_rq(drive->queue, idedisk_prep_fn);
550+
drive->prep_rq = idedisk_prep_fn;
552551
}
553552
}
554553

0 commit comments

Comments
 (0)