<!doctype html>
<html>
<head>
<title>src/hw/usb-msc.c</title>
<style type="text/css">
 body { color:#000000; background-color:#ffffff }
 body { font-family:Helvetica, sans-serif; font-size:10pt }
 h1 { font-size:14pt }
 .code { border-collapse:collapse; width:100%; }
 .code { font-family: "Monospace", monospace; font-size:10pt }
 .code { line-height: 1.2em }
 .comment { color: green; font-style: oblique }
 .keyword { color: blue }
 .string_literal { color: red }
 .directive { color: darkmagenta }
 .expansion { display: none; }
 .macro:hover .expansion { display: block; border: 2px solid #FF0000; padding: 2px; background-color:#FFF0F0; font-weight: normal;   -webkit-border-radius:5px;  -webkit-box-shadow:1px 1px 7px #000; position: absolute; top: -1em; left:10em; z-index: 1 } 
 .macro { color: darkmagenta; background-color:LemonChiffon; position: relative }
 .num { width:2.5em; padding-right:2ex; background-color:#eeeeee }
 .num { text-align:right; font-size:8pt }
 .num { color:#444444 }
 .line { padding-left: 1ex; border-left: 3px solid #ccc }
 .line { white-space: pre }
 .msg { -webkit-box-shadow:1px 1px 7px #000 }
 .msg { -webkit-border-radius:5px }
 .msg { font-family:Helvetica, sans-serif; font-size:8pt }
 .msg { float:left }
 .msg { padding:0.25em 1ex 0.25em 1ex }
 .msg { margin-top:10px; margin-bottom:10px }
 .msg { font-weight:bold }
 .msg { max-width:60em; word-wrap: break-word; white-space: pre-wrap }
 .msgT { padding:0x; spacing:0x }
 .msgEvent { background-color:#fff8b4; color:#000000 }
 .msgControl { background-color:#bbbbbb; color:#000000 }
 .mrange { background-color:#dfddf3 }
 .mrange { border-bottom:1px solid #6F9DBE }
 .PathIndex { font-weight: bold; padding:0px 5px; margin-right:5px; }
 .PathIndex { -webkit-border-radius:8px }
 .PathIndexEvent { background-color:#bfba87 }
 .PathIndexControl { background-color:#8c8c8c }
 .PathNav a { text-decoration:none; font-size: larger }
 .CodeInsertionHint { font-weight: bold; background-color: #10dd10 }
 .CodeRemovalHint { background-color:#de1010 }
 .CodeRemovalHint { border-bottom:1px solid #6F9DBE }
 table.simpletable {
   padding: 5px;
   font-size:12pt;
   margin:20px;
   border-collapse: collapse; border-spacing: 0px;
 }
 td.rowname {
   text-align:right; font-weight:bold; color:#444444;
   padding-right:2ex; }
</style>
</head>
<body>
<!-- BUGDESC Branch condition evaluates to a garbage value -->

<!-- BUGTYPE Branch condition evaluates to a garbage value -->

<!-- BUGCATEGORY Logic error -->

<!-- BUGFILE /dev/shm/seabios/src/hw/usb-msc.c -->

<!-- FILENAME usb-msc.c -->

<!-- FUNCTIONNAME usb_process_op -->

<!-- ISSUEHASHCONTENTOFLINEINCONTEXT 10e34b5a1c005ee9811c72ad0ad5cabd -->

<!-- BUGLINE 110 -->

<!-- BUGCOLUMN 9 -->

<!-- BUGPATHLENGTH 11 -->

<!-- BUGMETAEND -->
<!-- REPORTHEADER -->
<h3>Bug Summary</h3>
<table class="simpletable">
<tr><td class="rowname">File:</td><td>src/hw/usb-msc.c</td></tr>
<tr><td class="rowname">Location:</td><td><a href="#EndPath">line 110, column 9</a></td></tr>
<tr><td class="rowname">Description:</td><td>Branch condition evaluates to a garbage value</td></tr>
</table>
<!-- REPORTSUMMARYEXTRA -->
<h3>Annotated Source Code</h3>
<table class="code">
<tr><td class="num" id="LN1">1</td><td class="line"><span class='comment'>// Code for handling USB Mass Storage Controller devices.</span></td></tr>
<tr><td class="num" id="LN2">2</td><td class="line"><span class='comment'>//</span></td></tr>
<tr><td class="num" id="LN3">3</td><td class="line"><span class='comment'>// Copyright (C) 2010  Kevin O'Connor <kevin@koconnor.net></span></td></tr>
<tr><td class="num" id="LN4">4</td><td class="line"><span class='comment'>//</span></td></tr>
<tr><td class="num" id="LN5">5</td><td class="line"><span class='comment'>// This file may be distributed under the terms of the GNU LGPLv3 license.</span></td></tr>
<tr><td class="num" id="LN6">6</td><td class="line"> </td></tr>
<tr><td class="num" id="LN7">7</td><td class="line"><span class='directive'>#include "biosvar.h" // GET_GLOBALFLAT</span></td></tr>
<tr><td class="num" id="LN8">8</td><td class="line"><span class='directive'>#include "block.h" // DTYPE_USB</span></td></tr>
<tr><td class="num" id="LN9">9</td><td class="line"><span class='directive'>#include "blockcmd.h" // cdb_read</span></td></tr>
<tr><td class="num" id="LN10">10</td><td class="line"><span class='directive'>#include "config.h" // CONFIG_USB_MSC</span></td></tr>
<tr><td class="num" id="LN11">11</td><td class="line"><span class='directive'>#include "malloc.h" // free</span></td></tr>
<tr><td class="num" id="LN12">12</td><td class="line"><span class='directive'>#include "output.h" // dprintf</span></td></tr>
<tr><td class="num" id="LN13">13</td><td class="line"><span class='directive'>#include "std/disk.h" // DISK_RET_SUCCESS</span></td></tr>
<tr><td class="num" id="LN14">14</td><td class="line"><span class='directive'>#include "string.h" // memset</span></td></tr>
<tr><td class="num" id="LN15">15</td><td class="line"><span class='directive'>#include "usb.h" // struct usb_s</span></td></tr>
<tr><td class="num" id="LN16">16</td><td class="line"><span class='directive'>#include "usb-msc.h" // usb_msc_setup</span></td></tr>
<tr><td class="num" id="LN17">17</td><td class="line"><span class='directive'>#include "util.h" // bootprio_find_usb</span></td></tr>
<tr><td class="num" id="LN18">18</td><td class="line"> </td></tr>
<tr><td class="num" id="LN19">19</td><td class="line"><span class='keyword'>struct</span> usbdrive_s {</td></tr>
<tr><td class="num" id="LN20">20</td><td class="line">    <span class='keyword'>struct</span> drive_s drive;</td></tr>
<tr><td class="num" id="LN21">21</td><td class="line">    <span class='keyword'>struct</span> usb_pipe *bulkin, *bulkout;</td></tr>
<tr><td class="num" id="LN22">22</td><td class="line">    <span class='keyword'>int</span> lun;</td></tr>
<tr><td class="num" id="LN23">23</td><td class="line">};</td></tr>
<tr><td class="num" id="LN24">24</td><td class="line"> </td></tr>
<tr><td class="num" id="LN25">25</td><td class="line"> </td></tr>
<tr><td class="num" id="LN26">26</td><td class="line"><span class='comment'>/****************************************************************</span></td></tr>
<tr><td class="num" id="LN27">27</td><td class="line"> <span class='comment'>* Bulk-only drive command processing</span></td></tr>
<tr><td class="num" id="LN28">28</td><td class="line"> <span class='comment'>****************************************************************/</span></td></tr>
<tr><td class="num" id="LN29">29</td><td class="line"> </td></tr>
<tr><td class="num" id="LN30">30</td><td class="line"><span class='directive'>#define <span class='macro'>USB_CDB_SIZE<span class='expansion'>12</span></span> 12</span></td></tr>
<tr><td class="num" id="LN31">31</td><td class="line"> </td></tr>
<tr><td class="num" id="LN32">32</td><td class="line"><span class='directive'>#define <span class='macro'>CBW_SIGNATURE<span class='expansion'>0x43425355</span></span> 0x43425355 // USBC</span></td></tr>
<tr><td class="num" id="LN33">33</td><td class="line"> </td></tr>
<tr><td class="num" id="LN34">34</td><td class="line"><span class='keyword'>struct</span> cbw_s {</td></tr>
<tr><td class="num" id="LN35">35</td><td class="line">    u32 dCBWSignature;</td></tr>
<tr><td class="num" id="LN36">36</td><td class="line">    u32 dCBWTag;</td></tr>
<tr><td class="num" id="LN37">37</td><td class="line">    u32 dCBWDataTransferLength;</td></tr>
<tr><td class="num" id="LN38">38</td><td class="line">    u8 bmCBWFlags;</td></tr>
<tr><td class="num" id="LN39">39</td><td class="line">    u8 bCBWLUN;</td></tr>
<tr><td class="num" id="LN40">40</td><td class="line">    u8 bCBWCBLength;</td></tr>
<tr><td class="num" id="LN41">41</td><td class="line">    u8 CBWCB[16];</td></tr>
<tr><td class="num" id="LN42">42</td><td class="line">} <span class='macro'>PACKED<span class='expansion'>__attribute__((packed))</span></span>;</td></tr>
<tr><td class="num" id="LN43">43</td><td class="line"> </td></tr>
<tr><td class="num" id="LN44">44</td><td class="line"><span class='directive'>#define <span class='macro'>CSW_SIGNATURE<span class='expansion'>0x53425355</span></span> 0x53425355 // USBS</span></td></tr>
<tr><td class="num" id="LN45">45</td><td class="line"> </td></tr>
<tr><td class="num" id="LN46">46</td><td class="line"><span class='keyword'>struct</span> csw_s {</td></tr>
<tr><td class="num" id="LN47">47</td><td class="line">    u32 dCSWSignature;</td></tr>
<tr><td class="num" id="LN48">48</td><td class="line">    u32 dCSWTag;</td></tr>
<tr><td class="num" id="LN49">49</td><td class="line">    u32 dCSWDataResidue;</td></tr>
<tr><td class="num" id="LN50">50</td><td class="line">    u8 bCSWStatus;</td></tr>
<tr><td class="num" id="LN51">51</td><td class="line">} <span class='macro'>PACKED<span class='expansion'>__attribute__((packed))</span></span>;</td></tr>
<tr><td class="num" id="LN52">52</td><td class="line"> </td></tr>
<tr><td class="num" id="LN53">53</td><td class="line"><span class='keyword'>static</span> <span class='keyword'>int</span></td></tr>
<tr><td class="num" id="LN54">54</td><td class="line">usb_msc_send(<span class='keyword'>struct</span> usbdrive_s *udrive_gf, <span class='keyword'>int</span> dir, <span class='keyword'>void</span> *buf, u32 bytes)</td></tr>
<tr><td class="num" id="LN55">55</td><td class="line">{</td></tr>
<tr><td class="num" id="LN56">56</td><td class="line">    <span class='keyword'>struct</span> usb_pipe *pipe;</td></tr>
<tr><td class="num" id="LN57">57</td><td class="line">    <span class='keyword'>if</span> (dir == <span class='macro'>USB_DIR_OUT<span class='expansion'>0</span></span>)</td></tr>
<tr><td class="num" id="LN58">58</td><td class="line">        pipe = <span class='macro'>GET_GLOBALFLAT(udrive_gf->bulkout)<span class='expansion'>(*(typeof(&(*(&(udrive_gf->bulkout)))))((void*)&<br>(*(&(udrive_gf->bulkout))) + get_global_offset()))</span></span>;</td></tr>
<tr><td class="num" id="LN59">59</td><td class="line">    <span class='keyword'>else</span></td></tr>
<tr><td class="num" id="LN60">60</td><td class="line">        pipe = <span class='macro'>GET_GLOBALFLAT(udrive_gf->bulkin)<span class='expansion'>(*(typeof(&(*(&(udrive_gf->bulkin)))))((void*)&<br>(*(&(udrive_gf->bulkin))) + get_global_offset()))</span></span>;</td></tr>
<tr><td class="num" id="LN61">61</td><td class="line">    <span class='keyword'>return</span> usb_send_bulk(pipe, dir, buf, bytes);</td></tr>
<tr><td class="num" id="LN62">62</td><td class="line">}</td></tr>
<tr><td class="num" id="LN63">63</td><td class="line"> </td></tr>
<tr><td class="num" id="LN64">64</td><td class="line"><span class='comment'>// Low-level usb command transmit function.</span></td></tr>
<tr><td class="num" id="LN65">65</td><td class="line"><span class='keyword'>int</span></td></tr>
<tr><td class="num" id="LN66">66</td><td class="line">usb_process_op(<span class='keyword'>struct</span> disk_op_s *op)</td></tr>
<tr><td class="num" id="LN67">67</td><td class="line">{</td></tr>
<tr><td class="num" id="LN68">68</td><td class="line">    <span class='keyword'>if</span> (!<span class='macro'>CONFIG_USB_MSC<span class='expansion'>1</span></span>)</td></tr>
<tr><td class="num"></td><td class="line"><div id="Path1" class="msg msgControl" style="margin-left:5ex"><table class="msgT"><tr><td valign="top"><div class="PathIndex PathIndexControl">1</div></td><td>Taking false branch</td><td><div class="PathNav"><a href="#Path2" title="Next event (2)">&#x2192;</a></div></td></tr></table></div></td></tr>
<tr><td class="num" id="LN69">69</td><td class="line">        <span class='keyword'>return</span> 0;</td></tr>
<tr><td class="num" id="LN70">70</td><td class="line"> </td></tr>
<tr><td class="num" id="LN71">71</td><td class="line">    <span class='macro'>dprintf(16, <span class='string_literal'>"usb_cmd_data id=%p write=%d count=%d buf=%p\n"<span class='expansion'>do { if (8 && (16) <= 8) __dprintf(("usb_cmd_data id=%p write=%d count=%d buf=%p\n"<br>) , op->drive_gf, 0, op->count, op->buf_fl ); } while<br> (0)</span></span></span></td></tr>
<tr><td class="num" id="LN72">72</td><td class="line">            <span class='macro'>, op->drive_gf, 0, op->count, op->buf_fl)<span class='expansion'>do { if (8 && (16) <= 8) __dprintf(("usb_cmd_data id=%p write=%d count=%d buf=%p\n"<br>) , op->drive_gf, 0, op->count, op->buf_fl ); } while<br> (0)</span></span>;</td></tr>
<tr><td class="num" id="LN73">73</td><td class="line">    <span class='keyword'>struct</span> usbdrive_s *udrive_gf = <span class='macro'>container_of(<span class='expansion'>({ const typeof( ((struct usbdrive_s *)0)->drive ) *__mptr<br> = (op->drive_gf); (struct usbdrive_s *)( (char *)__mptr -<br> ((size_t) &((struct usbdrive_s *)0)->drive) );})</span></span></td></tr>
<tr><td class="num" id="LN74">74</td><td class="line">        <span class='macro'>op->drive_gf, <span class='keyword'>struct</span> usbdrive_s, drive)<span class='expansion'>({ const typeof( ((struct usbdrive_s *)0)->drive ) *__mptr<br> = (op->drive_gf); (struct usbdrive_s *)( (char *)__mptr -<br> ((size_t) &((struct usbdrive_s *)0)->drive) );})</span></span>;</td></tr>
<tr><td class="num" id="LN75">75</td><td class="line"> </td></tr>
<tr><td class="num" id="LN76">76</td><td class="line">    <span class='comment'>// Setup command block wrapper.</span></td></tr>
<tr><td class="num" id="LN77">77</td><td class="line">    <span class='keyword'>struct</span> cbw_s cbw;</td></tr>
<tr><td class="num" id="LN78">78</td><td class="line">    memset(&cbw, 0, <span class='keyword'>sizeof</span>(cbw));</td></tr>
<tr><td class="num" id="LN79">79</td><td class="line">    <span class='keyword'>int</span> blocksize = scsi_fill_cmd(op, cbw.CBWCB, <span class='macro'>USB_CDB_SIZE<span class='expansion'>12</span></span>);</td></tr>
<tr><td class="num" id="LN80">80</td><td class="line">    <span class='keyword'>if</span> (<span class="mrange">blocksize < 0</span>)</td></tr>
<tr><td class="num"></td><td class="line"><div id="Path2" class="msg msgEvent" style="margin-left:9ex"><table class="msgT"><tr><td valign="top"><div class="PathIndex PathIndexEvent">2</div></td><td><div class="PathNav"><a href="#Path1" title="Previous event (1)">&#x2190;</a></div></td></td><td>Assuming 'blocksize' is >= 0</td><td><div class="PathNav"><a href="#Path3" title="Next event (3)">&#x2192;</a></div></td></tr></table></div></td></tr>
<tr><td class="num"></td><td class="line"><div id="Path3" class="msg msgControl" style="margin-left:5ex"><table class="msgT"><tr><td valign="top"><div class="PathIndex PathIndexControl">3</div></td><td><div class="PathNav"><a href="#Path2" title="Previous event (2)">&#x2190;</a></div></td></td><td>Taking false branch</td><td><div class="PathNav"><a href="#Path4" title="Next event (4)">&#x2192;</a></div></td></tr></table></div></td></tr>
<tr><td class="num" id="LN81">81</td><td class="line">        <span class='keyword'>return</span> default_process_op(op);</td></tr>
<tr><td class="num" id="LN82">82</td><td class="line">    u32 bytes = blocksize * op->count;</td></tr>
<tr><td class="num" id="LN83">83</td><td class="line">    cbw.dCBWSignature = <span class='macro'>CBW_SIGNATURE<span class='expansion'>0x43425355</span></span>;</td></tr>
<tr><td class="num" id="LN84">84</td><td class="line">    cbw.dCBWTag = 999; <span class='comment'>// XXX</span></td></tr>
<tr><td class="num" id="LN85">85</td><td class="line">    cbw.dCBWDataTransferLength = bytes;</td></tr>
<tr><td class="num" id="LN86">86</td><td class="line">    cbw.bmCBWFlags = scsi_is_read(op) ? <span class='macro'>USB_DIR_IN<span class='expansion'>0x80</span></span> : <span class='macro'>USB_DIR_OUT<span class='expansion'>0</span></span>;</td></tr>
<tr><td class="num"></td><td class="line"><div id="Path4" class="msg msgControl" style="margin-left:22ex"><table class="msgT"><tr><td valign="top"><div class="PathIndex PathIndexControl">4</div></td><td><div class="PathNav"><a href="#Path3" title="Previous event (3)">&#x2190;</a></div></td></td><td>'?' condition is false</td><td><div class="PathNav"><a href="#Path5" title="Next event (5)">&#x2192;</a></div></td></tr></table></div></td></tr>
<tr><td class="num" id="LN87">87</td><td class="line">    cbw.bCBWLUN = <span class='macro'>GET_GLOBALFLAT(udrive_gf->lun)<span class='expansion'>(*(typeof(&(*(&(udrive_gf->lun)))))((void*)&(*<br>(&(udrive_gf->lun))) + get_global_offset()))</span></span>;</td></tr>
<tr><td class="num" id="LN88">88</td><td class="line">    cbw.bCBWCBLength = <span class='macro'>USB_CDB_SIZE<span class='expansion'>12</span></span>;</td></tr>
<tr><td class="num" id="LN89">89</td><td class="line"> </td></tr>
<tr><td class="num" id="LN90">90</td><td class="line">    <span class='comment'>// Transfer cbw to device.</span></td></tr>
<tr><td class="num" id="LN91">91</td><td class="line">    <span class='keyword'>int</span> ret = usb_msc_send(udrive_gf, <span class='macro'>USB_DIR_OUT<span class='expansion'>0</span></span></td></tr>
<tr><td class="num" id="LN92">92</td><td class="line">                           , <span class='macro'>MAKE_FLATPTR(GET_SEG(SS), &cbw)<span class='expansion'>((void*)(((u32)(0)<<4)+(u32)(&cbw)))</span></span>, <span class='keyword'>sizeof</span>(cbw));</td></tr>
<tr><td class="num" id="LN93">93</td><td class="line">    <span class='keyword'>if</span> (<span class="mrange">ret</span>)</td></tr>
<tr><td class="num"></td><td class="line"><div id="Path5" class="msg msgEvent" style="margin-left:9ex"><table class="msgT"><tr><td valign="top"><div class="PathIndex PathIndexEvent">5</div></td><td><div class="PathNav"><a href="#Path4" title="Previous event (4)">&#x2190;</a></div></td></td><td>Assuming 'ret' is 0</td><td><div class="PathNav"><a href="#Path6" title="Next event (6)">&#x2192;</a></div></td></tr></table></div></td></tr>
<tr><td class="num"></td><td class="line"><div id="Path6" class="msg msgControl" style="margin-left:5ex"><table class="msgT"><tr><td valign="top"><div class="PathIndex PathIndexControl">6</div></td><td><div class="PathNav"><a href="#Path5" title="Previous event (5)">&#x2190;</a></div></td></td><td>Taking false branch</td><td><div class="PathNav"><a href="#Path7" title="Next event (7)">&#x2192;</a></div></td></tr></table></div></td></tr>
<tr><td class="num" id="LN94">94</td><td class="line">        <span class='keyword'>goto</span> fail;</td></tr>
<tr><td class="num" id="LN95">95</td><td class="line"> </td></tr>
<tr><td class="num" id="LN96">96</td><td class="line">    <span class='comment'>// Transfer data to/from device.</span></td></tr>
<tr><td class="num" id="LN97">97</td><td class="line">    <span class='keyword'>if</span> (<span class="mrange">bytes</span>) {</td></tr>
<tr><td class="num"></td><td class="line"><div id="Path7" class="msg msgEvent" style="margin-left:9ex"><table class="msgT"><tr><td valign="top"><div class="PathIndex PathIndexEvent">7</div></td><td><div class="PathNav"><a href="#Path6" title="Previous event (6)">&#x2190;</a></div></td></td><td>Assuming 'bytes' is 0</td><td><div class="PathNav"><a href="#Path8" title="Next event (8)">&#x2192;</a></div></td></tr></table></div></td></tr>
<tr><td class="num"></td><td class="line"><div id="Path8" class="msg msgControl" style="margin-left:5ex"><table class="msgT"><tr><td valign="top"><div class="PathIndex PathIndexControl">8</div></td><td><div class="PathNav"><a href="#Path7" title="Previous event (7)">&#x2190;</a></div></td></td><td>Taking false branch</td><td><div class="PathNav"><a href="#Path9" title="Next event (9)">&#x2192;</a></div></td></tr></table></div></td></tr>
<tr><td class="num" id="LN98">98</td><td class="line">        ret = usb_msc_send(udrive_gf, cbw.bmCBWFlags, op->buf_fl, bytes);</td></tr>
<tr><td class="num" id="LN99">99</td><td class="line">        <span class='keyword'>if</span> (ret)</td></tr>
<tr><td class="num" id="LN100">100</td><td class="line">            <span class='keyword'>goto</span> fail;</td></tr>
<tr><td class="num" id="LN101">101</td><td class="line">    }</td></tr>
<tr><td class="num" id="LN102">102</td><td class="line"> </td></tr>
<tr><td class="num" id="LN103">103</td><td class="line">    <span class='comment'>// Transfer csw info.</span></td></tr>
<tr><td class="num" id="LN104">104</td><td class="line">    <span class='keyword'>struct</span> csw_s csw;</td></tr>
<tr><td class="num" id="LN105">105</td><td class="line">    ret = usb_msc_send(udrive_gf, <span class='macro'>USB_DIR_IN<span class='expansion'>0x80</span></span></td></tr>
<tr><td class="num" id="LN106">106</td><td class="line">                       , <span class='macro'>MAKE_FLATPTR(GET_SEG(SS), &csw)<span class='expansion'>((void*)(((u32)(0)<<4)+(u32)(&csw)))</span></span>, <span class='keyword'>sizeof</span>(csw));</td></tr>
<tr><td class="num" id="LN107">107</td><td class="line">    <span class='keyword'>if</span> (<span class="mrange">ret</span>)</td></tr>
<tr><td class="num"></td><td class="line"><div id="Path9" class="msg msgEvent" style="margin-left:9ex"><table class="msgT"><tr><td valign="top"><div class="PathIndex PathIndexEvent">9</div></td><td><div class="PathNav"><a href="#Path8" title="Previous event (8)">&#x2190;</a></div></td></td><td>Assuming 'ret' is 0</td><td><div class="PathNav"><a href="#Path10" title="Next event (10)">&#x2192;</a></div></td></tr></table></div></td></tr>
<tr><td class="num"></td><td class="line"><div id="Path10" class="msg msgControl" style="margin-left:5ex"><table class="msgT"><tr><td valign="top"><div class="PathIndex PathIndexControl">10</div></td><td><div class="PathNav"><a href="#Path9" title="Previous event (9)">&#x2190;</a></div></td></td><td>Taking false branch</td><td><div class="PathNav"><a href="#EndPath" title="Next event (11)">&#x2192;</a></div></td></tr></table></div></td></tr>
<tr><td class="num" id="LN108">108</td><td class="line">        <span class='keyword'>goto</span> fail;</td></tr>
<tr><td class="num" id="LN109">109</td><td class="line"> </td></tr>
<tr><td class="num" id="LN110">110</td><td class="line">    <span class='keyword'>if</span> (!<span class="mrange">csw.bCSWStatus</span>)</td></tr>
<tr><td class="num"></td><td class="line"><div id="EndPath" class="msg msgEvent" style="margin-left:9ex"><table class="msgT"><tr><td valign="top"><div class="PathIndex PathIndexEvent">11</div></td><td><div class="PathNav"><a href="#Path10" title="Previous event (10)">&#x2190;</a></div></td></td><td>Branch condition evaluates to a garbage value</td></tr></table></div></td></tr>
<tr><td class="num" id="LN111">111</td><td class="line">        <span class='keyword'>return</span> <span class='macro'>DISK_RET_SUCCESS<span class='expansion'>0x00</span></span>;</td></tr>
<tr><td class="num" id="LN112">112</td><td class="line">    <span class='keyword'>if</span> (csw.bCSWStatus == 2)</td></tr>
<tr><td class="num" id="LN113">113</td><td class="line">        <span class='keyword'>goto</span> fail;</td></tr>
<tr><td class="num" id="LN114">114</td><td class="line"> </td></tr>
<tr><td class="num" id="LN115">115</td><td class="line">    <span class='keyword'>if</span> (blocksize)</td></tr>
<tr><td class="num" id="LN116">116</td><td class="line">        op->count -= csw.dCSWDataResidue / blocksize;</td></tr>
<tr><td class="num" id="LN117">117</td><td class="line">    <span class='keyword'>return</span> <span class='macro'>DISK_RET_EBADTRACK<span class='expansion'>0x0c</span></span>;</td></tr>
<tr><td class="num" id="LN118">118</td><td class="line"> </td></tr>
<tr><td class="num" id="LN119">119</td><td class="line">fail:</td></tr>
<tr><td class="num" id="LN120">120</td><td class="line">    <span class='comment'>// XXX - reset connection</span></td></tr>
<tr><td class="num" id="LN121">121</td><td class="line">    <span class='macro'>dprintf(1, <span class='string_literal'>"USB transmission failed\n"</span>)<span class='expansion'>do { if (8 && (1) <= 8) __dprintf(("USB transmission failed\n"<br>) ); } while (0)</span></span>;</td></tr>
<tr><td class="num" id="LN122">122</td><td class="line">    <span class='keyword'>return</span> <span class='macro'>DISK_RET_EBADTRACK<span class='expansion'>0x0c</span></span>;</td></tr>
<tr><td class="num" id="LN123">123</td><td class="line">}</td></tr>
<tr><td class="num" id="LN124">124</td><td class="line"> </td></tr>
<tr><td class="num" id="LN125">125</td><td class="line"><span class='keyword'>static</span> <span class='keyword'>int</span></td></tr>
<tr><td class="num" id="LN126">126</td><td class="line">usb_msc_maxlun(<span class='keyword'>struct</span> usb_pipe *pipe)</td></tr>
<tr><td class="num" id="LN127">127</td><td class="line">{</td></tr>
<tr><td class="num" id="LN128">128</td><td class="line">    <span class='keyword'>struct</span> usb_ctrlrequest req;</td></tr>
<tr><td class="num" id="LN129">129</td><td class="line">    req.bRequestType = <span class='macro'>USB_DIR_IN<span class='expansion'>0x80</span></span> | <span class='macro'>USB_TYPE_CLASS<span class='expansion'>(0x01 << 5)</span></span> | <span class='macro'>USB_RECIP_INTERFACE<span class='expansion'>0x01</span></span>;</td></tr>
<tr><td class="num" id="LN130">130</td><td class="line">    req.bRequest = 0xfe;</td></tr>
<tr><td class="num" id="LN131">131</td><td class="line">    req.wValue = 0;</td></tr>
<tr><td class="num" id="LN132">132</td><td class="line">    req.wIndex = 0;</td></tr>
<tr><td class="num" id="LN133">133</td><td class="line">    req.wLength = 1;</td></tr>
<tr><td class="num" id="LN134">134</td><td class="line">    <span class='keyword'>unsigned</span> <span class='keyword'>char</span> maxlun;</td></tr>
<tr><td class="num" id="LN135">135</td><td class="line">    <span class='keyword'>int</span> ret = usb_send_default_control(pipe, &req, &maxlun);</td></tr>
<tr><td class="num" id="LN136">136</td><td class="line">    <span class='keyword'>if</span> (ret)</td></tr>
<tr><td class="num" id="LN137">137</td><td class="line">        <span class='keyword'>return</span> 0;</td></tr>
<tr><td class="num" id="LN138">138</td><td class="line">    <span class='keyword'>return</span> maxlun;</td></tr>
<tr><td class="num" id="LN139">139</td><td class="line">}</td></tr>
<tr><td class="num" id="LN140">140</td><td class="line"> </td></tr>
<tr><td class="num" id="LN141">141</td><td class="line"><span class='keyword'>static</span> <span class='keyword'>int</span></td></tr>
<tr><td class="num" id="LN142">142</td><td class="line">usb_msc_lun_setup(<span class='keyword'>struct</span> usb_pipe *inpipe, <span class='keyword'>struct</span> usb_pipe *outpipe,</td></tr>
<tr><td class="num" id="LN143">143</td><td class="line">                  <span class='keyword'>struct</span> usbdevice_s *usbdev, <span class='keyword'>int</span> lun)</td></tr>
<tr><td class="num" id="LN144">144</td><td class="line">{</td></tr>
<tr><td class="num" id="LN145">145</td><td class="line">    <span class='comment'>// Allocate drive structure.</span></td></tr>
<tr><td class="num" id="LN146">146</td><td class="line">    <span class='keyword'>struct</span> usbdrive_s *drive = malloc_fseg(<span class='keyword'>sizeof</span>(*drive));</td></tr>
<tr><td class="num" id="LN147">147</td><td class="line">    <span class='keyword'>if</span> (!drive) {</td></tr>
<tr><td class="num" id="LN148">148</td><td class="line">        <span class='macro'>warn_noalloc()<span class='expansion'>__warn_noalloc(148, __func__)</span></span>;</td></tr>
<tr><td class="num" id="LN149">149</td><td class="line">        <span class='keyword'>return</span> -1;</td></tr>
<tr><td class="num" id="LN150">150</td><td class="line">    }</td></tr>
<tr><td class="num" id="LN151">151</td><td class="line">    memset(drive, 0, <span class='keyword'>sizeof</span>(*drive));</td></tr>
<tr><td class="num" id="LN152">152</td><td class="line">    <span class='keyword'>if</span> (usb_32bit_pipe(inpipe))</td></tr>
<tr><td class="num" id="LN153">153</td><td class="line">        drive->drive.type = <span class='macro'>DTYPE_USB_32<span class='expansion'>0x71</span></span>;</td></tr>
<tr><td class="num" id="LN154">154</td><td class="line">    <span class='keyword'>else</span></td></tr>
<tr><td class="num" id="LN155">155</td><td class="line">        drive->drive.type = <span class='macro'>DTYPE_USB<span class='expansion'>0x70</span></span>;</td></tr>
<tr><td class="num" id="LN156">156</td><td class="line">    drive->bulkin = inpipe;</td></tr>
<tr><td class="num" id="LN157">157</td><td class="line">    drive->bulkout = outpipe;</td></tr>
<tr><td class="num" id="LN158">158</td><td class="line">    drive->lun = lun;</td></tr>
<tr><td class="num" id="LN159">159</td><td class="line"> </td></tr>
<tr><td class="num" id="LN160">160</td><td class="line">    <span class='keyword'>int</span> prio = bootprio_find_usb(usbdev, lun);</td></tr>
<tr><td class="num" id="LN161">161</td><td class="line">    <span class='keyword'>int</span> ret = scsi_drive_setup(&drive->drive, <span class='string_literal'>"USB MSC"</span>, prio);</td></tr>
<tr><td class="num" id="LN162">162</td><td class="line">    <span class='keyword'>if</span> (ret) {</td></tr>
<tr><td class="num" id="LN163">163</td><td class="line">        <span class='macro'>dprintf(1, <span class='string_literal'>"Unable to configure USB MSC drive.\n"</span>)<span class='expansion'>do { if (8 && (1) <= 8) __dprintf(("Unable to configure USB MSC drive.\n"<br>) ); } while (0)</span></span>;</td></tr>
<tr><td class="num" id="LN164">164</td><td class="line">        free(drive);</td></tr>
<tr><td class="num" id="LN165">165</td><td class="line">        <span class='keyword'>return</span> -1;</td></tr>
<tr><td class="num" id="LN166">166</td><td class="line">    }</td></tr>
<tr><td class="num" id="LN167">167</td><td class="line">    <span class='keyword'>return</span> 0;</td></tr>
<tr><td class="num" id="LN168">168</td><td class="line">}</td></tr>
<tr><td class="num" id="LN169">169</td><td class="line"> </td></tr>
<tr><td class="num" id="LN170">170</td><td class="line"><span class='comment'>/****************************************************************</span></td></tr>
<tr><td class="num" id="LN171">171</td><td class="line"> <span class='comment'>* Setup</span></td></tr>
<tr><td class="num" id="LN172">172</td><td class="line"> <span class='comment'>****************************************************************/</span></td></tr>
<tr><td class="num" id="LN173">173</td><td class="line"> </td></tr>
<tr><td class="num" id="LN174">174</td><td class="line"><span class='comment'>// Configure a usb msc device.</span></td></tr>
<tr><td class="num" id="LN175">175</td><td class="line"><span class='keyword'>int</span></td></tr>
<tr><td class="num" id="LN176">176</td><td class="line">usb_msc_setup(<span class='keyword'>struct</span> usbdevice_s *usbdev)</td></tr>
<tr><td class="num" id="LN177">177</td><td class="line">{</td></tr>
<tr><td class="num" id="LN178">178</td><td class="line">    <span class='keyword'>if</span> (!<span class='macro'>CONFIG_USB_MSC<span class='expansion'>1</span></span>)</td></tr>
<tr><td class="num" id="LN179">179</td><td class="line">        <span class='keyword'>return</span> -1;</td></tr>
<tr><td class="num" id="LN180">180</td><td class="line"> </td></tr>
<tr><td class="num" id="LN181">181</td><td class="line">    <span class='comment'>// Verify right kind of device</span></td></tr>
<tr><td class="num" id="LN182">182</td><td class="line">    <span class='keyword'>struct</span> usb_interface_descriptor *iface = usbdev->iface;</td></tr>
<tr><td class="num" id="LN183">183</td><td class="line">    <span class='keyword'>if</span> ((iface->bInterfaceSubClass != <span class='macro'>US_SC_SCSI<span class='expansion'>0x06</span></span> &&</td></tr>
<tr><td class="num" id="LN184">184</td><td class="line">         iface->bInterfaceSubClass != <span class='macro'>US_SC_ATAPI_8070<span class='expansion'>0x05</span></span> &&</td></tr>
<tr><td class="num" id="LN185">185</td><td class="line">         iface->bInterfaceSubClass != <span class='macro'>US_SC_ATAPI_8020<span class='expansion'>0x02</span></span>)</td></tr>
<tr><td class="num" id="LN186">186</td><td class="line">        || iface->bInterfaceProtocol != <span class='macro'>US_PR_BULK<span class='expansion'>0x50</span></span>) {</td></tr>
<tr><td class="num" id="LN187">187</td><td class="line">        <span class='macro'>dprintf(1, <span class='string_literal'>"Unsupported MSC USB device (subclass=%02x proto=%02x)\n"<span class='expansion'>do { if (8 && (1) <= 8) __dprintf(("Unsupported MSC USB device (subclass=%02x proto=%02x)\n"<br>) , iface->bInterfaceSubClass, iface->bInterfaceProtocol<br> ); } while (0)</span></span></span></td></tr>
<tr><td class="num" id="LN188">188</td><td class="line">                <span class='macro'>, iface->bInterfaceSubClass, iface->bInterfaceProtocol)<span class='expansion'>do { if (8 && (1) <= 8) __dprintf(("Unsupported MSC USB device (subclass=%02x proto=%02x)\n"<br>) , iface->bInterfaceSubClass, iface->bInterfaceProtocol<br> ); } while (0)</span></span>;</td></tr>
<tr><td class="num" id="LN189">189</td><td class="line">        <span class='keyword'>return</span> -1;</td></tr>
<tr><td class="num" id="LN190">190</td><td class="line">    }</td></tr>
<tr><td class="num" id="LN191">191</td><td class="line"> </td></tr>
<tr><td class="num" id="LN192">192</td><td class="line">    <span class='comment'>// Find bulk in and bulk out endpoints.</span></td></tr>
<tr><td class="num" id="LN193">193</td><td class="line">    <span class='keyword'>struct</span> usb_pipe *inpipe = <span class='macro'>NULL<span class='expansion'>((void*)0)</span></span>, *outpipe = <span class='macro'>NULL<span class='expansion'>((void*)0)</span></span>;</td></tr>
<tr><td class="num" id="LN194">194</td><td class="line">    <span class='keyword'>struct</span> usb_endpoint_descriptor *indesc = usb_find_desc(</td></tr>
<tr><td class="num" id="LN195">195</td><td class="line">        usbdev, <span class='macro'>USB_ENDPOINT_XFER_BULK<span class='expansion'>2</span></span>, <span class='macro'>USB_DIR_IN<span class='expansion'>0x80</span></span>);</td></tr>
<tr><td class="num" id="LN196">196</td><td class="line">    <span class='keyword'>struct</span> usb_endpoint_descriptor *outdesc = usb_find_desc(</td></tr>
<tr><td class="num" id="LN197">197</td><td class="line">        usbdev, <span class='macro'>USB_ENDPOINT_XFER_BULK<span class='expansion'>2</span></span>, <span class='macro'>USB_DIR_OUT<span class='expansion'>0</span></span>);</td></tr>
<tr><td class="num" id="LN198">198</td><td class="line">    <span class='keyword'>if</span> (!indesc || !outdesc)</td></tr>
<tr><td class="num" id="LN199">199</td><td class="line">        <span class='keyword'>goto</span> fail;</td></tr>
<tr><td class="num" id="LN200">200</td><td class="line">    inpipe = usb_alloc_pipe(usbdev, indesc);</td></tr>
<tr><td class="num" id="LN201">201</td><td class="line">    outpipe = usb_alloc_pipe(usbdev, outdesc);</td></tr>
<tr><td class="num" id="LN202">202</td><td class="line">    <span class='keyword'>if</span> (!inpipe || !outpipe)</td></tr>
<tr><td class="num" id="LN203">203</td><td class="line">        <span class='keyword'>goto</span> fail;</td></tr>
<tr><td class="num" id="LN204">204</td><td class="line"> </td></tr>
<tr><td class="num" id="LN205">205</td><td class="line">    <span class='keyword'>int</span> maxlun = usb_msc_maxlun(usbdev->defpipe);</td></tr>
<tr><td class="num" id="LN206">206</td><td class="line">    <span class='keyword'>int</span> lun, pipesused = 0;</td></tr>
<tr><td class="num" id="LN207">207</td><td class="line">    <span class='keyword'>for</span> (lun = 0; lun < maxlun + 1; lun++) {</td></tr>
<tr><td class="num" id="LN208">208</td><td class="line">        <span class='keyword'>int</span> ret = usb_msc_lun_setup(inpipe, outpipe, usbdev, lun);</td></tr>
<tr><td class="num" id="LN209">209</td><td class="line">        <span class='keyword'>if</span> (!ret)</td></tr>
<tr><td class="num" id="LN210">210</td><td class="line">            pipesused = 1;</td></tr>
<tr><td class="num" id="LN211">211</td><td class="line">    }</td></tr>
<tr><td class="num" id="LN212">212</td><td class="line"> </td></tr>
<tr><td class="num" id="LN213">213</td><td class="line">    <span class='keyword'>if</span> (!pipesused)</td></tr>
<tr><td class="num" id="LN214">214</td><td class="line">        <span class='keyword'>goto</span> fail;</td></tr>
<tr><td class="num" id="LN215">215</td><td class="line"> </td></tr>
<tr><td class="num" id="LN216">216</td><td class="line">    <span class='keyword'>return</span> 0;</td></tr>
<tr><td class="num" id="LN217">217</td><td class="line">fail:</td></tr>
<tr><td class="num" id="LN218">218</td><td class="line">    <span class='macro'>dprintf(1, <span class='string_literal'>"Unable to configure USB MSC device.\n"</span>)<span class='expansion'>do { if (8 && (1) <= 8) __dprintf(("Unable to configure USB MSC device.\n"<br>) ); } while (0)</span></span>;</td></tr>
<tr><td class="num" id="LN219">219</td><td class="line">    usb_free_pipe(usbdev, inpipe);</td></tr>
<tr><td class="num" id="LN220">220</td><td class="line">    usb_free_pipe(usbdev, outpipe);</td></tr>
<tr><td class="num" id="LN221">221</td><td class="line">    <span class='keyword'>return</span> -1;</td></tr>
<tr><td class="num" id="LN222">222</td><td class="line">}</td></tr>
</table></body></html>