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.
 
 
 
 
 
 

1150 lines
28 KiB

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