Revision 9f23011a
b/block-raw-posix.c | ||
---|---|---|
55 | 55 |
#ifdef __FreeBSD__ |
56 | 56 |
#include <signal.h> |
57 | 57 |
#include <sys/disk.h> |
58 |
#include <sys/cdio.h> |
|
58 | 59 |
#endif |
59 | 60 |
|
60 | 61 |
#ifdef __OpenBSD__ |
... | ... | |
110 | 111 |
int fd_got_error; |
111 | 112 |
int fd_media_changed; |
112 | 113 |
#endif |
114 |
#if defined(__FreeBSD__) |
|
115 |
int cd_open_flags; |
|
116 |
#endif |
|
113 | 117 |
uint8_t* aligned_buf; |
114 | 118 |
} BDRVRawState; |
115 | 119 |
|
... | ... | |
117 | 121 |
|
118 | 122 |
static int fd_open(BlockDriverState *bs); |
119 | 123 |
|
124 |
#if defined(__FreeBSD__) |
|
125 |
static int cd_open(BlockDriverState *bs); |
|
126 |
#endif |
|
127 |
|
|
128 |
static int raw_is_inserted(BlockDriverState *bs); |
|
129 |
|
|
120 | 130 |
static int raw_open(BlockDriverState *bs, const char *filename, int flags) |
121 | 131 |
{ |
122 | 132 |
BDRVRawState *s = bs->opaque; |
... | ... | |
773 | 783 |
int64_t size; |
774 | 784 |
#ifdef HOST_BSD |
775 | 785 |
struct stat sb; |
786 |
#ifdef __FreeBSD__ |
|
787 |
int reopened = 0; |
|
788 |
#endif |
|
776 | 789 |
#endif |
777 | 790 |
#ifdef __sun__ |
778 | 791 |
struct dk_minfo minfo; |
... | ... | |
785 | 798 |
return ret; |
786 | 799 |
|
787 | 800 |
#ifdef HOST_BSD |
801 |
#ifdef __FreeBSD__ |
|
802 |
again: |
|
803 |
#endif |
|
788 | 804 |
if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) { |
789 | 805 |
#ifdef DIOCGMEDIASIZE |
790 | 806 |
if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size)) |
... | ... | |
803 | 819 |
#else |
804 | 820 |
size = lseek(fd, 0LL, SEEK_END); |
805 | 821 |
#endif |
822 |
#ifdef __FreeBSD__ |
|
823 |
switch(s->type) { |
|
824 |
case FTYPE_CD: |
|
825 |
/* XXX FreeBSD acd returns UINT_MAX sectors for an empty drive */ |
|
826 |
if (size == 2048LL * (unsigned)-1) |
|
827 |
size = 0; |
|
828 |
/* XXX no disc? maybe we need to reopen... */ |
|
829 |
if (size <= 0 && !reopened && cd_open(bs) >= 0) { |
|
830 |
reopened = 1; |
|
831 |
goto again; |
|
832 |
} |
|
833 |
} |
|
834 |
#endif |
|
806 | 835 |
} else |
807 | 836 |
#endif |
808 | 837 |
#ifdef __sun__ |
... | ... | |
993 | 1022 |
bs->sg = 1; |
994 | 1023 |
} |
995 | 1024 |
#endif |
1025 |
#if defined(__FreeBSD__) |
|
1026 |
if (strstart(filename, "/dev/cd", NULL) || |
|
1027 |
strstart(filename, "/dev/acd", NULL)) { |
|
1028 |
s->type = FTYPE_CD; |
|
1029 |
s->cd_open_flags = open_flags; |
|
1030 |
} |
|
1031 |
#endif |
|
1032 |
s->fd = -1; |
|
996 | 1033 |
fd = open(filename, open_flags, 0644); |
997 | 1034 |
if (fd < 0) { |
998 | 1035 |
ret = -errno; |
... | ... | |
1001 | 1038 |
return ret; |
1002 | 1039 |
} |
1003 | 1040 |
s->fd = fd; |
1041 |
#if defined(__FreeBSD__) |
|
1042 |
/* make sure the door isnt locked at this time */ |
|
1043 |
if (s->type == FTYPE_CD) |
|
1044 |
ioctl (s->fd, CDIOCALLOW); |
|
1045 |
#endif |
|
1004 | 1046 |
#if defined(__linux__) |
1005 | 1047 |
/* close fd so that we can reopen it as needed */ |
1006 | 1048 |
if (s->type == FTYPE_FD) { |
... | ... | |
1167 | 1209 |
|
1168 | 1210 |
return ioctl(s->fd, req, buf); |
1169 | 1211 |
} |
1170 |
#else |
|
1212 |
#elif defined(__FreeBSD__) |
|
1213 |
|
|
1214 |
static int fd_open(BlockDriverState *bs) |
|
1215 |
{ |
|
1216 |
BDRVRawState *s = bs->opaque; |
|
1217 |
|
|
1218 |
/* this is just to ensure s->fd is sane (its called by io ops) */ |
|
1219 |
if (s->fd >= 0) |
|
1220 |
return 0; |
|
1221 |
return -EIO; |
|
1222 |
} |
|
1223 |
|
|
1224 |
static int cd_open(BlockDriverState *bs) |
|
1225 |
{ |
|
1226 |
#if defined(__FreeBSD__) |
|
1227 |
BDRVRawState *s = bs->opaque; |
|
1228 |
int fd; |
|
1229 |
|
|
1230 |
switch(s->type) { |
|
1231 |
case FTYPE_CD: |
|
1232 |
/* XXX force reread of possibly changed/newly loaded disc, |
|
1233 |
* FreeBSD seems to not notice sometimes... */ |
|
1234 |
if (s->fd >= 0) |
|
1235 |
close (s->fd); |
|
1236 |
fd = open(bs->filename, s->cd_open_flags, 0644); |
|
1237 |
if (fd < 0) { |
|
1238 |
s->fd = -1; |
|
1239 |
return -EIO; |
|
1240 |
} |
|
1241 |
s->fd = fd; |
|
1242 |
/* make sure the door isnt locked at this time */ |
|
1243 |
ioctl (s->fd, CDIOCALLOW); |
|
1244 |
} |
|
1245 |
#endif |
|
1246 |
return 0; |
|
1247 |
} |
|
1248 |
|
|
1249 |
static int raw_is_inserted(BlockDriverState *bs) |
|
1250 |
{ |
|
1251 |
BDRVRawState *s = bs->opaque; |
|
1252 |
|
|
1253 |
switch(s->type) { |
|
1254 |
case FTYPE_CD: |
|
1255 |
return (raw_getlength(bs) > 0); |
|
1256 |
case FTYPE_FD: |
|
1257 |
/* XXX handle this */ |
|
1258 |
/* FALLTHRU */ |
|
1259 |
default: |
|
1260 |
return 1; |
|
1261 |
} |
|
1262 |
} |
|
1263 |
|
|
1264 |
static int raw_media_changed(BlockDriverState *bs) |
|
1265 |
{ |
|
1266 |
return -ENOTSUP; |
|
1267 |
} |
|
1268 |
|
|
1269 |
static int raw_eject(BlockDriverState *bs, int eject_flag) |
|
1270 |
{ |
|
1271 |
BDRVRawState *s = bs->opaque; |
|
1272 |
|
|
1273 |
switch(s->type) { |
|
1274 |
case FTYPE_CD: |
|
1275 |
if (s->fd < 0) |
|
1276 |
return -ENOTSUP; |
|
1277 |
(void) ioctl (s->fd, CDIOCALLOW); |
|
1278 |
if (eject_flag) { |
|
1279 |
if (ioctl (s->fd, CDIOCEJECT) < 0) |
|
1280 |
perror("CDIOCEJECT"); |
|
1281 |
} else { |
|
1282 |
if (ioctl (s->fd, CDIOCCLOSE) < 0) |
|
1283 |
perror("CDIOCCLOSE"); |
|
1284 |
} |
|
1285 |
if (cd_open(bs) < 0) |
|
1286 |
return -ENOTSUP; |
|
1287 |
break; |
|
1288 |
case FTYPE_FD: |
|
1289 |
/* XXX handle this */ |
|
1290 |
/* FALLTHRU */ |
|
1291 |
default: |
|
1292 |
return -ENOTSUP; |
|
1293 |
} |
|
1294 |
return 0; |
|
1295 |
} |
|
1296 |
|
|
1297 |
static int raw_set_locked(BlockDriverState *bs, int locked) |
|
1298 |
{ |
|
1299 |
BDRVRawState *s = bs->opaque; |
|
1300 |
|
|
1301 |
switch(s->type) { |
|
1302 |
case FTYPE_CD: |
|
1303 |
if (s->fd < 0) |
|
1304 |
return -ENOTSUP; |
|
1305 |
if (ioctl (s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) { |
|
1306 |
/* Note: an error can happen if the distribution automatically |
|
1307 |
mounts the CD-ROM */ |
|
1308 |
// perror("CDROM_LOCKDOOR"); |
|
1309 |
} |
|
1310 |
break; |
|
1311 |
default: |
|
1312 |
return -ENOTSUP; |
|
1313 |
} |
|
1314 |
return 0; |
|
1315 |
} |
|
1316 |
|
|
1317 |
static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf) |
|
1318 |
{ |
|
1319 |
return -ENOTSUP; |
|
1320 |
} |
|
1321 |
#else /* !linux && !FreeBSD */ |
|
1171 | 1322 |
|
1172 | 1323 |
static int fd_open(BlockDriverState *bs) |
1173 | 1324 |
{ |
... | ... | |
1198 | 1349 |
{ |
1199 | 1350 |
return -ENOTSUP; |
1200 | 1351 |
} |
1201 |
#endif /* !linux */ |
|
1352 |
#endif /* !linux && !FreeBSD */
|
|
1202 | 1353 |
|
1203 | 1354 |
static int raw_sg_send_command(BlockDriverState *bs, void *buf, int count) |
1204 | 1355 |
{ |
Also available in: Unified diff