Commit f3a5d3f8a1a992376e3dd128ceee917cd1281da7

Authored by Christoph Hellwig
Committed by Christoph Hellwig
1 parent 90babde0

raw-posix: split hdev drivers

Instead of declaring one BlockDriver for all host devices declared one
for each type:  a generic one for normal disk devices, a Linux floppy
driver and a CDROM driver for Linux and FreeBSD.  This gets rid of a lot
of messy ifdefs and switching based on the type in the various removal
device methods.

block.c grows a new method to find the correct host device driver based
on OS-sepcific criteria, which will later into the actual drivers in a
later patch in this series.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Showing 2 changed files with 347 additions and 277 deletions
... ... @@ -249,32 +249,55 @@ static BlockDriver *find_protocol(const char *filename)
249 249 return NULL;
250 250 }
251 251  
252   -/* XXX: force raw format if block or character device ? It would
253   - simplify the BSD case */
254   -static BlockDriver *find_image_format(const char *filename)
  252 +/*
  253 + * Detect host devices. By convention, /dev/cdrom[N] is always
  254 + * recognized as a host CDROM.
  255 + */
  256 +#ifdef _WIN32
  257 +static BlockDriver *find_hdev_driver(const char *filename)
255 258 {
256   - int ret, score, score_max;
257   - BlockDriver *drv1, *drv;
258   - uint8_t buf[2048];
259   - BlockDriverState *bs;
260   -
261   - /* detect host devices. By convention, /dev/cdrom[N] is always
262   - recognized as a host CDROM */
263 259 if (strstart(filename, "/dev/cdrom", NULL))
264 260 return bdrv_find_format("host_device");
265   -#ifdef _WIN32
266 261 if (is_windows_drive(filename))
267 262 return bdrv_find_format("host_device");
  263 + return NULL;
  264 +}
