History

scsi: sr: cdrom: Move cdrom_read_cdda_bpc() into the sr driver

cdrom_read_cdda_bpc() relies on sending SCSI command to the low level driver using a REQ_OP_SCSI_IN request. This isn't generic block layer functionality, so move the actual low-level code into the sr driver and call it through a new read_cdda_bpc method in the cdrom_device_ops structure. With this the CDROM code does not have to pull in scsi_normalize_sense() and depend on CONFIG_SCSI_COMMON.

Christoph Hellwig committed 5 years ago

Commit ba51bda1 parent 08dc2f93 files · +67 −66Browse files

Unified · Split

3 files
  1. drivers/cdrom/cdrom.c +8 −63
  2. drivers/scsi/sr.c +55 −1
  3. include/linux/cdrom.h +4 −2
drivers/cdrom/cdrom.c+8−63
@@ -629,7 +629,7 @@ int register_cdrom(struct gendisk *disk, struct cdrom_device_info *cdi) · 628 unmodified lines
629 if (CDROM_CAN(CDC_MRW_W))629 if (CDROM_CAN(CDC_MRW_W))
630 cdi->exit = cdrom_mrw_exit;630 cdi->exit = cdrom_mrw_exit;
631 631
632 if (cdi->disk)632 if (cdi->ops->read_cdda_bpc)
633 cdi->cdda_method = CDDA_BPC_FULL;633 cdi->cdda_method = CDDA_BPC_FULL;
634 else634 else
635 cdi->cdda_method = CDDA_OLD;635 cdi->cdda_method = CDDA_OLD;
@@ -2159,81 +2159,26 @@ static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf, · 1523 unmodified lines
2159static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,2159static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
2160 int lba, int nframes)2160 int lba, int nframes)
2161{2161{
2162 struct request_queue *q = cdi->disk->queue;2162 int max_frames = (queue_max_sectors(cdi->disk->queue) << 9) /
2163 struct request *rq;2163 CD_FRAMESIZE_RAW;
2164 struct scsi_request *req;
2165 struct bio *bio;
2166 unsigned int len;
2167 int nr, ret = 0;2164 int nr, ret = 0;
2168 2165
2169 if (!q)
2170 return -ENXIO;
2171
2172 if (!blk_queue_scsi_passthrough(q)) {
2173 WARN_ONCE(true,
2174 "Attempt read CDDA info through a non-SCSI queue\n");
2175 return -EINVAL;
2176 }
2177
2178 cdi->last_sense = 0;2166 cdi->last_sense = 0;
2179 2167
2180 while (nframes) {2168 while (nframes) {
2181 nr = nframes;
2182 if (cdi->cdda_method == CDDA_BPC_SINGLE)2169 if (cdi->cdda_method == CDDA_BPC_SINGLE)
2183 nr = 1;2170 nr = 1;
2184 if (nr * CD_FRAMESIZE_RAW > (queue_max_sectors(q) << 9))2171 else
2185 nr = (queue_max_sectors(q) << 9) / CD_FRAMESIZE_RAW;2172 nr = min(nframes, max_frames);
2186
2187 len = nr * CD_FRAMESIZE_RAW;
2188
2189 rq = blk_get_request(q, REQ_OP_DRV_IN, 0);
2190 if (IS_ERR(rq)) {
2191 ret = PTR_ERR(rq);
2192 break;
2193 }
2194 req = scsi_req(rq);
2195
2196 ret = blk_rq_map_user(q, rq, NULL, ubuf, len, GFP_KERNEL);
2197 if (ret) {
2198 blk_put_request(rq);
2199 break;
2200 }
2201
2202 req->cmd[0] = GPCMD_READ_CD;
2203 req->cmd[1] = 1 << 2;
2204 req->cmd[2] = (lba >> 24) & 0xff;
2205 req->cmd[3] = (lba >> 16) & 0xff;
2206 req->cmd[4] = (lba >> 8) & 0xff;
2207 req->cmd[5] = lba & 0xff;
2208 req->cmd[6] = (nr >> 16) & 0xff;
2209 req->cmd[7] = (nr >> 8) & 0xff;
2210 req->cmd[8] = nr & 0xff;
2211 req->cmd[9] = 0xf8;
2212
2213 req->cmd_len = 12;
2214 rq->timeout = 60 * HZ;
2215 bio = rq->bio;
2216
2217 blk_execute_rq(cdi->disk, rq, 0);
2218 if (scsi_req(rq)->result) {
2219 struct scsi_sense_hdr sshdr;
2220
2221 ret = -EIO;
2222 scsi_normalize_sense(req->sense, req->sense_len,
2223 &sshdr);
2224 cdi->last_sense = sshdr.sense_key;
2225 }
2226
2227 if (blk_rq_unmap_user(bio))
2228 ret = -EFAULT;
2229 blk_put_request(rq);
2230 2173
2174 ret = cdi->ops->read_cdda_bpc(cdi, ubuf, lba, nr,
2175 &cdi->last_sense);
2231 if (ret)2176 if (ret)
2232 break;2177 break;
2233 2178
2234 nframes -= nr;2179 nframes -= nr;
2235 lba += nr;2180 lba += nr;
2236 ubuf += len;2181 ubuf += (nr * CD_FRAMESIZE_RAW);
2237 }2182 }
2238 2183
2239 return ret;2184 return ret;
drivers/scsi/sr.c+55−1
@@ -120,6 +120,8 @@ static void get_capabilities(struct scsi_cd *); · 119 unmodified lines
120static unsigned int sr_check_events(struct cdrom_device_info *cdi,120static unsigned int sr_check_events(struct cdrom_device_info *cdi,
121 unsigned int clearing, int slot);121 unsigned int clearing, int slot);
122static int sr_packet(struct cdrom_device_info *, struct packet_command *);122static int sr_packet(struct cdrom_device_info *, struct packet_command *);
123static int sr_read_cdda_bpc(struct cdrom_device_info *cdi, void __user *ubuf,
124 u32 lba, u32 nr, u8 *last_sense);
123 125
124static const struct cdrom_device_ops sr_dops = {126static const struct cdrom_device_ops sr_dops = {
125 .open = sr_open,127 .open = sr_open,
@@ -133,8 +135,9 @@ static const struct cdrom_device_ops sr_dops = { · 7 unmodified lines
133 .get_mcn = sr_get_mcn,135 .get_mcn = sr_get_mcn,
134 .reset = sr_reset,136 .reset = sr_reset,
135 .audio_ioctl = sr_audio_ioctl,137 .audio_ioctl = sr_audio_ioctl,
136 .capability = SR_CAPABILITIES,
137 .generic_packet = sr_packet,138 .generic_packet = sr_packet,
139 .read_cdda_bpc = sr_read_cdda_bpc,
140 .capability = SR_CAPABILITIES,
138};141};
139 142
140static void sr_kref_release(struct kref *kref);143static void sr_kref_release(struct kref *kref);
@@ -951,6 +954,57 @@ static int sr_packet(struct cdrom_device_info *cdi, · 810 unmodified lines
951 return cgc->stat;954 return cgc->stat;
952}955}
953 956
957static int sr_read_cdda_bpc(struct cdrom_device_info *cdi, void __user *ubuf,
958 u32 lba, u32 nr, u8 *last_sense)
959{
960 struct gendisk *disk = cdi->disk;
961 u32 len = nr * CD_FRAMESIZE_RAW;
962 struct scsi_request *req;
963 struct request *rq;
964 struct bio *bio;
965 int ret;
966
967 rq = blk_get_request(disk->queue, REQ_OP_DRV_IN, 0);
968 if (IS_ERR(rq))
969 return PTR_ERR(rq);
970 req = scsi_req(rq);
971
972 ret = blk_rq_map_user(disk->queue, rq, NULL, ubuf, len, GFP_KERNEL);
973 if (ret)
974 goto out_put_request;
975
976 req->cmd[0] = GPCMD_READ_CD;
977 req->cmd[1] = 1 << 2;
978 req->cmd[2] = (lba >> 24) & 0xff;
979 req->cmd[3] = (lba >> 16) & 0xff;
980 req->cmd[4] = (lba >> 8) & 0xff;
981 req->cmd[5] = lba & 0xff;
982 req->cmd[6] = (nr >> 16) & 0xff;
983 req->cmd[7] = (nr >> 8) & 0xff;
984 req->cmd[8] = nr & 0xff;
985 req->cmd[9] = 0xf8;
986 req->cmd_len = 12;
987 rq->timeout = 60 * HZ;
988 bio = rq->bio;
989
990 blk_execute_rq(disk, rq, 0);
991 if (scsi_req(rq)->result) {
992 struct scsi_sense_hdr sshdr;
993
994 scsi_normalize_sense(req->sense, req->sense_len,
995 &sshdr);
996 *last_sense = sshdr.sense_key;
997 ret = -EIO;
998 }
999
1000 if (blk_rq_unmap_user(bio))
1001 ret = -EFAULT;
1002out_put_request:
1003 blk_put_request(rq);
1004 return ret;
1005}
1006
1007
954/**1008/**
955 * sr_kref_release - Called to free the scsi_cd structure1009 * sr_kref_release - Called to free the scsi_cd structure
956 * @kref: pointer to embedded kref1010 * @kref: pointer to embedded kref
include/linux/cdrom.h+4−2
@@ -86,11 +86,13 @@ struct cdrom_device_ops { · 85 unmodified lines
86 /* play stuff */86 /* play stuff */
87 int (*audio_ioctl) (struct cdrom_device_info *,unsigned int, void *);87 int (*audio_ioctl) (struct cdrom_device_info *,unsigned int, void *);
88 88
89/* driver specifications */
90 const int capability; /* capability flags */
91 /* handle uniform packets for scsi type devices (scsi,atapi) */89 /* handle uniform packets for scsi type devices (scsi,atapi) */
92 int (*generic_packet) (struct cdrom_device_info *,90 int (*generic_packet) (struct cdrom_device_info *,
93 struct packet_command *);91 struct packet_command *);
92 int (*read_cdda_bpc)(struct cdrom_device_info *cdi, void __user *ubuf,
93 u32 lba, u32 nframes, u8 *last_sense);
94/* driver specifications */
95 const int capability; /* capability flags */
94};96};
95 97
96int cdrom_multisession(struct cdrom_device_info *cdi,98int cdrom_multisession(struct cdrom_device_info *cdi,