You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1181 lines
28 KiB

  1. /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
  2. /*
  3. Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
  4. Provided under GPL version 2 or later
  5. and under FreeBSD license revised, i.e. without advertising clause.
  6. */
  7. #ifdef HAVE_CONFIG_H
  8. #include "../config.h"
  9. #endif
  10. #include <errno.h>
  11. #include <unistd.h>
  12. #include <stdio.h>
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15. #include <fcntl.h>
  16. #include <sys/ioctl.h>
  17. #include <sys/file.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <sys/poll.h>
  21. #include <camlib.h>
  22. #include <cam/scsi/scsi_message.h>
  23. #include <cam/scsi/scsi_pass.h>
  24. #include <err.h> /* XXX */
  25. /* ts A70909 */
  26. #include <sys/statvfs.h>
  27. /* ts B00121 */
  28. #include <sys/disk.h> /* DIOCGMEDIASIZE */
  29. /* ts B00326 : For use of CAM_PASS_ERR_RECOVER with ahci */
  30. #define Libburn_for_freebsd_ahcI yes
  31. /* ts B00327 : for debugging of cam_send_cdb() failures
  32. # define Libburn_ahci_verbouS yes
  33. */
  34. /* ts B00327 : Apply CAM_PASS_ERR_RECOVER to drives even if not ahci
  35. # define libburn_ahci_style_for_alL yes
  36. */
  37. #include "transport.h"
  38. #include "drive.h"
  39. #include "sg.h"
  40. #include "spc.h"
  41. #include "mmc.h"
  42. #include "sbc.h"
  43. #include "debug.h"
  44. #include "toc.h"
  45. #include "util.h"
  46. #include "init.h"
  47. #include "libdax_msgs.h"
  48. extern struct libdax_msgs *libdax_messenger;
  49. struct burn_drive_enumeration_state {
  50. int fd;
  51. union ccb ccb;
  52. unsigned int i;
  53. int skip_device;
  54. };
  55. static void enumerate_common(char *fname, int bus_no, int host_no,
  56. int channel_no, int target_no, int lun_no);
  57. /* ts A51221 */
  58. int burn_drive_is_banned(char *device_address);
  59. /* ts A60821
  60. debug: for tracing calls which might use open drive fds
  61. or for catching SCSI usage of emulated drives. */
  62. int mmc_function_spy(struct burn_drive *d, char * text);
  63. /* ts B00113
  64. Whether to log SCSI commands:
  65. bit0= log in /tmp/libburn_sg_command_log
  66. bit1= log to stderr
  67. bit2= flush every line
  68. */
  69. extern int burn_sg_log_scsi;
  70. /* ts B00114 */
  71. /* Storage object is in libburn/init.c
  72. whether to strive for exclusive access to the drive
  73. */
  74. extern int burn_sg_open_o_excl;
  75. /* ts A91227 */
  76. /** Returns the id string of the SCSI transport adapter and eventually
  77. needed operating system facilities.
  78. This call is usable even if sg_initialize() was not called yet. In that
  79. case a preliminary constant message might be issued if detailed info is
  80. not available yet.
  81. @param msg returns id string
  82. @param flag unused yet, submit 0
  83. @return 1 = success, <=0 = failure
  84. */
  85. int sg_id_string(char msg[1024], int flag)
  86. {
  87. strcpy(msg, "internal FreeBSD CAM adapter sg-freebsd");
  88. return 1;
  89. }
  90. /* ts A91227 */
  91. /** Performs global initialization of the SCSI transport adapter and eventually
  92. needed operating system facilities. Checks for compatibility supporting
  93. software components.
  94. @param msg returns ids and/or error messages of eventual helpers
  95. @param flag unused yet, submit 0
  96. @return 1 = success, <=0 = failure
  97. */
  98. int sg_initialize(char msg[1024], int flag)
  99. {
  100. return sg_id_string(msg, 0);
  101. }
  102. /* ts A91227 */
  103. /** Performs global finalization of the SCSI transport adapter and eventually
  104. needed operating system facilities. Releases globally acquired resources.
  105. @param flag unused yet, submit 0
  106. @return 1 = success, <=0 = failure
  107. */
  108. int sg_shutdown(int flag)
  109. {
  110. return 1;
  111. }
  112. /** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
  113. struct burn_drive which are defined in os-*.h.
  114. The eventual initialization of those components was made underneath
  115. scsi_enumerate_drives().
  116. This will be called when a burn_drive gets disposed.
  117. @param d the drive to be finalized
  118. @param flag unused yet, submit 0
  119. @return 1 = success, <=0 = failure
  120. */
  121. int sg_dispose_drive(struct burn_drive *d, int flag)
  122. {
  123. return 1;
  124. }
  125. /* ts A61021 : Moved most code from scsi_enumerate_drives under
  126. sg_give_next_adr() */
  127. /* Some helper functions for scsi_give_next_adr() */
  128. static int sg_init_enumerator(burn_drive_enumerator_t *idx_)
  129. {
  130. struct burn_drive_enumeration_state *idx;
  131. int bufsize;
  132. idx = calloc(1, sizeof(*idx));
  133. if (idx == NULL) {
  134. warnx("cannot allocate memory for enumerator");
  135. return -1;
  136. }
  137. idx->skip_device = 0;
  138. if ((idx->fd = open(XPT_DEVICE, O_RDWR)) == -1) {
  139. warn("could not open %s", XPT_DEVICE);
  140. free(idx);
  141. idx = NULL;
  142. return -1;
  143. }
  144. memset(&(idx->ccb), 0, sizeof(union ccb));
  145. idx->ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
  146. idx->ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
  147. idx->ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
  148. idx->ccb.ccb_h.func_code = XPT_DEV_MATCH;
  149. bufsize = sizeof(struct dev_match_result) * 100;
  150. idx->ccb.cdm.match_buf_len = bufsize;
  151. idx->ccb.cdm.matches = (struct dev_match_result *) calloc(1, bufsize);
  152. if (idx->ccb.cdm.matches == NULL) {
  153. warnx("cannot allocate memory for matches");
  154. close(idx->fd);
  155. free(idx);
  156. return -1;
  157. }
  158. idx->ccb.cdm.num_matches = 0;
  159. idx->i = idx->ccb.cdm.num_matches; /* to trigger buffer load */
  160. /*
  161. * We fetch all nodes, since we display most of them in the default
  162. * case, and all in the verbose case.
  163. */
  164. idx->ccb.cdm.num_patterns = 0;
  165. idx->ccb.cdm.pattern_buf_len = 0;
  166. *idx_ = idx;
  167. return 1;
  168. }
  169. static void sg_destroy_enumerator(burn_drive_enumerator_t *idx_)
  170. {
  171. struct burn_drive_enumeration_state *idx = *idx_;
  172. if(idx->fd != -1)
  173. close(idx->fd);
  174. free(idx->ccb.cdm.matches);
  175. free(idx);
  176. *idx_ = NULL;
  177. }
  178. static int sg_next_enumeration_buffer(burn_drive_enumerator_t *idx_)
  179. {
  180. struct burn_drive_enumeration_state *idx = *idx_;
  181. /*
  182. * We do the ioctl multiple times if necessary, in case there are
  183. * more than 100 nodes in the EDT.
  184. */
  185. if (ioctl(idx->fd, CAMIOCOMMAND, &(idx->ccb)) == -1) {
  186. warn("error sending CAMIOCOMMAND ioctl");
  187. return -1;
  188. }
  189. if ((idx->ccb.ccb_h.status != CAM_REQ_CMP)
  190. || ((idx->ccb.cdm.status != CAM_DEV_MATCH_LAST)
  191. && (idx->ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
  192. warnx("got CAM error %#x, CDM error %d\n",
  193. idx->ccb.ccb_h.status, idx->ccb.cdm.status);
  194. return -1;
  195. }
  196. return 1;
  197. }
  198. /** Returns the next index object state and the next enumerated drive address.
  199. @param idx An opaque handle. Make no own theories about it.
  200. @param adr Takes the reply
  201. @param adr_size Gives maximum size of reply including final 0
  202. @param initialize 1 = start new,
  203. 0 = continue, use no other values for now
  204. -1 = finish
  205. @return 1 = reply is a valid address , 0 = no further address available
  206. -1 = severe error (e.g. adr_size too small)
  207. */
  208. int sg_give_next_adr(burn_drive_enumerator_t *idx_,
  209. char adr[], int adr_size, int initialize)
  210. {
  211. struct burn_drive_enumeration_state *idx;
  212. int ret;
  213. if (initialize == 1) {
  214. ret = sg_init_enumerator(idx_);
  215. if (ret<=0)
  216. return ret;
  217. } else if (initialize == -1) {
  218. sg_destroy_enumerator(idx_);
  219. return 0;
  220. }
  221. idx = *idx_;
  222. do {
  223. if (idx->i >= idx->ccb.cdm.num_matches) {
  224. ret = sg_next_enumeration_buffer(idx_);
  225. if (ret<=0)
  226. return -1;
  227. idx->i = 0;
  228. } else
  229. (idx->i)++;
  230. while (idx->i < idx->ccb.cdm.num_matches) {
  231. switch (idx->ccb.cdm.matches[idx->i].type) {
  232. case DEV_MATCH_BUS:
  233. break;
  234. case DEV_MATCH_DEVICE: {
  235. struct device_match_result* result;
  236. result = &(idx->ccb.cdm.matches[idx->i].result.device_result);
  237. if (result->flags & DEV_RESULT_UNCONFIGURED)
  238. idx->skip_device = 1;
  239. else
  240. idx->skip_device = 0;
  241. break;
  242. }
  243. case DEV_MATCH_PERIPH: {
  244. struct periph_match_result* result;
  245. result = &(idx->ccb.cdm.matches[idx->i].result.periph_result);
  246. /* ts B00112 : we really want only "cd" devices.
  247. if (idx->skip_device ||
  248. strcmp(result->periph_name, "pass") == 0)
  249. break;
  250. */
  251. if (idx->skip_device ||
  252. strcmp(result->periph_name, "cd") != 0)
  253. break;
  254. ret = snprintf(adr, adr_size, "/dev/%s%d",
  255. result->periph_name, result->unit_number);
  256. if(ret >= adr_size)
  257. return -1;
  258. /* Found next enumerable address */
  259. return 1;
  260. }
  261. default:
  262. /* fprintf(stderr, "unknown match type\n"); */
  263. break;
  264. }
  265. (idx->i)++;
  266. }
  267. } while ((idx->ccb.ccb_h.status == CAM_REQ_CMP)
  268. && (idx->ccb.cdm.status == CAM_DEV_MATCH_MORE));
  269. return 0;
  270. }
  271. int sg_is_enumerable_adr(char* adr)
  272. {
  273. burn_drive_enumerator_t idx;
  274. int ret;
  275. char buf[64];
  276. ret = sg_init_enumerator(&idx);
  277. if (ret <= 0)
  278. return 0;
  279. while(1) {
  280. ret = sg_give_next_adr(&idx, buf, sizeof(buf), 0);
  281. if (ret <= 0)
  282. break;
  283. if (strcmp(adr, buf) == 0) {
  284. sg_destroy_enumerator(&idx);
  285. return 1;
  286. }
  287. }
  288. sg_destroy_enumerator(&idx);
  289. return (0);
  290. }
  291. /** Try to obtain SCSI address parameters.
  292. @return 1 is success , 0 is failure
  293. */
  294. int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
  295. int *target_no, int *lun_no)
  296. {
  297. burn_drive_enumerator_t idx;
  298. int ret;
  299. char buf[64];
  300. struct periph_match_result* result;
  301. ret = sg_init_enumerator(&idx);
  302. if (ret <= 0)
  303. return 0;
  304. while(1) {
  305. ret = sg_give_next_adr(&idx, buf, sizeof(buf), 0);
  306. if (ret <= 0)
  307. break;
  308. if (strcmp(path, buf) == 0) {
  309. result = &(idx->ccb.cdm.matches[idx->i].result.periph_result);
  310. *bus_no = result->path_id;
  311. *host_no = result->path_id;
  312. *channel_no = 0;
  313. *target_no = result->target_id;
  314. *lun_no = result->target_lun;
  315. sg_destroy_enumerator(&idx);
  316. return 1;
  317. }
  318. }
  319. sg_destroy_enumerator(&idx);
  320. return (0);
  321. }
  322. int sg_close_drive(struct burn_drive * d)
  323. {
  324. if (d->cam != NULL) {
  325. cam_close_device(d->cam);
  326. d->cam = NULL;
  327. }
  328. if (d->lock_fd > 0) {
  329. close(d->lock_fd);
  330. d->lock_fd = -1;
  331. }
  332. return 0;
  333. }
  334. int sg_drive_is_open(struct burn_drive * d)
  335. {
  336. return (d->cam != NULL);
  337. }
  338. int scsi_enumerate_drives(void)
  339. {
  340. burn_drive_enumerator_t idx;
  341. int ret;
  342. char buf[64];
  343. struct periph_match_result* result;
  344. ret = sg_init_enumerator(&idx);
  345. if (ret <= 0)
  346. return 0;
  347. while(1) {
  348. ret = sg_give_next_adr(&idx, buf, sizeof(buf), 0);
  349. if (ret <= 0)
  350. break;
  351. if (burn_drive_is_banned(buf))
  352. continue;
  353. result = &idx->ccb.cdm.matches[idx->i].result.periph_result;
  354. enumerate_common(buf, result->path_id, result->path_id,
  355. 0, result->target_id,
  356. result->target_lun);
  357. }
  358. sg_destroy_enumerator(&idx);
  359. return 1;
  360. }
  361. #ifdef Scsi_freebsd_make_own_enumeratE
  362. /* ts A61021: The old version which mixes SCSI and operating system adapter
  363. */
  364. static void enumerate_common(char *fname, int bus_no, int host_no,
  365. int channel_no, int target_no, int lun_no)
  366. {
  367. struct burn_drive *t;
  368. struct burn_drive out;
  369. /* Initialize pointers to managed memory */
  370. out.devname = NULL;
  371. out.idata = NULL;
  372. out.mdata = NULL;
  373. /* ts A60923 */
  374. out.bus_no = bus_no;
  375. out.host = host_no;
  376. out.id = target_no;
  377. out.channel = channel_no;
  378. out.lun = lun_no;
  379. out.devname = strdup(fname);
  380. if (out.devname == NULL)
  381. goto could_not_allocate;
  382. out.cam = NULL;
  383. out.lock_fd = -1;
  384. out.is_ahci = 0;
  385. out.start_lba= -2000000000;
  386. out.end_lba= -2000000000;
  387. out.read_atip = mmc_read_atip;
  388. out.grab = sg_grab;
  389. out.release = sg_release;
  390. out.drive_is_open= sg_drive_is_open;
  391. out.issue_command = sg_issue_command;
  392. out.getcaps = spc_getcaps;
  393. out.released = 1;
  394. out.status = BURN_DISC_UNREADY;
  395. out.eject = sbc_eject;
  396. out.load = sbc_load;
  397. out.lock = spc_prevent;
  398. out.unlock = spc_allow;
  399. out.read_disc_info = spc_sense_write_params;
  400. out.get_erase_progress = spc_get_erase_progress;
  401. out.test_unit_ready = spc_test_unit_ready;
  402. out.probe_write_modes = spc_probe_write_modes;
  403. out.read_toc = mmc_read_toc;
  404. out.write = mmc_write;
  405. out.erase = mmc_erase;
  406. out.read_cd = mmc_read_cd;
  407. out.perform_opc = mmc_perform_opc;
  408. out.set_speed = mmc_set_speed;
  409. out.send_parameters = spc_select_error_params;
  410. out.send_write_parameters = spc_select_write_params;
  411. out.send_cue_sheet = mmc_send_cue_sheet;
  412. out.sync_cache = mmc_sync_cache;
  413. out.get_nwa = mmc_get_nwa;
  414. out.close_disc = mmc_close_disc;
  415. out.close_session = mmc_close_session;
  416. out.close_track_session = mmc_close;
  417. out.read_buffer_capacity = mmc_read_buffer_capacity;
  418. out.idata = calloc(1, sizeof(struct burn_scsi_inquiry_data));
  419. out.idata->valid = 0;
  420. out.mdata = calloc(1, sizeof(struct scsi_mode_data));
  421. if (out.idata == NULL || out.mdata == NULL) {
  422. could_not_allocate:;
  423. libdax_msgs_submit(libdax_messenger, -1, 0x00020108,
  424. LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
  425. "Could not allocate new drive object", 0, 0);
  426. if (out.devname != NULL)
  427. free(out.devname);
  428. out.devname = NULL;
  429. if (out.idata != NULL)
  430. free(out.idata);
  431. out.idata = NULL;
  432. if (out.mdata != NULL)
  433. free(out.mdata);
  434. out.mdata = NULL;
  435. return;
  436. }
  437. out.mdata->p2a_valid = 0;
  438. memset(&out.params, 0, sizeof(struct params));
  439. t = burn_drive_register(&out);
  440. /* ts A60821
  441. <<< debug: for tracing calls which might use open drive fds */
  442. mmc_function_spy(NULL, "enumerate_common : -------- doing grab");
  443. /* try to get the drive info */
  444. if (t->grab(t)) {
  445. t->getcaps(t);
  446. t->unlock(t);
  447. t->released = 1;
  448. }
  449. /* ts A60821
  450. <<< debug: for tracing calls which might use open drive fds */
  451. mmc_function_spy(NULL, "enumerate_common : ----- would release ");
  452. }
  453. #else /* Scsi_freebsd_make_own_enumeratE */
  454. /* The new, more concise version of enumerate_common */
  455. static void enumerate_common(char *fname, int bus_no, int host_no,
  456. int channel_no, int target_no, int lun_no)
  457. {
  458. int ret;
  459. struct burn_drive out;
  460. /* General libburn drive setup */
  461. burn_setup_drive(&out, fname);
  462. /* This transport adapter uses SCSI-family commands and models
  463. (seems the adapter would know better than its boss, if ever) */
  464. ret = burn_scsi_setup_drive(&out, bus_no, host_no, channel_no,
  465. target_no, lun_no, 0);
  466. if (ret<=0)
  467. return;
  468. /* Operating system adapter is CAM */
  469. /* Adapter specific handles and data */
  470. out.cam = NULL;
  471. out.lock_fd = -1;
  472. out.is_ahci = 0;
  473. /* Adapter specific functions */
  474. out.grab = sg_grab;
  475. out.release = sg_release;
  476. out.drive_is_open = sg_drive_is_open;
  477. out.issue_command = sg_issue_command;
  478. /* Finally register drive and inquire drive information */
  479. burn_drive_finish_enum(&out);
  480. }
  481. #endif /* ! Scsi_freebsd_make_own_enumeratE */
  482. /* Lock the inode associated to dev_fd and the inode associated to devname.
  483. Return OS errno, number of pass device of dev_fd, locked fd to devname,
  484. error message.
  485. A return value of > 0 means success, <= 0 means failure.
  486. */
  487. static int freebsd_dev_lock(int dev_fd, char *devname,
  488. int *os_errno, int *pass_dev_no, int *lock_fd, char msg[4096],
  489. int flag)
  490. {
  491. int lock_denied = 0, fd_stbuf_valid, name_stbuf_valid, i, pass_l = 100;
  492. int max_retry = 3, tries = 0;
  493. struct stat fd_stbuf, name_stbuf;
  494. char pass_name[16], *lock_name;
  495. *os_errno = 0;
  496. *pass_dev_no = -1;
  497. *lock_fd = -1;
  498. msg[0] = 0;
  499. fd_stbuf_valid = !fstat(dev_fd, &fd_stbuf);
  500. /* Try to find name of pass device by inode number */
  501. lock_name = (char *) "effective device";
  502. if(fd_stbuf_valid) {
  503. for (i = 0; i < pass_l; i++) {
  504. sprintf(pass_name, "/dev/pass%d", i);
  505. if (stat(pass_name, &name_stbuf) != -1)
  506. if(fd_stbuf.st_ino == name_stbuf.st_ino &&
  507. fd_stbuf.st_dev == name_stbuf.st_dev)
  508. break;
  509. }
  510. if (i < pass_l) {
  511. lock_name = pass_name;
  512. *pass_dev_no = i;
  513. }
  514. }
  515. name_stbuf_valid = !stat(devname, &name_stbuf);
  516. for (tries= 0; tries <= max_retry; tries++) {
  517. lock_denied = flock(dev_fd, LOCK_EX | LOCK_NB);
  518. *os_errno = errno;
  519. if (lock_denied) {
  520. if (errno == EAGAIN && tries < max_retry) {
  521. /* <<< debugging
  522. fprintf(stderr,
  523. "\nlibcdio_DEBUG: EAGAIN pass, tries= %d\n",
  524. tries);
  525. */
  526. usleep(2000000);
  527. continue;
  528. }
  529. sprintf(msg,
  530. "Device busy. flock(LOCK_EX) failed on %s of %s",
  531. strlen(lock_name) > 2000 || *pass_dev_no < 0 ?
  532. "pass device" : lock_name,
  533. strlen(devname) > 2000 ? "drive" : devname);
  534. return 0;
  535. }
  536. break;
  537. }
  538. /*
  539. fprintf(stderr, "libburn_DEBUG: flock obtained on %s of %s\n",
  540. lock_name, devname);
  541. */
  542. /* Eventually lock the official device node too */
  543. if (fd_stbuf_valid && name_stbuf_valid &&
  544. (fd_stbuf.st_ino != name_stbuf.st_ino ||
  545. fd_stbuf.st_dev != name_stbuf.st_dev)) {
  546. *lock_fd = open(devname, O_RDONLY);
  547. if (*lock_fd == 0) {
  548. close(*lock_fd);
  549. *lock_fd = -1;
  550. } if (*lock_fd > 0) {
  551. for (tries = 0; tries <= max_retry; tries++) {
  552. lock_denied =
  553. flock(*lock_fd, LOCK_EX | LOCK_NB);
  554. if (lock_denied) {
  555. if (errno == EAGAIN &&
  556. tries < max_retry) {
  557. /* <<< debugging
  558. fprintf(stderr,
  559. "\nlibcdio_DEBUG: EAGAIN dev, tries= %d\n",
  560. tries);
  561. */
  562. usleep(2000000);
  563. continue;
  564. }
  565. close(*lock_fd);
  566. *lock_fd = -1;
  567. sprintf(msg,
  568. "Device busy. flock(LOCK_EX) failed on %s",
  569. strlen(devname) > 4000 ? "drive" : devname);
  570. return 0;
  571. }
  572. break;
  573. }
  574. }
  575. /*
  576. fprintf(stderr, "libburn_DEBUG: flock obtained on %s\n",
  577. devname);
  578. */
  579. }
  580. return 1;
  581. }
  582. static int sg_lock(struct burn_drive *d, int flag)
  583. {
  584. int ret, os_errno, pass_dev_no = -1, flock_fd = -1;
  585. char *msg = NULL;
  586. BURN_ALLOC_MEM(msg, char, 4096);
  587. ret = freebsd_dev_lock(d->cam->fd, d->devname,
  588. &os_errno, &pass_dev_no, &flock_fd, msg, 0);
  589. if (ret <= 0) {
  590. libdax_msgs_submit(libdax_messenger, d->global_index,
  591. 0x00020008,
  592. LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
  593. msg, os_errno, 0);
  594. sg_close_drive(d);
  595. {ret = 0; goto ex;}
  596. }
  597. if (d->lock_fd > 0)
  598. close(d->lock_fd);
  599. d->lock_fd = flock_fd;
  600. ret = 1;
  601. ex:;
  602. BURN_FREE_MEM(msg);
  603. return ret;
  604. }
  605. int sg_grab(struct burn_drive *d)
  606. {
  607. struct cam_device *cam;
  608. char path_string[80];
  609. if (mmc_function_spy(d, "sg_grab") <= 0)
  610. return 0;
  611. if (burn_drive_is_open(d)) {
  612. d->released = 0;
  613. return 1;
  614. }
  615. cam = cam_open_device(d->devname, O_RDWR);
  616. if (cam == NULL) {
  617. libdax_msgs_submit(libdax_messenger, d->global_index,
  618. 0x00020003,
  619. LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
  620. "Could not grab drive", errno, 0);
  621. return 0;
  622. }
  623. d->cam = cam;
  624. if (burn_sg_open_o_excl & 63)
  625. if (sg_lock(d, 0) <= 0)
  626. return 0;
  627. fcntl(cam->fd, F_SETOWN, getpid());
  628. cam_path_string(d->cam, path_string, sizeof(path_string));
  629. #ifdef Libburn_ahci_verbouS
  630. fprintf(stderr, "libburn_EXPERIMENTAL: CAM path = %s\n", path_string);
  631. #endif
  632. if (strstr(path_string, ":ahcich") != NULL)
  633. d->is_ahci = 1;
  634. else
  635. d->is_ahci = -1;
  636. d->released = 0;
  637. return 1;
  638. }
  639. /*
  640. non zero return means you still have the drive and it's not
  641. in a state to be released? (is that even possible?)
  642. */
  643. int sg_release(struct burn_drive *d)
  644. {
  645. if (mmc_function_spy(d, "sg_release") <= 0)
  646. return 0;
  647. if (d->cam == NULL)
  648. return 0;
  649. mmc_function_spy(NULL, "sg_release ----------- closing.");
  650. sg_close_drive(d);
  651. d->released = 1;
  652. return 0;
  653. }
  654. int sg_issue_command(struct burn_drive *d, struct command *c)
  655. {
  656. int done = 0, err, sense_len = 0, ret, ignore_error, i;
  657. int cam_pass_err_recover = 0, key, asc, ascq, timeout_ms;
  658. union ccb *ccb;
  659. static FILE *fp = NULL;
  660. time_t start_time;
  661. mmc_function_spy(NULL, "sg_issue_command");
  662. c->error = 0;
  663. memset(c->sense, 0, sizeof(c->sense));
  664. if (d->cam == NULL)
  665. return 0;
  666. if (burn_sg_log_scsi & 1) {
  667. if (fp == NULL) {
  668. fp= fopen("/tmp/libburn_sg_command_log", "a");
  669. fprintf(fp,
  670. "\n-----------------------------------------\n");
  671. }
  672. }
  673. if (burn_sg_log_scsi & 3)
  674. scsi_log_cmd(c,fp,0);
  675. c->error = 0;
  676. if (c->timeout > 0)
  677. timeout_ms = c->timeout;
  678. else
  679. timeout_ms = 200000;
  680. ccb = cam_getccb(d->cam);
  681. cam_fill_csio(&ccb->csio,
  682. 1, /* retries */
  683. NULL, /* cbfncp */
  684. CAM_DEV_QFRZDIS, /* flags */
  685. MSG_SIMPLE_Q_TAG, /* tag_action */
  686. NULL, /* data_ptr */
  687. 0, /* dxfer_len */
  688. sizeof (ccb->csio.sense_data), /* sense_len */
  689. 0, /* cdb_len */
  690. timeout_ms); /* timeout */
  691. switch (c->dir) {
  692. case TO_DRIVE:
  693. ccb->csio.ccb_h.flags |= CAM_DIR_OUT;
  694. break;
  695. case FROM_DRIVE:
  696. ccb->csio.ccb_h.flags |= CAM_DIR_IN;
  697. break;
  698. case NO_TRANSFER:
  699. ccb->csio.ccb_h.flags |= CAM_DIR_NONE;
  700. break;
  701. }
  702. #ifdef Libburn_for_freebsd_ahcI
  703. /* ts B00325 : Advise by Alexander Motin */
  704. /* Runs well on 8-STABLE (23 Mar 2003)
  705. But on 8-RELEASE cam_send_ccb() returns non-zero with errno 6
  706. on eject. Long lasting TEST UNIT READY cycles break with
  707. errno 16.
  708. */
  709. #ifdef Libburn_ahci_style_for_alL
  710. {
  711. #else
  712. if (d->is_ahci > 0) {
  713. #endif
  714. ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
  715. cam_pass_err_recover = 1;
  716. }
  717. #endif /* Libburn_for_freebsd_ahcI */
  718. ccb->csio.cdb_len = c->oplen;
  719. memcpy(&ccb->csio.cdb_io.cdb_bytes, &c->opcode, c->oplen);
  720. if (c->page) {
  721. ccb->csio.data_ptr = c->page->data;
  722. if (c->dir == FROM_DRIVE) {
  723. /* ts A90430 : Ticket 148 , by jwehle :
  724. "On ... FreeBSD 6.4 which has a usb memory reader in
  725. addition to a ATAPI DVD burner sg_issue_command
  726. will hang while the SCSI bus is being scanned"
  727. */
  728. if (c->dxfer_len >= 0)
  729. ccb->csio.dxfer_len = c->dxfer_len;
  730. else
  731. ccb->csio.dxfer_len = BUFFER_SIZE;
  732. /* touch page so we can use valgrind */
  733. memset(c->page->data, 0, BUFFER_SIZE);
  734. } else {
  735. ccb->csio.dxfer_len = c->page->bytes;
  736. }
  737. } else {
  738. ccb->csio.data_ptr = NULL;
  739. ccb->csio.dxfer_len = 0;
  740. }
  741. /* ts B90523 : Record effective transfer length request for debugging*/
  742. c->dxfer_len = ccb->csio.dxfer_len;
  743. start_time = time(NULL);
  744. for (i = 0; !done; i++) {
  745. memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data));
  746. memset(c->sense, 0, sizeof(c->sense));
  747. c->start_time = burn_get_time(0);
  748. err = cam_send_ccb(d->cam, ccb);
  749. c->end_time = burn_get_time(0);
  750. ignore_error = sense_len = 0;
  751. /* ts B00325 : CAM_AUTOSNS_VALID advised by Alexander Motin */
  752. if (ccb->ccb_h.status & CAM_AUTOSNS_VALID) {
  753. /* ts B00110 */
  754. /* Better curb sense_len */
  755. sense_len = ccb->csio.sense_len;
  756. if (sense_len > (int) sizeof(c->sense))
  757. sense_len = sizeof(c->sense);
  758. memcpy(c->sense, &ccb->csio.sense_data, sense_len);
  759. spc_decode_sense(c->sense, sense_len,
  760. &key, &asc, &ascq);
  761. if (sense_len >= 14 && cam_pass_err_recover && key)
  762. ignore_error = 1;
  763. }
  764. if (err == -1 && cam_pass_err_recover && ! ignore_error) {
  765. #ifdef Libburn_ahci_verbouS
  766. fprintf(stderr, "libburn_EXPERIMENTAL: errno = %d . cam_errbuf = '%s'\n", errno, cam_errbuf);
  767. #endif
  768. if (errno == ENXIO && c->opcode[0] != 0) {
  769. /* Operations on empty or ejected tray */
  770. /* MEDIUM NOT PRESENT */
  771. #ifdef Libburn_ahci_verbouS
  772. fprintf(stderr, "libburn_EXPERIMENTAL: Emulating [2,3A,00] MEDIUM NOT PRESENT\n");
  773. #endif
  774. c->sense[0] = 0x70; /*Fixed format sense data*/
  775. c->sense[2] = 0x02;
  776. c->sense[12] = 0x3A;
  777. c->sense[13] = 0x00;
  778. sense_len = 14;
  779. ignore_error = 1;
  780. } else if (c->opcode[0] == 0 &&
  781. (errno == EBUSY || errno == ENXIO)) {
  782. /* Timeout of TEST UNIT READY loop */
  783. /* Inquiries while tray is being loaded */
  784. /*LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE*/
  785. #ifdef Libburn_ahci_verbouS
  786. fprintf(stderr, "libburn_EXPERIMENTAL: Emulating [2,04,00] LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE\n");
  787. #endif
  788. c->sense[0] = 0x70; /*Fixed format sense data*/
  789. c->sense[2] = 0x02;
  790. c->sense[12] = 0x04;
  791. c->sense[13] = 0x00;
  792. sense_len = 14;
  793. ignore_error = 1;
  794. } else if (errno == EINVAL) {
  795. /* Inappropriate MODE SENSE */
  796. /* INVALID FIELD IN CDB */
  797. #ifdef Libburn_ahci_verbouS
  798. fprintf(stderr, "libburn_EXPERIMENTAL: Emulating [5,24,00] INVALID FIELD IN CDB\n");
  799. #endif
  800. c->sense[0] = 0x70; /*Fixed format sense data*/
  801. c->sense[2] = 0x05;
  802. c->sense[12] = 0x24;
  803. c->sense[13] = 0x00;
  804. sense_len = 14;
  805. ignore_error = 1;
  806. }
  807. }
  808. if (err == -1 && !ignore_error) {
  809. libdax_msgs_submit(libdax_messenger,
  810. d->global_index, 0x0002010c,
  811. LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
  812. "Failed to transfer command to drive",
  813. errno, 0);
  814. sg_close_drive(d);
  815. d->released = 1;
  816. d->busy = BURN_DRIVE_IDLE;
  817. c->error = 1;
  818. {ret = -1; goto ex;}
  819. }
  820. /* XXX */
  821. if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
  822. if (sense_len < 14) {
  823. /*LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE*/
  824. #ifdef Libburn_ahci_verbouS
  825. fprintf(stderr, "libburn_EXPERIMENTAL: CAM_STATUS= %d .Emulating [2,04,00] LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE\n", (ccb->ccb_h.status & CAM_STATUS_MASK));
  826. #endif
  827. c->sense[0] = 0x70; /*Fixed format sense data*/
  828. c->sense[2] = 0x02;
  829. c->sense[12] = 0x04;
  830. c->sense[13] = 0x00;
  831. done = 1;
  832. }
  833. }
  834. done = scsi_eval_cmd_outcome(d, c, fp, c->sense,
  835. sense_len, start_time,
  836. timeout_ms, i, !!ignore_error);
  837. if (d->cancel)
  838. done = 1;
  839. if (!done)
  840. spc_register_retry(c);
  841. } while (!done);
  842. ret = 1;
  843. ex:;
  844. cam_freeccb(ccb);
  845. return ret;
  846. }
  847. /* ts B00115 */
  848. /* Return 1 if the given path leads to a regular file or a device that can be
  849. fseeked, read and eventually written with 2 kB granularity.
  850. */
  851. int burn_os_is_2k_seekrw(char *path, int flag)
  852. {
  853. struct stat stbuf;
  854. #ifdef Libburn_DIOCGMEDIASIZE_ISBLK
  855. int fd, ret;
  856. off_t add_size;
  857. #else
  858. char *spt;
  859. int i, e;
  860. #endif /* ! Libburn_DIOCGMEDIASIZE_ISBLK */
  861. if (stat(path, &stbuf) == -1)
  862. return 0;
  863. if (S_ISREG(stbuf.st_mode))
  864. return 1;
  865. if (!S_ISCHR(stbuf.st_mode))
  866. return 0;
  867. #ifdef Libburn_DIOCGMEDIASIZE_ISBLK
  868. /* If it throws no error with DIOCGMEDIASIZE then it is a
  869. 'block device'
  870. */
  871. fd = open(path, O_RDONLY);
  872. if (fd == -1)
  873. return 0;
  874. ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
  875. close(fd);
  876. return (ret != -1);
  877. #else /* Libburn_DIOCGMEDIASIZE_ISBLK */
  878. spt = strrchr(path, '/');
  879. if (spt == NULL)
  880. spt = path;
  881. else
  882. spt++;
  883. e = strlen(spt);
  884. for (i = strlen(spt) - 1; i > 0; i--)
  885. if (spt[i] >= '0' && spt[i] <= '9')
  886. e = i;
  887. if (strncmp(spt, "da", e) == 0) /* SCSI disk. E.g. USB stick. */
  888. return 1;
  889. if (strncmp(spt, "cd", e) == 0) /* SCSI CD drive might be writeable. */
  890. return 1;
  891. if (strncmp(spt, "ad", e) == 0) /* IDE hard drive */
  892. return 1;
  893. if (strncmp(spt, "acd", e) == 0) /* IDE CD drive might be writeable */
  894. return 1;
  895. if (strncmp(spt, "fd", e) == 0) /* Floppy disk */
  896. return 1;
  897. if (strncmp(spt, "fla", e) == 0) /* Flash drive */
  898. return 1;
  899. return 0;
  900. #endif /* ! Libburn_DIOCGMEDIASIZE_ISBLK */
  901. }
  902. /* ts A70909 */
  903. /** Estimate the potential payload capacity of a file address.
  904. @param path The address of the file to be examined. If it does not
  905. exist yet, then the directory will be inquired.
  906. @param bytes This value gets modified if an estimation is possible
  907. @return -2 = cannot perform necessary operations on file object
  908. -1 = neither path nor dirname of path exist
  909. 0 = could not estimate size capacity of file object
  910. 1 = estimation has been made, bytes was set
  911. */
  912. int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
  913. {
  914. struct stat stbuf;
  915. struct statvfs vfsbuf;
  916. char *testpath = NULL, *cpt;
  917. off_t add_size = 0;
  918. int fd, ret;
  919. BURN_ALLOC_MEM(testpath, char, 4096);
  920. testpath[0] = 0;
  921. if (stat(path, &stbuf) == -1) {
  922. strcpy(testpath, path);
  923. cpt = strrchr(testpath, '/');
  924. if(cpt == NULL)
  925. strcpy(testpath, ".");
  926. else if(cpt == testpath)
  927. testpath[1] = 0;
  928. else
  929. *cpt = 0;
  930. if (stat(testpath, &stbuf) == -1)
  931. {ret = -1; goto ex;}
  932. #ifdef Libburn_if_this_was_linuX
  933. } else if(S_ISBLK(stbuf.st_mode)) {
  934. int open_mode = O_RDWR, fd, ret;
  935. long blocks;
  936. blocks = *bytes / 512;
  937. if(burn_sg_open_o_excl)
  938. open_mode |= O_EXCL;
  939. fd = open(path, open_mode);
  940. if (fd == -1)
  941. {ret = -2; goto ex;}
  942. ret = ioctl(fd, BLKGETSIZE, &blocks);
  943. close(fd);
  944. if (ret == -1)
  945. {ret = -2; goto ex;}
  946. *bytes = ((off_t) blocks) * (off_t) 512;
  947. #endif /* Libburn_if_this_was_linuX */
  948. } else if(S_ISCHR(stbuf.st_mode)) {
  949. fd = open(path, O_RDONLY);
  950. if (fd == -1)
  951. {ret = -2; goto ex;}
  952. ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
  953. close(fd);
  954. if (ret == -1)
  955. {ret = -2; goto ex;}
  956. *bytes = add_size;
  957. } else if(S_ISREG(stbuf.st_mode)) {
  958. add_size = burn_sparse_file_addsize(write_start, &stbuf);
  959. strcpy(testpath, path);
  960. } else
  961. {ret = 0; goto ex;}
  962. if (testpath[0]) {
  963. if (statvfs(testpath, &vfsbuf) == -1)
  964. {ret = -2; goto ex;}
  965. *bytes = add_size + ((off_t) vfsbuf.f_frsize) *
  966. (off_t) vfsbuf.f_bavail;
  967. }
  968. ret = 1;
  969. ex:
  970. BURN_FREE_MEM(testpath);
  971. return ret;
  972. }
  973. /* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
  974. #ifdef Libburn_read_o_direcT
  975. /* No special O_DIRECT-like precautions are implemented here */
  976. #endif /* Libburn_read_o_direcT */
  977. int burn_os_open_track_src(char *path, int open_flags, int flag)
  978. {
  979. int fd;
  980. fd = open(path, open_flags);
  981. return fd;
  982. }
  983. void *burn_os_alloc_buffer(size_t amount, int flag)
  984. {
  985. void *buf = NULL;
  986. buf = calloc(1, amount);
  987. return buf;
  988. }
  989. int burn_os_free_buffer(void *buffer, size_t amount, int flag)
  990. {
  991. if (buffer == NULL)
  992. return 0;
  993. free(buffer);
  994. return 1;
  995. }