268 265 #else
269   - {
270   - struct stat st;
271   - if (stat(filename, &st) >= 0 &&
  266 +static BlockDriver *find_hdev_driver(const char *filename)
  267 +{
  268 + struct stat st;
  269 +
  270 +#ifdef __linux__
  271 + if (strstart(filename, "/dev/fd", NULL))
  272 + return bdrv_find_format("host_floppy");
  273 + if (strstart(filename, "/dev/cd", NULL))
  274 + return bdrv_find_format("host_cdrom");
  275 +#elif defined(__FreeBSD__)
  276 + if (strstart(filename, "/dev/cd", NULL) ||
  277 + strstart(filename, "/dev/acd", NULL)) {
  278 + return bdrv_find_format("host_cdrom");
  279 + }
  280 +#else
  281 + if (strstart(filename, "/dev/cdrom", NULL))
  282 + return bdrv_find_format("host_device");
  283 +#endif
  284 +
  285 + if (stat(filename, &st) >= 0 &&
272 286 (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
273   - return bdrv_find_format("host_device");
274   - }
  287 + return bdrv_find_format("host_device");
275 288 }
  289 +
  290 + return NULL;
  291 +}
276 292 #endif
277 293  
  294 +static BlockDriver *find_image_format(const char *filename)
  295 +{
  296 + int ret, score, score_max;
  297 + BlockDriver *drv1, *drv;
  298 + uint8_t buf[2048];
  299 + BlockDriverState *bs;
  300 +
278 301 drv = find_protocol(filename);
279 302 /* no need to test disk image formats for vvfat */
280 303 if (drv && strcmp(drv->format_name, "vvfat") == 0)
... ... @@ -394,7 +417,10 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
394 417 if (flags & BDRV_O_FILE) {
395 418 drv = find_protocol(filename);
396 419 } else if (!drv) {
397   - drv = find_image_format(filename);
  420 + drv = find_hdev_driver(filename);
  421 + if (!drv) {
  422 + drv = find_image_format(filename);
  423 + }
398 424 }
399 425 if (!drv) {
400 426 ret = -ENOENT;
... ...
block/raw-posix.c
... ... @@ -119,11 +119,9 @@ static int posix_aio_init(void);
119 119 static int fd_open(BlockDriverState *bs);
120 120  
121 121 #if defined(__FreeBSD__)
122   -static int cd_open(BlockDriverState *bs);
  122 +static int cdrom_reopen(BlockDriverState *bs);
123 123 #endif
124 124  
125   -static int raw_is_inserted(BlockDriverState *bs);
126   -
127 125 static int raw_open_common(BlockDriverState *bs, const char *filename,
128 126 int flags)
129 127 {
... ... @@ -808,7 +806,7 @@ again:
808 806 if (size == 2048LL * (unsigned)-1)
809 807 size = 0;
810 808 /* XXX no disc? maybe we need to reopen... */
811   - if (size <= 0 && !reopened && cd_open(bs) >= 0) {
  809 + if (size <= 0 && !reopened && cdrom_reopen(bs) >= 0) {
812 810 reopened = 1;
813 811 goto again;
814 812 }
... ... @@ -958,7 +956,6 @@ kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex ma
958 956 static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
959 957 {
960 958 BDRVRawState *s = bs->opaque;
961   - int ret;
962 959  
963 960 #ifdef CONFIG_COCOA
964 961 if (strstart(filename, "/dev/cdrom", NULL)) {
... ... @@ -988,46 +985,13 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
988 985 #endif
989 986  
990 987 s->type = FTYPE_FILE;
991   -#if defined(__linux__)
992   - if (strstart(filename, "/dev/cd", NULL)) {
993   - /* open will not fail even if no CD is inserted */
994   - s->open_flags |= O_NONBLOCK;
995   - s->type = FTYPE_CD;
996   - } else if (strstart(filename, "/dev/fd", NULL)) {
997   - s->type = FTYPE_FD;
998   - /* open will not fail even if no floppy is inserted */
999   - s->open_flags |= O_NONBLOCK;
1000   -#ifdef CONFIG_AIO
1001   - } else if (strstart(filename, "/dev/sg", NULL)) {
  988 +#if defined(__linux__) && defined(CONFIG_AIO)
  989 + if (strstart(filename, "/dev/sg", NULL)) {
1002 990 bs->sg = 1;
1003   -#endif
1004 991 }
1005 992 #endif
1006   -#if defined(__FreeBSD__)
1007   - if (strstart(filename, "/dev/cd", NULL) ||
1008   - strstart(filename, "/dev/acd", NULL)) {
1009   - s->type = FTYPE_CD;
1010   - }
1011   -#endif
1012   -
1013   - ret = raw_open_common(bs, filename, flags);
1014   - if (ret)
1015   - return ret;
1016 993  
1017   -#if defined(__FreeBSD__)
1018   - /* make sure the door isnt locked at this time */
1019   - if (s->type == FTYPE_CD)
1020   - ioctl (s->fd, CDIOCALLOW);
1021   -#endif
1022   -#if defined(__linux__)
1023   - /* close fd so that we can reopen it as needed */
1024   - if (s->type == FTYPE_FD) {
1025   - close(s->fd);
1026   - s->fd = -1;
1027   - s->fd_media_changed = 1;
1028   - }
1029   -#endif
1030   - return 0;
  994 + return raw_open_common(bs, filename, flags);
1031 995 }
1032 996  
1033 997 #if defined(__linux__)
... ... @@ -1080,105 +1044,6 @@ static int fd_open(BlockDriverState *bs)
1080 1044 return 0;
1081 1045 }
1082 1046  
1083   -static int raw_is_inserted(BlockDriverState *bs)
1084   -{
1085   - BDRVRawState *s = bs->opaque;
1086   - int ret;
1087   -
1088   - switch(s->type) {
1089   - case FTYPE_CD:
1090   - ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1091   - if (ret == CDS_DISC_OK)
1092   - return 1;
1093   - else
1094   - return 0;
1095   - break;
1096   - case FTYPE_FD:
1097   - ret = fd_open(bs);
1098   - return (ret >= 0);
1099   - default:
1100   - return 1;
1101   - }
1102   -}
1103   -
1104   -/* currently only used by fdc.c, but a CD version would be good too */
1105   -static int raw_media_changed(BlockDriverState *bs)
1106   -{
1107   - BDRVRawState *s = bs->opaque;
1108   -
1109   - switch(s->type) {
1110   - case FTYPE_FD:
1111   - {
1112   - int ret;
1113   - /* XXX: we do not have a true media changed indication. It
1114   - does not work if the floppy is changed without trying
1115   - to read it */
1116   - fd_open(bs);
1117   - ret = s->fd_media_changed;
1118   - s->fd_media_changed = 0;
1119   -#ifdef DEBUG_FLOPPY
1120   - printf("Floppy changed=%d\n", ret);
1121   -#endif
1122   - return ret;
1123   - }
1124   - default:
1125   - return -ENOTSUP;
1126   - }
1127   -}
1128   -
1129   -static int raw_eject(BlockDriverState *bs, int eject_flag)
1130   -{
1131   - BDRVRawState *s = bs->opaque;
1132   -
1133   - switch(s->type) {
1134   - case FTYPE_CD:
1135   - if (eject_flag) {
1136   - if (ioctl (s->fd, CDROMEJECT, NULL) < 0)
1137   - perror("CDROMEJECT");
1138   - } else {
1139   - if (ioctl (s->fd, CDROMCLOSETRAY, NULL) < 0)
1140   - perror("CDROMEJECT");
1141   - }
1142   - break;
1143   - case FTYPE_FD:
1144   - {
1145   - int fd;
1146   - if (s->fd >= 0) {
1147   - close(s->fd);
1148   - s->fd = -1;
1149   - }
1150   - fd = open(bs->filename, s->open_flags | O_NONBLOCK);
1151   - if (fd >= 0) {
1152   - if (ioctl(fd, FDEJECT, 0) < 0)
1153   - perror("FDEJECT");
1154   - close(fd);
1155   - }
1156   - }
1157   - break;
1158   - default:
1159   - return -ENOTSUP;
1160   - }
1161   - return 0;
1162   -}
1163   -
1164   -static int raw_set_locked(BlockDriverState *bs, int locked)
1165   -{
1166   - BDRVRawState *s = bs->opaque;
1167   -
1168   - switch(s->type) {
1169   - case FTYPE_CD:
1170   - if (ioctl (s->fd, CDROM_LOCKDOOR, locked) < 0) {
1171   - /* Note: an error can happen if the distribution automatically
1172   - mounts the CD-ROM */
1173   - // perror("CDROM_LOCKDOOR");
1174   - }
1175   - break;
1176   - default:
1177   - return -ENOTSUP;
1178   - }
1179   - return 0;
1180   -}
1181   -
1182 1047 static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
1183 1048 {
1184 1049 BDRVRawState *s = bs->opaque;
... ... @@ -1220,7 +1085,6 @@ static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs,
1220 1085 #endif
1221 1086  
1222 1087 #elif defined(__FreeBSD__)
1223   -
1224 1088 static int fd_open(BlockDriverState *bs)
1225 1089 {
1226 1090 BDRVRawState *s = bs->opaque;
... ... @@ -1231,99 +1095,6 @@ static int fd_open(BlockDriverState *bs)
1231 1095 return -EIO;
1232 1096 }
1233 1097  
1234   -static int cd_open(BlockDriverState *bs)
1235   -{
1236   -#if defined(__FreeBSD__)
1237   - BDRVRawState *s = bs->opaque;
1238   - int fd;
1239   -
1240   - switch(s->type) {
1241   - case FTYPE_CD:
1242   - /* XXX force reread of possibly changed/newly loaded disc,
1243   - * FreeBSD seems to not notice sometimes... */
1244   - if (s->fd >= 0)
1245   - close (s->fd);
1246   - fd = open(bs->filename, s->open_flags, 0644);
1247   - if (fd < 0) {
1248   - s->fd = -1;
1249   - return -EIO;
1250   - }
1251   - s->fd = fd;
1252   - /* make sure the door isnt locked at this time */
1253   - ioctl (s->fd, CDIOCALLOW);
1254   - }
1255   -#endif
1256   - return 0;
1257   -}
1258   -
1259   -static int raw_is_inserted(BlockDriverState *bs)
1260   -{
1261   - BDRVRawState *s = bs->opaque;
1262   -
1263   - switch(s->type) {
1264   - case FTYPE_CD:
1265   - return (raw_getlength(bs) > 0);
1266   - case FTYPE_FD:
1267   - /* XXX handle this */
1268   - /* FALLTHRU */
1269   - default:
1270   - return 1;
1271   - }
1272   -}
1273   -
1274   -static int raw_media_changed(BlockDriverState *bs)
1275   -{
1276   - return -ENOTSUP;
1277   -}
1278   -
1279   -static int raw_eject(BlockDriverState *bs, int eject_flag)
1280   -{
1281   - BDRVRawState *s = bs->opaque;
1282   -
1283   - switch(s->type) {
1284   - case FTYPE_CD:
1285   - if (s->fd < 0)
1286   - return -ENOTSUP;
1287   - (void) ioctl (s->fd, CDIOCALLOW);
1288   - if (eject_flag) {
1289   - if (ioctl (s->fd, CDIOCEJECT) < 0)
1290   - perror("CDIOCEJECT");
1291   - } else {
1292   - if (ioctl (s->fd, CDIOCCLOSE) < 0)
1293   - perror("CDIOCCLOSE");
1294   - }
1295   - if (cd_open(bs) < 0)
1296   - return -ENOTSUP;
1297   - break;
1298   - case FTYPE_FD:
1299   - /* XXX handle this */
1300   - /* FALLTHRU */
1301   - default:
1302   - return -ENOTSUP;
1303   - }
1304   - return 0;
1305   -}
1306   -
1307   -static int raw_set_locked(BlockDriverState *bs, int locked)
1308   -{
1309   - BDRVRawState *s = bs->opaque;
1310   -
1311   - switch(s->type) {
1312   - case FTYPE_CD:
1313   - if (s->fd < 0)
1314   - return -ENOTSUP;
1315   - if (ioctl (s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) {
1316   - /* Note: an error can happen if the distribution automatically
1317   - mounts the CD-ROM */
1318   - // perror("CDROM_LOCKDOOR");
1319   - }
1320   - break;
1321   - default:
1322   - return -ENOTSUP;
1323   - }
1324   - return 0;
1325   -}
1326   -
1327 1098 static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
1328 1099 {
1329 1100 return -ENOTSUP;
... ... @@ -1335,26 +1106,6 @@ static int fd_open(BlockDriverState *bs)
1335 1106 return 0;
1336 1107 }
1337 1108  
1338   -static int raw_is_inserted(BlockDriverState *bs)
1339   -{
1340   - return 1;
1341   -}
1342   -
1343   -static int raw_media_changed(BlockDriverState *bs)
1344   -{
1345   - return -ENOTSUP;
1346   -}
1347   -
1348   -static int raw_eject(BlockDriverState *bs, int eject_flag)
1349   -{
1350   - return -ENOTSUP;
1351   -}
1352   -
1353   -static int raw_set_locked(BlockDriverState *bs, int locked)
1354   -{
1355   - return -ENOTSUP;
1356   -}
1357   -
1358 1109 static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
1359 1110 {
1360 1111 return -ENOTSUP;
... ... @@ -1415,22 +1166,315 @@ static BlockDriver bdrv_host_device = {
1415 1166 .bdrv_write = raw_write,
1416 1167 .bdrv_getlength = raw_getlength,
1417 1168  
  1169 + /* generic scsi device */
  1170 + .bdrv_ioctl = raw_ioctl,
  1171 +#ifdef CONFIG_AIO
  1172 + .bdrv_aio_ioctl = raw_aio_ioctl,
  1173 +#endif
  1174 +};
  1175 +
  1176 +#ifdef __linux__
  1177 +static int floppy_open(BlockDriverState *bs, const char *filename, int flags)
  1178 +{
  1179 + BDRVRawState *s = bs->opaque;
  1180 + int ret;
  1181 +
  1182 + posix_aio_init();
  1183 +
  1184 + s->type = FTYPE_FD;
  1185 + /* open will not fail even if no floppy is inserted */
  1186 + s->open_flags |= O_NONBLOCK;
  1187 +
  1188 + ret = raw_open_common(bs, filename, flags);
  1189 + if (ret)
  1190 + return ret;
  1191 +
  1192 + /* close fd so that we can reopen it as needed */
  1193 + close(s->fd);
  1194 + s->fd = -1;
  1195 + s->fd_media_changed = 1;
  1196 +
  1197 + return 0;
  1198 +}
  1199 +
  1200 +static int floppy_is_inserted(BlockDriverState *bs)
  1201 +{
  1202 + return fd_open(bs) >= 0;
  1203 +}
  1204 +
  1205 +static int floppy_media_changed(BlockDriverState *bs)
  1206 +{
  1207 + BDRVRawState *s = bs->opaque;
  1208 + int ret;
  1209 +
  1210 + /*
  1211 + * XXX: we do not have a true media changed indication.
  1212 + * It does not work if the floppy is changed without trying to read it.
  1213 + */
  1214 + fd_open(bs);
  1215 + ret = s->fd_media_changed;
  1216 + s->fd_media_changed = 0;
  1217 +#ifdef DEBUG_FLOPPY
  1218 + printf("Floppy changed=%d\n", ret);
  1219 +#endif
  1220 + return ret;
  1221 +}
  1222 +
  1223 +static int floppy_eject(BlockDriverState *bs, int eject_flag)
  1224 +{
  1225 + BDRVRawState *s = bs->opaque;
  1226 + int fd;
  1227 +
  1228 + if (s->fd >= 0) {
  1229 + close(s->fd);
  1230 + s->fd = -1;
  1231 + }
  1232 + fd = open(bs->filename, s->open_flags | O_NONBLOCK);
  1233 + if (fd >= 0) {
  1234 + if (ioctl(fd, FDEJECT, 0) < 0)
  1235 + perror("FDEJECT");
  1236 + close(fd);
  1237 + }
  1238 +
  1239 + return 0;
  1240 +}
  1241 +
  1242 +static BlockDriver bdrv_host_floppy = {
  1243 + .format_name = "host_floppy",
  1244 + .instance_size = sizeof(BDRVRawState),
  1245 + .bdrv_open = floppy_open,
  1246 + .bdrv_close = raw_close,
  1247 + .bdrv_create = hdev_create,
  1248 + .bdrv_flush = raw_flush,
  1249 +
  1250 +#ifdef CONFIG_AIO
  1251 + .bdrv_aio_readv = raw_aio_readv,
  1252 + .bdrv_aio_writev = raw_aio_writev,
  1253 +#endif
  1254 +
  1255 + .bdrv_read = raw_read,
  1256 + .bdrv_write = raw_write,
  1257 + .bdrv_getlength = raw_getlength,
  1258 +
  1259 + /* removable device support */
  1260 + .bdrv_is_inserted = floppy_is_inserted,
  1261 + .bdrv_media_changed = floppy_media_changed,
  1262 + .bdrv_eject = floppy_eject,
  1263 +
  1264 + /* generic scsi device */
  1265 + .bdrv_ioctl = raw_ioctl,
  1266 +#ifdef CONFIG_AIO
  1267 + .bdrv_aio_ioctl = raw_aio_ioctl,
  1268 +#endif
  1269 +};
  1270 +
  1271 +static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
  1272 +{
  1273 + BDRVRawState *s = bs->opaque;
  1274 +
  1275 + /* open will not fail even if no CD is inserted */
  1276 + s->open_flags |= O_NONBLOCK;
  1277 + s->type = FTYPE_CD;
  1278 +
  1279 + return raw_open_common(bs, filename, flags);
  1280 +}
  1281 +
  1282 +static int cdrom_is_inserted(BlockDriverState *bs)
  1283 +{
  1284 + BDRVRawState *s = bs->opaque;
  1285 + int ret;
  1286 +
  1287 + ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
  1288 + if (ret == CDS_DISC_OK)
  1289 + return 1;
  1290 + return 0;
  1291 +}
  1292 +
  1293 +static int cdrom_eject(BlockDriverState *bs, int eject_flag)
  1294 +{
  1295 + BDRVRawState *s = bs->opaque;
  1296 +
  1297 + if (eject_flag) {
  1298 + if (ioctl(s->fd, CDROMEJECT, NULL) < 0)
  1299 + perror("CDROMEJECT");
  1300 + } else {
  1301 + if (ioctl(s->fd, CDROMCLOSETRAY, NULL) < 0)
  1302 + perror("CDROMEJECT");
  1303 + }
  1304 +
  1305 + return 0;
  1306 +}
  1307 +
  1308 +static int cdrom_set_locked(BlockDriverState *bs, int locked)
  1309 +{
  1310 + BDRVRawState *s = bs->opaque;
  1311 +
  1312 + if (ioctl(s->fd, CDROM_LOCKDOOR, locked) < 0) {
  1313 + /*
  1314 + * Note: an error can happen if the distribution automatically
  1315 + * mounts the CD-ROM
  1316 + */
  1317 + /* perror("CDROM_LOCKDOOR"); */
  1318 + }
  1319 +
  1320 + return 0;
  1321 +}
  1322 +
  1323 +static BlockDriver bdrv_host_cdrom = {
  1324 + .format_name = "host_cdrom",
  1325 + .instance_size = sizeof(BDRVRawState),
  1326 + .bdrv_open = cdrom_open,
  1327 + .bdrv_close = raw_close,
  1328 + .bdrv_create = hdev_create,
  1329 + .bdrv_flush = raw_flush,
  1330 +
  1331 +#ifdef CONFIG_AIO
  1332 + .bdrv_aio_readv = raw_aio_readv,
  1333 + .bdrv_aio_writev = raw_aio_writev,
  1334 +#endif
  1335 +
  1336 + .bdrv_read = raw_read,
  1337 + .bdrv_write = raw_write,
  1338 + .bdrv_getlength = raw_getlength,
  1339 +
  1340 + /* removable device support */
  1341 + .bdrv_is_inserted = cdrom_is_inserted,
  1342 + .bdrv_eject = cdrom_eject,
  1343 + .bdrv_set_locked = cdrom_set_locked,
  1344 +
  1345 + /* generic scsi device */
  1346 + .bdrv_ioctl = raw_ioctl,
  1347 +#ifdef CONFIG_AIO
  1348 + .bdrv_aio_ioctl = raw_aio_ioctl,
  1349 +#endif
  1350 +};
  1351 +#endif /* __linux__ */
  1352 +
  1353 +#ifdef __FreeBSD__
  1354 +static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
  1355 +{
  1356 + BDRVRawState *s = bs->opaque;
  1357 + int ret;
  1358 +
  1359 + s->type = FTYPE_CD;
  1360 +
  1361 + ret = raw_open_common(bs, filename, flags);
  1362 + if (ret)
  1363 + return ret;
  1364 +
  1365 + /* make sure the door isnt locked at this time */
  1366 + ioctl(s->fd, CDIOCALLOW);
  1367 + return 0;
  1368 +}
  1369 +
  1370 +static int cdrom_reopen(BlockDriverState *bs)
  1371 +{
  1372 + BDRVRawState *s = bs->opaque;
  1373 + int fd;
  1374 +
  1375 + /*
  1376 + * Force reread of possibly changed/newly loaded disc,
  1377 + * FreeBSD seems to not notice sometimes...
  1378 + */
  1379 + if (s->fd >= 0)
  1380 + close(s->fd);
  1381 + fd = open(bs->filename, s->open_flags, 0644);
  1382 + if (fd < 0) {
  1383 + s->fd = -1;
  1384 + return -EIO;
  1385 + }
  1386 + s->fd = fd;
  1387 +
  1388 + /* make sure the door isnt locked at this time */
  1389 + ioctl(s->fd, CDIOCALLOW);
  1390 + return 0;
  1391 +}
  1392 +
  1393 +static int cdrom_is_inserted(BlockDriverState *bs)
  1394 +{
  1395 + return raw_getlength(bs) > 0;
  1396 +}
  1397 +
  1398 +static int cdrom_eject(BlockDriverState *bs, int eject_flag)
  1399 +{
  1400 + BDRVRawState *s = bs->opaque;
  1401 +
  1402 + if (s->fd < 0)
  1403 + return -ENOTSUP;
  1404 +
  1405 + (void) ioctl(s->fd, CDIOCALLOW);
  1406 +
  1407 + if (eject_flag) {
  1408 + if (ioctl(s->fd, CDIOCEJECT) < 0)
  1409 + perror("CDIOCEJECT");
  1410 + } else {
  1411 + if (ioctl(s->fd, CDIOCCLOSE) < 0)
  1412 + perror("CDIOCCLOSE");
  1413 + }
  1414 +
  1415 + if (cdrom_reopen(bs) < 0)
  1416 + return -ENOTSUP;
  1417 + return 0;
  1418 +}
  1419 +
  1420 +static int cdrom_set_locked(BlockDriverState *bs, int locked)
  1421 +{
  1422 + BDRVRawState *s = bs->opaque;
  1423 +
  1424 + if (s->fd < 0)
  1425 + return -ENOTSUP;
  1426 + if (ioctl(s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) {
  1427 + /*
  1428 + * Note: an error can happen if the distribution automatically
  1429 + * mounts the CD-ROM
  1430 + */
  1431 + /* perror("CDROM_LOCKDOOR"); */
  1432 + }
  1433 +
  1434 + return 0;
  1435 +}
  1436 +
  1437 +static BlockDriver bdrv_host_cdrom = {
  1438 + .format_name = "host_cdrom",
  1439 + .instance_size = sizeof(BDRVRawState),
  1440 + .bdrv_open = cdrom_open,
  1441 + .bdrv_close = raw_close,
  1442 + .bdrv_create = hdev_create,
  1443 + .bdrv_flush = raw_flush,
  1444 +
  1445 +#ifdef CONFIG_AIO
  1446 + .bdrv_aio_readv = raw_aio_readv,
  1447 + .bdrv_aio_writev = raw_aio_writev,
  1448 +#endif
  1449 +
  1450 + .bdrv_read = raw_read,
  1451 + .bdrv_write = raw_write,
  1452 + .bdrv_getlength = raw_getlength,
  1453 +
1418 1454 /* removable device support */
1419   - .bdrv_is_inserted = raw_is_inserted,
1420   - .bdrv_media_changed = raw_media_changed,
1421   - .bdrv_eject = raw_eject,
1422   - .bdrv_set_locked = raw_set_locked,
  1455 + .bdrv_is_inserted = cdrom_is_inserted,
  1456 + .bdrv_eject = cdrom_eject,
  1457 + .bdrv_set_locked = cdrom_set_locked,
  1458 +
1423 1459 /* generic scsi device */
1424   - .bdrv_ioctl = raw_ioctl,
  1460 + .bdrv_ioctl = raw_ioctl,
1425 1461 #ifdef CONFIG_AIO
1426   - .bdrv_aio_ioctl = raw_aio_ioctl,
  1462 + .bdrv_aio_ioctl = raw_aio_ioctl,
1427 1463 #endif
1428 1464 };
  1465 +#endif /* __FreeBSD__ */
1429 1466  
1430 1467 static void bdrv_raw_init(void)
1431 1468 {
1432 1469 bdrv_register(&bdrv_raw);
1433 1470 bdrv_register(&bdrv_host_device);
  1471 +#ifdef __linux__
  1472 + bdrv_register(&bdrv_host_floppy);
  1473 + bdrv_register(&bdrv_host_cdrom);
  1474 +#endif
  1475 +#ifdef __FreeBSD__
  1476 + bdrv_register(&bdrv_host_cdrom);
  1477 +#endif
1434 1478 }
1435 1479  
1436 1480 block_init(bdrv_raw_init);
... ...