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.

186 lines
4.6 KiB

15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
  1. /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
  2. /* scsi block commands */
  3. /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
  4. Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
  5. Provided under GPL version 2 or later.
  6. */
  7. #ifdef HAVE_CONFIG_H
  8. #include "../config.h"
  9. #endif
  10. #include <string.h>
  11. #include <unistd.h>
  12. #include "transport.h"
  13. #include "sbc.h"
  14. #include "spc.h"
  15. #include "options.h"
  16. /* ts A70910
  17. debug: for tracing calls which might use open drive fds
  18. or for catching SCSI usage of emulated drives. */
  19. int mmc_function_spy(struct burn_drive *d, char * text);
  20. /* START STOP UNIT as of SBC-1 and SBC-2
  21. 0: Opcode 0x1B
  22. 1: bit0= Immed
  23. bit1-7= reserved
  24. 2: reserved
  25. 3: reserved
  26. 4: bit0= Start (else Stop unit)
  27. bit1= Load/Eject (according to Start resp. Stop)
  28. bit2-3= reserved
  29. bit4-7= Power Condition
  30. 0= Start Valid: process Start and Load/Eject bits
  31. 1= assume Active state
  32. 2= assume Idle state
  33. 3= assume Stanby state
  34. (5= SBC-1 only: assume Sleep state)
  35. 7= transfer control of power conditions to logical unit
  36. 10= force idle condition timer to 0
  37. 11= force standby condition timer to 0
  38. All others are reserved.
  39. 5: Control (set to 0)
  40. */
  41. static unsigned char SBC_LOAD[] = { 0x1b, 0, 0, 0, 3, 0 };
  42. static unsigned char SBC_UNLOAD[] = { 0x1b, 0, 0, 0, 2, 0 };
  43. static unsigned char SBC_START_UNIT[] = { 0x1b, 0, 0, 0, 1, 0 };
  44. static unsigned char SBC_STOP_UNIT[] = { 0x1b, 0, 0, 0, 0, 0 };
  45. void sbc_load(struct burn_drive *d)
  46. {
  47. struct command *c;
  48. c = &(d->casual_command);
  49. if (mmc_function_spy(d, "load") <= 0)
  50. return;
  51. scsi_init_command(c, SBC_LOAD, sizeof(SBC_LOAD));
  52. c->retry = 1;
  53. /* ts A70921 : Had to revoke Immed because of LG GSA-4082B */
  54. /* c->opcode[1] |= 1; / * ts A70918 : Immed */
  55. c->dir = NO_TRANSFER;
  56. c->timeout = Libburn_mmc_load_timeouT;
  57. d->issue_command(d, c);
  58. if (c->error)
  59. return;
  60. /* ts A70923 : Needed regardless of Immed bit. Was once 1 minute, now
  61. 5 minutes for loading. If this does not suffice then other commands
  62. shall fail righteously. */
  63. spc_wait_unit_attention(d, 300, "waiting after START UNIT (+ LOAD)",0);
  64. }
  65. void sbc_eject(struct burn_drive *d)
  66. {
  67. struct command *c;
  68. c = &(d->casual_command);
  69. if (mmc_function_spy(d, "eject") <= 0)
  70. return;
  71. scsi_init_command(c, SBC_UNLOAD, sizeof(SBC_UNLOAD));
  72. /* c->opcode[1] |= 1; / * ts A70918 : Immed , ts B00109 : revoked */
  73. c->page = NULL;
  74. c->dir = NO_TRANSFER;
  75. d->issue_command(d, c);
  76. /* ts A70918 : Wait long. A late eject could surprise or hurt user.
  77. ts B00109 : Asynchronous eject revoked, as one cannot reliably
  78. distinguish out from unready.
  79. if (c->error)
  80. return;
  81. spc_wait_unit_attention(d, 1800, "STOP UNIT (+ EJECT)", 0);
  82. */
  83. }
  84. /* ts A91112 : Now with flag */
  85. /* @param flag bit0= asynchronous waiting
  86. */
  87. int sbc_start_unit_flag(struct burn_drive *d, int flag)
  88. {
  89. struct command *c;
  90. int ret;
  91. c = &(d->casual_command);
  92. if (mmc_function_spy(d, "start_unit") <= 0)
  93. return 0;
  94. scsi_init_command(c, SBC_START_UNIT, sizeof(SBC_START_UNIT));
  95. c->retry = 1;
  96. if (d->do_no_immed && (flag & 1))
  97. c->timeout = 1800 * 1000;
  98. else
  99. c->opcode[1] |= (flag & 1); /* ts A70918 : Immed */
  100. c->dir = NO_TRANSFER;
  101. d->issue_command(d, c);
  102. if (c->error)
  103. return 0;
  104. if (d->do_no_immed || !(flag & 1))
  105. return 1;
  106. /* ts A70918 : asynchronous */
  107. ret = spc_wait_unit_attention(d, 1800, "START UNIT", 0);
  108. return ret;
  109. }
  110. int sbc_start_unit(struct burn_drive *d)
  111. {
  112. int ret;
  113. d->is_stopped = 0; /* no endless starting attempts */
  114. /* Asynchronous, not to block controller by waiting */
  115. ret = sbc_start_unit_flag(d, 1);
  116. if (ret <= 0)
  117. return ret;
  118. /* Synchronous to catch Pioneer DVR-216D which is ready too early.
  119. A pending START UNIT can prevent ejecting of the tray.
  120. */
  121. ret = sbc_start_unit_flag(d, 0);
  122. return ret;
  123. }
  124. /* ts A90824 : Trying to reduce drive noise */
  125. int sbc_stop_unit(struct burn_drive *d)
  126. {
  127. struct command *c;
  128. int ret;
  129. c = &(d->casual_command);
  130. if (mmc_function_spy(d, "stop_unit") <= 0)
  131. return 0;
  132. scsi_init_command(c, SBC_STOP_UNIT, sizeof(SBC_STOP_UNIT));
  133. c->retry = 0;
  134. c->opcode[1] |= 1; /* Immed */
  135. c->dir = NO_TRANSFER;
  136. d->issue_command(d, c);
  137. if (c->error)
  138. return 0;
  139. ret = spc_wait_unit_attention(d, 1800, "STOP UNIT", 0);
  140. d->is_stopped = 1;
  141. return ret;
  142. }
  143. /* ts A61021 : the sbc specific part of sg.c:enumerate_common()
  144. */
  145. int sbc_setup_drive(struct burn_drive *d)
  146. {
  147. d->eject = sbc_eject;
  148. d->load = sbc_load;
  149. d->start_unit = sbc_start_unit;
  150. d->stop_unit = sbc_stop_unit;
  151. d->is_stopped = 0;
  152. return 1;
  153. }