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.
 
 
 
 
 
 

1007 lines
27 KiB

  1. /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
  2. /*
  3. Copyright (c) 2010 Thomas Schmitt <scdbackup@gmx.net>
  4. Provided under GPL version 2 or later.
  5. */
  6. /*
  7. This is the main operating system dependent SCSI part of libburn. It implements
  8. the transport level aspects of SCSI control and command i/o.
  9. Present implementation: GNU libcdio , for X/Open compliant operating systems
  10. PORTING:
  11. Porting libburn typically will consist of adding a new operating system case
  12. to the following switcher files:
  13. os.h Operating system specific libburn definitions and declarations.
  14. sg.c Operating system dependent transport level modules.
  15. and of deriving the following system specific files from existing examples:
  16. os-*.h Included by os.h. You will need some general system knowledge
  17. about signals and knowledge about the storage object needs of your
  18. transport level module sg-*.c.
  19. sg-*.c This source module. You will need special system knowledge about
  20. how to detect all potentially available drives, how to open them,
  21. eventually how to exclusively reserve them, how to perform
  22. SCSI transactions, how to inquire the (pseudo-)SCSI driver.
  23. You will not need to care about CD burning, MMC or other high-level
  24. SCSI aspects.
  25. Said sg-*.c operations are defined by a public function interface, which has
  26. to be implemented in a way that provides libburn with the desired services:
  27. sg_id_string() returns an id string of the SCSI transport adapter.
  28. It may be called before initialization but then may
  29. return only a preliminary id.
  30. sg_initialize() performs global initialization of the SCSI transport
  31. adapter and eventually needed operating system
  32. facilities. Checks for compatibility of supporting
  33. software components.
  34. sg_shutdown() performs global finalizations and releases golbally
  35. aquired resources.
  36. sg_give_next_adr() iterates over the set of potentially useful drive
  37. address strings.
  38. scsi_enumerate_drives() brings all available, not-whitelist-banned, and
  39. accessible drives into libburn's list of drives.
  40. sg_dispose_drive() finalizes adapter specifics of struct burn_drive
  41. on destruction. Releases resources which were aquired
  42. underneath scsi_enumerate_drives().
  43. sg_drive_is_open() tells wether libburn has the given drive in use.
  44. sg_grab() opens the drive for SCSI commands and ensures
  45. undisturbed access.
  46. sg_release() closes a drive opened by sg_grab()
  47. sg_issue_command() sends a SCSI command to the drive, receives reply,
  48. and evaluates wether the command succeeded or shall
  49. be retried or finally failed.
  50. sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
  51. burn_os_is_2k_seekrw() tells whether the given path leads to a file object
  52. that can be used in 2 kB granularity by lseek(2),
  53. read(2), and possibly write(2) if not read-only..
  54. E.g. a USB stick or a hard disk.
  55. burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
  56. burn_os_open_track_src() opens a disk file in a way that allows best
  57. throughput with file reading and/or SCSI write command
  58. transmission.
  59. burn_os_alloc_buffer() allocates a memory area that is suitable for file
  60. descriptors issued by burn_os_open_track_src().
  61. The buffer size may be rounded up for alignment
  62. reasons.
  63. burn_os_free_buffer() delete a buffer obtained by burn_os_alloc_buffer().
  64. Porting hints are marked by the text "PORTING:".
  65. Send feedback to libburn-hackers@pykix.org .
  66. */
  67. #ifdef HAVE_CONFIG_H
  68. #include "../config.h"
  69. #endif
  70. /** PORTING : ------- OS dependent headers and definitions ------ */
  71. #include <unistd.h>
  72. #include <stdio.h>
  73. #include <sys/types.h>
  74. #include <errno.h>
  75. #include <fcntl.h>
  76. #include <sys/stat.h>
  77. #include <string.h>
  78. #include <stdlib.h>
  79. #ifdef Libburn_os_has_statvfS
  80. #include <sys/statvfs.h>
  81. #endif /* Libburn_os_has_stavtfS */
  82. #ifdef __linux
  83. /* for ioctl(BLKGETSIZE) */
  84. #include <sys/ioctl.h>
  85. #include <linux/fs.h>
  86. #endif
  87. #ifdef __FreeBSD__
  88. #define Libburn_is_on_freebsD 1
  89. #endif
  90. #ifdef __FreeBSD_kernel__
  91. #define Libburn_is_on_freebsD 1
  92. #endif
  93. #ifdef Libburn_is_on_freebsD
  94. /* To avoid ATAPI devices */
  95. #define Libburn_guess_freebsd_atapi_devicE 1
  96. /* To obtain size of disk-like devices */
  97. #include <sys/disk.h> /* DIOCGMEDIASIZE */
  98. #endif /* Libburn_is_on_freebsD */
  99. #define Libburn_guess_freebsd_atapi_devicE 1
  100. #ifdef sun
  101. #define Libburn_is_on_solariS 1
  102. #endif
  103. #ifdef __sun
  104. #define Libburn_is_on_solariS 1
  105. #endif
  106. #include <cdio/cdio.h>
  107. #include <cdio/logging.h>
  108. #include <cdio/mmc.h>
  109. /* The waiting time before eventually retrying a failed SCSI command.
  110. Before each retry wait Libburn_sg_linux_retry_incR longer than with
  111. the previous one.
  112. */
  113. #define Libburn_sg_libcdio_retry_usleeP 100000
  114. #define Libburn_sg_libcdio_retry_incR 100000
  115. /** PORTING : ------ libburn portable headers and definitions ----- */
  116. #include "transport.h"
  117. #include "drive.h"
  118. #include "sg.h"
  119. #include "spc.h"
  120. /* collides with symbols of <cdio/mmc.h>
  121. #include "mmc.h"
  122. */
  123. #include "sbc.h"
  124. #include "debug.h"
  125. #include "toc.h"
  126. #include "util.h"
  127. #include "libdax_msgs.h"
  128. extern struct libdax_msgs *libdax_messenger;
  129. /* is in portable part of libburn */
  130. int burn_drive_is_banned(char *device_address);
  131. int burn_drive_resolve_link(char *path, char adr[],
  132. int *recursion_count, int flag); /* drive.c */
  133. /* Whether to log SCSI commands:
  134. bit0= log in /tmp/libburn_sg_command_log
  135. bit1= log to stderr
  136. bit2= flush every line
  137. */
  138. extern int burn_sg_log_scsi;
  139. /* ------------------------------------------------------------------------ */
  140. /* PORTING: Private definitions. Port only if needed by public functions. */
  141. /* (Public functions are listed below) */
  142. /* ------------------------------------------------------------------------ */
  143. /* Storage object is in libburn/init.c
  144. whether to strive for exclusive access to the drive
  145. */
  146. extern int burn_sg_open_o_excl;
  147. /* ------------------------------------------------------------------------ */
  148. /* PORTING: Private functions. Port only if needed by public functions */
  149. /* (Public functions are listed below) */
  150. /* ------------------------------------------------------------------------ */
  151. static int sg_close_drive(struct burn_drive * d)
  152. {
  153. CdIo_t *p_cdio;
  154. if (d->p_cdio != NULL) {
  155. p_cdio = (CdIo_t *) d->p_cdio;
  156. cdio_destroy(p_cdio);
  157. d->p_cdio = NULL;
  158. }
  159. return 0;
  160. }
  161. static int sg_give_next_adr_raw(burn_drive_enumerator_t *idx,
  162. char adr[], int adr_size, int initialize)
  163. {
  164. char **pos;
  165. int count = 0;
  166. if (initialize == 1) {
  167. idx->pos = idx->ppsz_cd_drives =
  168. cdio_get_devices(DRIVER_DEVICE);
  169. if (idx->ppsz_cd_drives == NULL)
  170. return 0;
  171. for (pos = idx->ppsz_cd_drives ; pos != NULL; pos++) {
  172. if (*pos == NULL)
  173. break;
  174. count++;
  175. }
  176. } else if (initialize == -1) {
  177. if (idx->ppsz_cd_drives != NULL)
  178. if (*(idx->ppsz_cd_drives) != NULL)
  179. cdio_free_device_list(idx->ppsz_cd_drives);
  180. idx->ppsz_cd_drives = NULL;
  181. }
  182. #ifdef Libburn_guess_freebsd_atapi_devicE
  183. try_next:;
  184. #endif
  185. if (idx->pos == NULL)
  186. return 0;
  187. if (*(idx->pos) == NULL)
  188. return 0;
  189. #ifdef Libburn_guess_freebsd_atapi_devicE
  190. if (strncmp(*(idx->pos), "/dev/acd", 8) == 0) {
  191. (idx->pos)++;
  192. goto try_next;
  193. }
  194. #endif
  195. if (strlen(*(idx->pos)) >= adr_size)
  196. return -1;
  197. strcpy(adr, *(idx->pos));
  198. (idx->pos)++;
  199. return 1;
  200. }
  201. /* ----------------------------------------------------------------------- */
  202. /* PORTING: Private functions which contain publicly needed functionality. */
  203. /* Their portable part must be performed. So it is probably best */
  204. /* to replace the non-portable part and to call these functions */
  205. /* in your port, too. */
  206. /* ----------------------------------------------------------------------- */
  207. /** Wraps a detected drive into libburn structures and hands it over to
  208. libburn drive list.
  209. */
  210. static void enumerate_common(char *fname, char *cdio_name,
  211. int bus_no, int host_no,
  212. int channel_no, int target_no, int lun_no)
  213. {
  214. int ret;
  215. struct burn_drive out;
  216. /* General libburn drive setup */
  217. burn_setup_drive(&out, fname);
  218. /* This transport adapter uses SCSI-family commands and models
  219. (seems the adapter would know better than its boss, if ever) */
  220. ret = burn_scsi_setup_drive(&out, bus_no, host_no, channel_no,
  221. target_no, lun_no, 0);
  222. if (ret <= 0)
  223. return;
  224. /* PORTING: ------------------- non portable part --------------- */
  225. /* Transport adapter is libcdio */
  226. /* Adapter specific handles and data */
  227. out.p_cdio = NULL;
  228. strcpy(out.libcdio_name, fname);
  229. if (strlen(cdio_name) < sizeof(out.libcdio_name))
  230. strcpy(out.libcdio_name, cdio_name);
  231. /* PORTING: ---------------- end of non portable part ------------ */
  232. /* Adapter specific functions with standardized names */
  233. out.grab = sg_grab;
  234. out.release = sg_release;
  235. out.drive_is_open = sg_drive_is_open;
  236. out.issue_command = sg_issue_command;
  237. /* Finally register drive and inquire drive information */
  238. burn_drive_finish_enum(&out);
  239. }
  240. /* ------------------------------------------------------------------------ */
  241. /* PORTING: Public functions. These MUST be ported. */
  242. /* ------------------------------------------------------------------------ */
  243. /** Returns the id string of the SCSI transport adapter and eventually
  244. needed operating system facilities.
  245. This call is usable even if sg_initialize() was not called yet. In that
  246. case a preliminary constant message might be issued if detailed info is
  247. not available yet.
  248. @param msg returns id string
  249. @param flag unused yet, submit 0
  250. @return 1 = success, <=0 = failure
  251. */
  252. int sg_id_string(char msg[1024], int flag)
  253. {
  254. char *version_text;
  255. sprintf(msg, "sg-libcdio h%d with libcdio ", LIBCDIO_VERSION_NUM);
  256. #if LIBCDIO_VERSION_NUM < 83
  257. LIBBURN_MISCONFIGURATION = 0;
  258. INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_cdio_version_dot_h_TOO_OLD__NEED_libcdio_VERSION_NUM_83 = 0;
  259. LIBBURN_MISCONFIGURATION_ = 0;
  260. #endif /* LIBCDIO_VERSION_NUM < 83 */
  261. version_text = (char *) cdio_version_string;
  262. strncat(msg, version_text, 800);
  263. return 1;
  264. }
  265. /** Performs global initialization of the SCSI transport adapter and eventually
  266. needed operating system facilities. Checks for compatibility of supporting
  267. software components.
  268. @param msg returns ids and/or error messages of eventual helpers
  269. @param flag unused yet, submit 0
  270. @return 1 = success, <=0 = failure
  271. */
  272. int sg_initialize(char msg[1024], int flag)
  273. {
  274. int cdio_ver;
  275. char *msg_pt;
  276. cdio_loglevel_default = CDIO_LOG_ASSERT;
  277. msg[0] = 0;
  278. sg_id_string(msg, 0);
  279. cdio_ver = libcdio_version_num;
  280. libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
  281. LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
  282. msg , 0, 0);
  283. if (cdio_ver < LIBCDIO_VERSION_NUM) {
  284. strcat(msg, " ---> ");
  285. msg_pt = msg + strlen(msg);
  286. sprintf(msg_pt,
  287. "libcdio TOO OLD: numeric version %d , need at least %d",
  288. cdio_ver, LIBCDIO_VERSION_NUM);
  289. libdax_msgs_submit(libdax_messenger, -1,
  290. 0x00000002,
  291. LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
  292. msg_pt, 0, 0);
  293. return 0;
  294. }
  295. return 1;
  296. }
  297. /** Performs global finalization of the SCSI transport adapter and eventually
  298. needed operating system facilities. Releases globally aquired resources.
  299. @param flag unused yet, submit 0
  300. @return 1 = success, <=0 = failure
  301. */
  302. int sg_shutdown(int flag)
  303. {
  304. return 1;
  305. }
  306. /** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
  307. struct burn_drive which are defined in os-*.h.
  308. The eventual initialization of those components was made underneath
  309. scsi_enumerate_drives().
  310. This will be called when a burn_drive gets disposed.
  311. @param d the drive to be finalized
  312. @param flag unused yet, submit 0
  313. @return 1 = success, <=0 = failure
  314. */
  315. int sg_dispose_drive(struct burn_drive *d, int flag)
  316. {
  317. return 1;
  318. }
  319. /** Returns the next index number and the next enumerated drive address.
  320. The enumeration has to cover all available and accessible drives. It is
  321. allowed to return addresses of drives which are not available but under
  322. some (even exotic) circumstances could be available. It is on the other
  323. hand allowed, only to hand out addresses which can really be used right
  324. in the moment of this call. (This implementation chooses the latter.)
  325. @param idx An opaque handle. Make no own theories about it.
  326. @param adr Takes the reply
  327. @param adr_size Gives maximum size of reply including final 0
  328. @param initialize 1 = start new,
  329. 0 = continue, use no other values for now
  330. -1 = finish
  331. @return 1 = reply is a valid address , 0 = no further address available
  332. -1 = severe error (e.g. adr_size too small)
  333. */
  334. int sg_give_next_adr(burn_drive_enumerator_t *idx,
  335. char adr[], int adr_size, int initialize)
  336. {
  337. int ret, recursion_count = 0;
  338. char path[4096];
  339. #ifdef Libburn_is_on_solariS
  340. int l;
  341. #endif
  342. ret = sg_give_next_adr_raw(idx, adr, adr_size, initialize);
  343. if (ret <= 0)
  344. return ret;
  345. if (strlen(adr) >= sizeof(path))
  346. return ret;
  347. #ifdef Libburn_is_on_solariS
  348. /* >>> provisory : preserve Solaris /dev/rdsk/cXtYdZs2 addresses */
  349. l = strlen(adr);
  350. if (l >= 18)
  351. if (strncmp(adr, "/dev/rdsk/c", 11) == 0 && adr[11] >= '0' &&
  352. adr[11] <= '9' && strcmp(adr + (l - 2), "s2") == 0)
  353. return 1;
  354. #endif /* Libburn_is_on_solariS */
  355. ret = burn_drive_resolve_link(adr, path, &recursion_count, 2);
  356. if(ret > 0 && strlen(path) < adr_size)
  357. strcpy(path, adr);
  358. return (ret >= 0);
  359. }
  360. /** Brings all available, not-whitelist-banned, and accessible drives into
  361. libburn's list of drives.
  362. */
  363. int scsi_enumerate_drives(void)
  364. {
  365. burn_drive_enumerator_t idx;
  366. int initialize = 1, ret, i_bus_no = -1, recursion_count = 0;
  367. int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1;
  368. char buf[4096], target[4096];
  369. #ifdef Libburn_is_on_solariS
  370. int l;
  371. #endif
  372. while(1) {
  373. ret = sg_give_next_adr_raw(&idx, buf, sizeof(buf), initialize);
  374. initialize = 0;
  375. if (ret <= 0)
  376. break;
  377. ret = 1;
  378. #ifdef Libburn_is_on_solariS
  379. /* >>> provisory : preserve Solaris /dev/rdsk/cXtYdZs2 */
  380. l = strlen(buf);
  381. if (l >= 18)
  382. if (strncmp(buf, "/dev/rdsk/c", 11) == 0 &&
  383. buf[11] >= '0' && buf[11] <= '9' &&
  384. strcmp(buf + (l - 2), "s2") == 0)
  385. ret = 0;
  386. #endif /* Libburn_is_on_solariS */
  387. if (ret == 1) {
  388. ret = burn_drive_resolve_link(buf, target,
  389. &recursion_count,2);
  390. }
  391. if (ret <= 0)
  392. strcpy(target, buf);
  393. if (burn_drive_is_banned(target))
  394. continue;
  395. sg_obtain_scsi_adr(buf, &i_bus_no, &i_host_no,
  396. &i_channel_no, &i_target_no, &i_lun_no);
  397. enumerate_common(target, buf,
  398. i_bus_no, i_host_no, i_channel_no,
  399. i_target_no, i_lun_no);
  400. }
  401. sg_give_next_adr(&idx, buf, sizeof(buf), -1);
  402. return 1;
  403. }
  404. /** Tells whether libburn has the given drive in use or exclusively reserved.
  405. If it is "open" then libburn will eventually call sg_release() on it when
  406. it is time to give up usage resp. reservation.
  407. */
  408. /** Published as burn_drive.drive_is_open() */
  409. int sg_drive_is_open(struct burn_drive * d)
  410. {
  411. return (d->p_cdio != NULL);
  412. }
  413. /** Opens the drive for SCSI commands and - if burn activities are prone
  414. to external interference on your system - obtains an exclusive access lock
  415. on the drive. (Note: this is not physical tray locking.)
  416. A drive that has been opened with sg_grab() will eventually be handed
  417. over to sg_release() for closing and unreserving.
  418. */
  419. int sg_grab(struct burn_drive *d)
  420. {
  421. CdIo_t *p_cdio;
  422. char *am_eff, msg[4096], *am_wanted;
  423. int os_errno, second_try = 0;
  424. if (d->p_cdio != NULL) {
  425. d->released = 0;
  426. return 1;
  427. }
  428. if (d->libcdio_name[0] == 0) /* just to be sure it is initialized */
  429. strcpy(d->libcdio_name, d->devname);
  430. am_wanted = (burn_sg_open_o_excl & 63) ? "MMC_RDWR_EXCL" : "MMC_RDWR";
  431. try_to_open:;
  432. p_cdio = cdio_open_am(d->libcdio_name, DRIVER_DEVICE, am_wanted);
  433. if (p_cdio == NULL) {
  434. os_errno = errno;
  435. sprintf(msg, "Could not grab drive '%s'", d->devname);
  436. libdax_msgs_submit(libdax_messenger, d->global_index,
  437. 0x00020003,
  438. LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
  439. msg, os_errno, 0);
  440. return 0;
  441. }
  442. am_eff = (char *) cdio_get_arg(p_cdio, "access-mode");
  443. if (strncmp(am_eff, "MMC_RDWR", 8) != 0) {
  444. cdio_destroy(p_cdio);
  445. if (!second_try) {
  446. am_wanted = (burn_sg_open_o_excl & 63) ?
  447. "MMC_RDWR" : "MMC_RDWR_EXCL";
  448. second_try = 1;
  449. goto try_to_open;
  450. }
  451. libdax_msgs_submit(libdax_messenger, d->global_index,
  452. 0x00020003,
  453. LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
  454. "libcdio provides no MMC_RDWR access mode", 0, 0);
  455. return 0;
  456. }
  457. d->p_cdio = p_cdio;
  458. d->released = 0;
  459. return 1;
  460. }
  461. /** PORTING: Is mainly about the call to sg_close_drive() and whether it
  462. implements the demanded functionality.
  463. */
  464. /** Gives up the drive for SCSI commands and releases eventual access locks.
  465. (Note: this is not physical tray locking.)
  466. */
  467. int sg_release(struct burn_drive *d)
  468. {
  469. if (d->p_cdio == NULL) {
  470. burn_print(1, "release an ungrabbed drive. die\n");
  471. return 0;
  472. }
  473. sg_close_drive(d);
  474. return 0;
  475. }
  476. /** Sends a SCSI command to the drive, receives reply and evaluates wether
  477. the command succeeded or shall be retried or finally failed.
  478. Returned SCSI errors shall not lead to a return value indicating failure.
  479. The callers get notified by c->error. An SCSI failure which leads not to
  480. a retry shall be notified via scsi_notify_error().
  481. The Libburn_log_sg_commandS facility might be of help when problems with
  482. a drive have to be examined. It shall stay disabled for normal use.
  483. @return: 1 success , <=0 failure
  484. */
  485. int sg_issue_command(struct burn_drive *d, struct command *c)
  486. {
  487. int sense_valid = 0, i, usleep_time, timeout_ms, no_retry = 0;
  488. int key = 0, asc = 0, ascq = 0;
  489. time_t start_time;
  490. driver_return_code_t i_status;
  491. unsigned int dxfer_len;
  492. static FILE *fp = NULL;
  493. mmc_cdb_t cdb = {{0, }};
  494. cdio_mmc_direction_t e_direction;
  495. CdIo_t *p_cdio;
  496. unsigned char *sense_pt = NULL;
  497. c->error = 0;
  498. if (d->p_cdio == NULL) {
  499. return 0;
  500. }
  501. p_cdio = (CdIo_t *) d->p_cdio;
  502. if (burn_sg_log_scsi & 1) {
  503. if (fp == NULL) {
  504. fp= fopen("/tmp/libburn_sg_command_log", "a");
  505. fprintf(fp,
  506. "\n-----------------------------------------\n");
  507. }
  508. }
  509. if (burn_sg_log_scsi & 3)
  510. scsi_log_cmd(c,fp,0);
  511. memcpy(cdb.field, c->opcode, c->oplen);
  512. if (c->dir == TO_DRIVE) {
  513. dxfer_len = c->page->bytes;
  514. e_direction = SCSI_MMC_DATA_WRITE;
  515. } else if (c->dir == FROM_DRIVE) {
  516. if (c->dxfer_len >= 0)
  517. dxfer_len = c->dxfer_len;
  518. else
  519. dxfer_len = BUFFER_SIZE;
  520. e_direction = SCSI_MMC_DATA_READ;
  521. /* touch page so we can use valgrind */
  522. memset(c->page->data, 0, BUFFER_SIZE);
  523. } else {
  524. dxfer_len = 0;
  525. e_direction = SCSI_MMC_DATA_NONE;
  526. }
  527. /* retry-loop */
  528. start_time = time(NULL);
  529. timeout_ms = 200000;
  530. for(i = 0; ; i++) {
  531. i_status = mmc_run_cmd(p_cdio, timeout_ms, &cdb, e_direction,
  532. dxfer_len, c->page->data);
  533. sense_valid = mmc_last_cmd_sense(p_cdio, &sense_pt);
  534. if (sense_valid >= 18) {
  535. memcpy(c->sense, sense_pt,
  536. sense_valid >= sizeof(c->sense) ?
  537. sizeof(c->sense) : sense_valid );
  538. spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
  539. } else
  540. key = asc = ascq = 0;
  541. if (sense_pt != NULL)
  542. free(sense_pt);
  543. /* Regrettably mmc_run_cmd() does not clearly distinguish between transport
  544. failure and SCSI error reply.
  545. This reaction here would be for transport failure:
  546. if (i_status != 0 && i_status != DRIVER_OP_ERROR) {
  547. libdax_msgs_submit(libdax_messenger,
  548. d->global_index, 0x0002010c,
  549. LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
  550. "Failed to transfer command to drive",
  551. errno, 0);
  552. sg_close_drive(d);
  553. d->released = 1;
  554. d->busy = BURN_DRIVE_IDLE;
  555. c->error = 1;
  556. return -1;
  557. }
  558. */
  559. if ((!sense_valid) || (key == 0 && asc == 0 && ascq == 0)) {
  560. memset(c->sense, 0, sizeof(c->sense));
  561. if (i_status != 0) { /* set dummy sense */
  562. /*LOGICAL UNIT NOT READY,
  563. CAUSE NOT REPORTABLE*/
  564. c->sense[0] = 0x70; /*Fixed format sense data*/
  565. c->sense[2] = 0x02;
  566. c->sense[12] = 0x04;
  567. no_retry = 1;
  568. }
  569. }
  570. if (i_status != 0 || (key || asc || ascq)) {
  571. if (no_retry || !c->retry) {
  572. c->error = 1;
  573. goto ex;
  574. }
  575. switch (scsi_error(d, c->sense, 18)) {
  576. case RETRY:
  577. if (burn_sg_log_scsi & 3) {
  578. /* >>> Need own duration time
  579. measurement. Then remove bit1 */
  580. scsi_log_err(c, fp, c->sense, 18, 0,
  581. 1 | 2);
  582. scsi_log_cmd(c,fp,0);
  583. }
  584. break;
  585. case FAIL:
  586. c->error = 1;
  587. goto ex;
  588. }
  589. /*
  590. Calming down retries and breaking up endless cycle
  591. */
  592. usleep_time = Libburn_sg_libcdio_retry_usleeP +
  593. i * Libburn_sg_libcdio_retry_incR;
  594. if (time(NULL) + usleep_time / 1000000 - start_time >
  595. timeout_ms / 1000 + 1) {
  596. c->error = 1;
  597. goto ex;
  598. }
  599. usleep(usleep_time);
  600. } else
  601. break; /* retry-loop */
  602. } /* end of retry-loop */
  603. ex:;
  604. if (c->error)
  605. scsi_notify_error(d, c, c->sense, 18, 0);
  606. if (burn_sg_log_scsi & 3)
  607. /* >>> Need own duration time measurement. Then remove bit1 */
  608. scsi_log_err(c, fp, c->sense, 18, 0, (c->error != 0) | 2);
  609. return 1;
  610. }
  611. /** Tries to obtain SCSI address parameters.
  612. @return 1 is success , 0 is failure
  613. */
  614. int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
  615. int *target_no, int *lun_no)
  616. {
  617. CdIo_t *p_cdio;
  618. char *tuple;
  619. *bus_no = *host_no = *channel_no = *target_no = *lun_no = -1;
  620. p_cdio = cdio_open(path, DRIVER_DEVICE);
  621. if (p_cdio == NULL)
  622. return 0;
  623. /* Try whether a bus,host,channel,target,lun address tuple is
  624. available */
  625. tuple = (char *) cdio_get_arg(p_cdio, "scsi-tuple");
  626. if (tuple != NULL) if (tuple[0]) {
  627. sscanf(tuple, "%d,%d,%d,%d,%d",
  628. bus_no, host_no, channel_no, target_no, lun_no);
  629. }
  630. cdio_destroy(p_cdio);
  631. return (*bus_no >= 0);
  632. }
  633. /** Tells wether a text is a persistent address as listed by the enumeration
  634. functions.
  635. */
  636. int sg_is_enumerable_adr(char* adr)
  637. {
  638. burn_drive_enumerator_t idx;
  639. int initialize = 1, ret;
  640. char buf[64];
  641. while(1) {
  642. ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
  643. initialize = 0;
  644. if (ret <= 0)
  645. break;
  646. if (strcmp(adr, buf) == 0) {
  647. sg_give_next_adr(&idx, buf, sizeof(buf), -1);
  648. return 1;
  649. }
  650. }
  651. sg_give_next_adr(&idx, buf, sizeof(buf), -1);
  652. return (0);
  653. }
  654. #ifdef __FreeBSD__
  655. #define Libburn_guess_block_devicE 1
  656. #endif
  657. #ifdef __FreeBSD_kernel__
  658. #define Libburn_guess_block_devicE 1
  659. #endif
  660. #ifdef Libburn_guess_block_devicE
  661. /* ts B00115 */
  662. /* The FreeBSD implementation of burn_os_is_2k_seekrw().
  663. On FreeBSD there are no block devices.
  664. */
  665. static int freebsd_is_2k_seekrw(char *path, int flag)
  666. {
  667. struct stat stbuf;
  668. char *spt;
  669. int i, e;
  670. if (stat(path, &stbuf) == -1)
  671. return 0;
  672. if (S_ISREG(stbuf.st_mode))
  673. return 1;
  674. if (!S_ISCHR(stbuf.st_mode))
  675. return 0;
  676. spt = strrchr(path, '/');
  677. if (spt == NULL)
  678. spt = path;
  679. else
  680. spt++;
  681. e = strlen(spt);
  682. for (i = strlen(spt) - 1; i > 0; i--)
  683. if (spt[i] >= '0' && spt[i] <= '9')
  684. e = i;
  685. if (strncmp(spt, "da", e) == 0) /* SCSI disk. E.g. USB stick. */
  686. return 1;
  687. if (strncmp(spt, "cd", e) == 0) /* SCSI CD drive might be writeable. */
  688. return 1;
  689. if (strncmp(spt, "ad", e) == 0) /* IDE hard drive */
  690. return 1;
  691. if (strncmp(spt, "acd", e) == 0) /* IDE CD drive might be writeable */
  692. return 1;
  693. if (strncmp(spt, "fd", e) == 0) /* Floppy disk */
  694. return 1;
  695. if (strncmp(spt, "fla", e) == 0) /* Flash drive */
  696. return 1;
  697. return 0;
  698. }
  699. #endif /* Libburn_guess_block_devicE */
  700. /* Return 1 if the given path leads to a regular file or a device that can be
  701. seeked, read, and possibly written with 2 kB granularity.
  702. */
  703. int burn_os_is_2k_seekrw(char *path, int flag)
  704. {
  705. #ifdef Libburn_guess_block_devicE
  706. return freebsd_is_2k_seekrw(path, flag);
  707. #else
  708. struct stat stbuf;
  709. if (stat(path, &stbuf) == -1)
  710. return 0;
  711. if (S_ISREG(stbuf.st_mode))
  712. return 1;
  713. if (S_ISBLK(stbuf.st_mode))
  714. return 1;
  715. return 0;
  716. #endif /* ! Libburn_guess_block_devicE */
  717. }
  718. /** Estimate the potential payload capacity of a file address.
  719. @param path The address of the file to be examined. If it does not
  720. exist yet, then the directory will be inquired.
  721. @param bytes The pointed value gets modified, but only if an estimation is
  722. possible.
  723. @return -2 = cannot perform necessary operations on file object
  724. -1 = neither path nor dirname of path exist
  725. 0 = could not estimate size capacity of file object
  726. 1 = estimation has been made, bytes was set
  727. */
  728. int burn_os_stdio_capacity(char *path, off_t *bytes)
  729. {
  730. struct stat stbuf;
  731. #ifdef Libburn_os_has_statvfS
  732. struct statvfs vfsbuf;
  733. #endif
  734. char testpath[4096], *cpt;
  735. long blocks;
  736. off_t add_size = 0;
  737. testpath[0] = 0;
  738. blocks = *bytes / 512;
  739. if (stat(path, &stbuf) == -1) {
  740. strcpy(testpath, path);
  741. cpt = strrchr(testpath, '/');
  742. if(cpt == NULL)
  743. strcpy(testpath, ".");
  744. else if(cpt == testpath)
  745. testpath[1] = 0;
  746. else
  747. *cpt = 0;
  748. if (stat(testpath, &stbuf) == -1)
  749. return -1;
  750. #ifdef __linux
  751. /* GNU/Linux specific determination of block device size */
  752. } else if(S_ISBLK(stbuf.st_mode)) {
  753. int open_mode = O_RDONLY, fd, ret;
  754. fd = open(path, open_mode);
  755. if (fd == -1)
  756. return -2;
  757. ret = ioctl(fd, BLKGETSIZE, &blocks);
  758. close(fd);
  759. if (ret == -1)
  760. return -2;
  761. *bytes = ((off_t) blocks) * (off_t) 512;
  762. #endif /* __linux */
  763. #ifdef Libburn_is_on_freebsD
  764. } else if(S_ISCHR(stbuf.st_mode)) {
  765. int fd, ret;
  766. fd = open(path, O_RDONLY);
  767. if (fd == -1)
  768. return -2;
  769. ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
  770. close(fd);
  771. if (ret == -1)
  772. return -2;
  773. *bytes = add_size;
  774. #endif /* Libburn_is_on_freebsD */
  775. #ifdef Libburn_is_on_solariS
  776. } else if(S_ISBLK(stbuf.st_mode)) {
  777. int open_mode = O_RDONLY, fd;
  778. fd = open(path, open_mode);
  779. if (fd == -1)
  780. return -2;
  781. *bytes = lseek(fd, 0, SEEK_END);
  782. close(fd);
  783. if (*bytes == -1) {
  784. *bytes = 0;
  785. return 0;
  786. }
  787. #endif /* Libburn_is_on_solariS */
  788. } else if(S_ISREG(stbuf.st_mode)) {
  789. add_size = stbuf.st_blocks * (off_t) 512;
  790. strcpy(testpath, path);
  791. } else
  792. return 0;
  793. if (testpath[0]) {
  794. #ifdef Libburn_os_has_statvfS
  795. if (statvfs(testpath, &vfsbuf) == -1)
  796. return -2;
  797. *bytes = add_size + ((off_t) vfsbuf.f_frsize) *
  798. (off_t) vfsbuf.f_bavail;
  799. #else /* Libburn_os_has_statvfS */
  800. return 0;
  801. #endif /* ! Libburn_os_has_stavtfS */
  802. }
  803. return 1;
  804. }
  805. /* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
  806. #ifdef Libburn_read_o_direcT
  807. /* No special O_DIRECT-like precautions are implemented here */
  808. #endif /* Libburn_read_o_direcT */
  809. int burn_os_open_track_src(char *path, int open_flags, int flag)
  810. {
  811. int fd;
  812. fd = open(path, open_flags);
  813. return fd;
  814. }
  815. void *burn_os_alloc_buffer(size_t amount, int flag)
  816. {
  817. void *buf = NULL;
  818. buf = calloc(1, amount);
  819. return buf;
  820. }
  821. int burn_os_free_buffer(void *buffer, size_t amount, int flag)
  822. {
  823. if (buffer == NULL)
  824. return 0;
  825. free(buffer);
  826. return 1;
  827. }