📄 transport.c.htm
字号:
<a class="l" name="48"> 48 </a><a href="/source/s?defs=get_uscsi_cmd">get_uscsi_cmd</a>(<b>void</b>)<a class="l" name="49"> 49 </a>{<a class="hl" name="50"> 50 </a> (<b>void</b>) <a href="/source/s?defs=memset">memset</a>(&<a href="/source/s?defs=uscmd">uscmd</a>, <span class="n">0</span>, <b>sizeof</b> (<a href="/source/s?defs=uscmd">uscmd</a>));<a class="l" name="51"> 51 </a> (<b>void</b>) <a href="/source/s?defs=memset">memset</a>(<a href="/source/s?defs=ucdb">ucdb</a>, <span class="n">0</span>, <span class="n">16</span>);<a class="l" name="52"> 52 </a> <a href="/source/s?defs=uscmd">uscmd</a>.<a href="/source/s?defs=uscsi_cdb">uscsi_cdb</a> = <a href="/source/s?defs=ucdb">ucdb</a>;<a class="l" name="53"> 53 </a> <b>return</b> (&<a href="/source/s?defs=uscmd">uscmd</a>);<a class="l" name="54"> 54 </a>}<a class="l" name="55"> 55 </a><a class="l" name="56"> 56 </a><b>int</b><a class="l" name="57"> 57 </a><a href="/source/s?defs=uscsi">uscsi</a>(<b>int</b> <a href="/source/s?defs=fd">fd</a>, <b>struct</b> <a href="/source/s?defs=uscsi_cmd">uscsi_cmd</a> *<a href="/source/s?defs=scmd">scmd</a>)<a class="l" name="58"> 58 </a>{<a class="l" name="59"> 59 </a> <b>int</b> <a href="/source/s?defs=ret">ret</a>, <a href="/source/s?defs=global_rqsense">global_rqsense</a>;<a class="hl" name="60"> 60 </a> <b>int</b> <a href="/source/s?defs=retries">retries</a>, <a href="/source/s?defs=max_retries">max_retries</a>;<a class="l" name="61"> 61 </a><a class="l" name="62"> 62 </a> <span class="c">/* set up for request sense extensions */</span><a class="l" name="63"> 63 </a> <b>if</b> (!(<a href="/source/s?defs=scmd">scmd</a>-><a href="/source/s?defs=uscsi_flags">uscsi_flags</a> & <a href="/source/s?defs=USCSI_RQENABLE">USCSI_RQENABLE</a>)) {<a class="l" name="64"> 64 </a> <a href="/source/s?defs=scmd">scmd</a>-><a href="/source/s?defs=uscsi_flags">uscsi_flags</a> |= <a href="/source/s?defs=USCSI_RQENABLE">USCSI_RQENABLE</a>;<a class="l" name="65"> 65 </a> <a href="/source/s?defs=scmd">scmd</a>-><a href="/source/s?defs=uscsi_rqlen">uscsi_rqlen</a> = <a href="/source/s?defs=RQBUFLEN">RQBUFLEN</a>;<a class="l" name="66"> 66 </a> <a href="/source/s?defs=scmd">scmd</a>-><a href="/source/s?defs=uscsi_rqbuf">uscsi_rqbuf</a> = <a href="/source/s?defs=rqbuf">rqbuf</a>;<a class="l" name="67"> 67 </a> <a href="/source/s?defs=global_rqsense">global_rqsense</a> = <span class="n">1</span>;<a class="l" name="68"> 68 </a> } <b>else</b> {<a class="l" name="69"> 69 </a> <a href="/source/s?defs=global_rqsense">global_rqsense</a> = <span class="n">0</span>;<a class="hl" name="70"> 70 </a> }<a class="l" name="71"> 71 </a><a class="l" name="72"> 72 </a> <span class="c">/*<a class="l" name="73"> 73 </a> * Some DVD drives may have a delay for writing or sync cache, and<a class="l" name="74"> 74 </a> * read media info (done after syncing cache). This can take a<a class="l" name="75"> 75 </a> * significant number of time. Such as the Pioneer A0X which will<a class="l" name="76"> 76 </a> * generate TOC after the cache is full in the middle of writing.<a class="l" name="77"> 77 </a> */</span><a class="l" name="78"> 78 </a><a class="l" name="79"> 79 </a> <b>if</b> ((<a href="/source/s?defs=device_type">device_type</a> != <a href="/source/s?defs=CD_RW">CD_RW</a>) && ((<a href="/source/s?defs=scmd">scmd</a>-><a href="/source/s?defs=uscsi_cdb">uscsi_cdb</a>[<span class="n">0</span>] == <a href="/source/s?defs=WRITE_10_CMD">WRITE_10_CMD</a>) ||<a class="hl" name="80"> 80 </a> (<a href="/source/s?defs=scmd">scmd</a>-><a href="/source/s?defs=uscsi_cdb">uscsi_cdb</a>[<span class="n">0</span>] == <a href="/source/s?defs=READ_INFO_CMD">READ_INFO_CMD</a>) || (<a href="/source/s?defs=scmd">scmd</a>-><a href="/source/s?defs=uscsi_cdb">uscsi_cdb</a>[<span class="n">0</span>] ==<a class="l" name="81"> 81 </a> <a href="/source/s?defs=SYNC_CACHE_CMD">SYNC_CACHE_CMD</a>) || (<a href="/source/s?defs=scmd">scmd</a>-><a href="/source/s?defs=uscsi_cdb">uscsi_cdb</a>[<span class="n">0</span>] == <a href="/source/s?defs=CLOSE_TRACK_CMD">CLOSE_TRACK_CMD</a>))) {<a class="l" name="82"> 82 </a><a class="l" name="83"> 83 </a> <a href="/source/s?defs=max_retries">max_retries</a> = <span class="n">500</span>;<a class="l" name="84"> 84 </a> } <b>else</b> {<a class="l" name="85"> 85 </a> <span class="c">/*<a class="l" name="86"> 86 </a> * Pioneer <a href="/source/s?path=A08/">A08</a>/<a href="/source/s?path=A08/A09">A09</a> retries approx 30 times.<a class="l" name="87"> 87 </a> */</span><a class="l" name="88"> 88 </a> <a href="/source/s?defs=max_retries">max_retries</a> = <span class="n">40</span>;<a class="l" name="89"> 89 </a> }<a class="hl" name="90"> 90 </a><a class="l" name="91"> 91 </a> <span class="c">/*<a class="l" name="92"> 92 </a> * The device may be busy or slow and fail with a not ready status.<a class="l" name="93"> 93 </a> * we'll allow a limited number of retries to give the drive time<a class="l" name="94"> 94 </a> * to recover.<a class="l" name="95"> 95 </a> */</span><a class="l" name="96"> 96 </a> <b>for</b> (<a href="/source/s?defs=retries">retries</a> = <span class="n">0</span>; <a href="/source/s?defs=retries">retries</a> < <a href="/source/s?defs=max_retries">max_retries</a>; <a href="/source/s?defs=retries">retries</a>++) {<a class="l" name="97"> 97 </a><a class="l" name="98"> 98 </a> <a href="/source/s?defs=scmd">scmd</a>-><a href="/source/s?defs=uscsi_status">uscsi_status</a> = <span class="n">0</span>;<a class="l" name="99"> 99 </a><a class="hl" name="100"> 100 </a> <b>if</b> (<a href="/source/s?defs=global_rqsense">global_rqsense</a>)<a class="l" name="101"> 101 </a> (<b>void</b>) <a href="/source/s?defs=memset">memset</a>(<a href="/source/s?defs=rqbuf">rqbuf</a>, <span class="n">0</span>, <a href="/source/s?defs=RQBUFLEN">RQBUFLEN</a>);<a class="l" name="102"> 102 </a><a class="l" name="103"> 103 </a> <b>if</b> (<a href="/source/s?defs=debug">debug</a> && <a href="/source/s?defs=verbose">verbose</a>) {<a class="l" name="104"> 104 </a> <b>int</b> i;<a class="l" name="105"> 105 </a><a class="l" name="106"> 106 </a> (<b>void</b>) <a href="/source/s?defs=printf">printf</a>(<span class="s">"cmd:["</span>);<a class="l" name="107"> 107 </a> <b>for</b> (i = <span class="n">0</span>; i < <a href="/source/s?defs=scmd">scmd</a>-><a href="/source/s?defs=uscsi_cdblen">uscsi_cdblen</a>; i++)<a class="l" name="108"> 108 </a> (<b>void</b>) <a href="/source/s?defs=printf">printf</a>(<span class="s">"0x%02x "</span>,<a class="l" name="109"> 109 </a> (<a href="/source/s?defs=uchar_t">uchar_t</a>)<a href="/source/s?defs=scmd">scmd</a>-><a href="/source/s?defs=uscsi_cdb">uscsi_cdb</a>[i]);<a class="hl" name="110"> 110 </a> (<b>void</b>) <a href="/source/s?defs=printf">printf</a>(<span class="s">"]\n"</span>);<a class="l" name="111"> 111 </a> }<a class="l" name="112"> 112 </a><a class="l" name="113"> 113 </a> <span class="c">/*<a class="l" name="114"> 114 </a> * We need to have root privledges in order to use<a class="l" name="115"> 115 </a> * uscsi commands on the device.<a class="l" name="116"> 116 </a> */</span><a class="l" name="117"> 117 </a><a class="l" name="118"> 118 </a> <a href="/source/s?defs=raise_priv">raise_priv</a>();<a class="l" name="119"> 119 </a> <a href="/source/s?defs=ret">ret</a> = <a href="/source/s?defs=ioctl">ioctl</a>(<a href="/source/s?defs=fd">fd</a>, <a href="/source/s?defs=USCSICMD">USCSICMD</a>, <a href="/source/s?defs=scmd">scmd</a>);<a class="hl" name="120"> 120 </a> <a href="/source/s?defs=lower_priv">lower_priv</a>();<a class="l" name="121"> 121 </a><a class="l" name="122"> 122 </a> <span class="c">/* maintain consistency in case of sgen */</span><a class="l" name="123"> 123 </a> <b>if</b> ((<a href="/source/s?defs=ret">ret</a> == <span class="n">0</span>) && (<a href="/source/s?defs=scmd">scmd</a>-><a href="/source/s?defs=uscsi_status">uscsi_status</a> == <span class="n">2</span>)) {<a class="l" name="124"> 124 </a> <a href="/source/s?defs=ret">ret</a> = -<span class="n">1</span>;<a class="l" name="125"> 125 </a> <a href="/source/s?defs=errno">errno</a> = <a href="/source/s?defs=EIO">EIO</a>;<a class="l" name="126"> 126 </a> }<a class="l" name="127"> 127 </a><a class="l" name="128"> 128 </a> <span class="c">/* if error and extended request sense, retrieve errors */</span><a class="l" name="129"> 129 </a> <b>if</b> (<a href="/source/s?defs=global_rqsense">global_rqsense</a> && (<a href="/source/s?defs=ret">ret</a> < <span class="n">0</span>) && (<a href="/source/s?defs=scmd">scmd</a>-><a href="/source/s?defs=uscsi_status">uscsi_status</a> == <span class="n">2</span>)) {<a class="hl" name="130"> 130 </a> <span class="c">/*<a class="l" name="131"> 131 </a> * The drive is not ready to recieve commands but<a class="l" name="132"> 132 </a> * may be in the process of becoming ready.<a class="l" name="133"> 133 </a> * sleep for a short time then retry command.<a class="l" name="134"> 134 </a> * <a href="/source/s?path=SENSE/">SENSE</a>/<a href="/source/s?path=SENSE/ASC">ASC</a> = 2/4 : not ready<a class="l" name="135"> 135 </a> * ASCQ = 0 Not Reportable.<a class="l" name="136"> 136 </a> * ASCQ = 1 Becoming ready.<a class="l" name="137"> 137 </a> * ASCQ = 4 FORMAT in progress.<a class="l" name="138"> 138 </a> * ASCQ = 7 Operation in progress.<a class="l" name="139"> 139 </a> * ASCQ = 8 Long write in progress.<a class="hl" name="140"> 140 </a> */</span><a class="l" name="141"> 141 </a> <b>if</b> ((<a href="/source/s?defs=SENSE_KEY">SENSE_KEY</a>(<a href="/source/s?defs=rqbuf">rqbuf</a>) == <span class="n">2</span>) && (<a href="/source/s?defs=ASC">ASC</a>(<a href="/source/s?defs=rqbuf">rqbuf</a>) == <span class="n">4</span>) &&<a class="l" name="142"> 142 </a> ((<a href="/source/s?defs=ASCQ">ASCQ</a>(<a href="/source/s?defs=rqbuf">rqbuf</a>) == <span class="n">0</span>) || (<a href="/source/s?defs=ASCQ">ASCQ</a>(<a href="/source/s?defs=rqbuf">rqbuf</a>) == <span class="n">1</span>) ||<a class="l" name="143"> 143 </a> (<a href="/source/s?defs=ASCQ">ASCQ</a>(<a href="/source/s?defs=rqbuf">rqbuf</a>) == <span class="n">4</span>)) || (<a href="/source/s?defs=ASCQ">ASCQ</a>(<a href="/source/s?defs=rqbuf">rqbuf</a>) == <span class="n">7</span>)) {<a class="l" name="144"> 144 </a> <a href="/source/s?defs=total_retries">total_retries</a>++;<a class="l" name="145"> 145 </a> (<b>void</b>) <a href="/source/s?defs=sleep">sleep</a>(<span class="n">3</span>);<a class="l" name="146"> 146 </a> <b>continue</b>;<a class="l" name="147"> 147 </a> }<a class="l" name="148"> 148 </a><a class="l" name="149"> 149 </a> <span class="c">/*<a class="hl" name="150"> 150 </a> * we do not print this out under normal circumstances<a class="l" name="151"> 151 </a> * since we have BUFE enabled and do not want to alarm<a class="l" name="152"> 152 </a> * users with uneccessary messages.<a class="l" name="153"> 153 </a> */</span><a class="l" name="154"> 154 </a> <b>if</b> (<a href="/source/s?defs=debug">debug</a>) {<a class="l" name="155"> 155 </a> <b>if</b> ((<a href="/source/s?defs=SENSE_KEY">SENSE_KEY</a>(<a href="/source/s?defs=rqbuf">rqbuf</a>) == <span class="n">5</span>) && (<a href="/source/s?defs=ASC">ASC</a>(<a href="/source/s?defs=rqbuf">rqbuf</a>) ==<a class="l" name="156"> 156 </a> <span class="n">0x21</span>) && (<a href="/source/s?defs=ASCQ">ASCQ</a>(<a href="/source/s?defs=rqbuf">rqbuf</a>) == <span class="n">2</span>)) {<a class="l" name="157"> 157 </a> (<b>void</b>) <a href="/source/s?defs=printf">printf</a>(<a href="/source/s?defs=gettext">gettext</a>(<a class="l" name="158"> 158 </a> <span class="s">"Buffer underrun occurred! trying to recover...\n"</span>));<a class="l" name="159"> 159 </a> }<a class="hl" name="160"> 160 </a> }<a class="l" name="161"> 161 </a><a class="l" name="162"> 162 </a> <span class="c">/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -