.. | .. |
---|
75 | 75 | else |
---|
76 | 76 | sc->cmd.cmd2.rptr = sc->dmarptr; |
---|
77 | 77 | |
---|
78 | | - sc->wait_time = 1000; |
---|
79 | | - sc->timeout = jiffies + sc->wait_time; |
---|
| 78 | + sc->expiry_time = jiffies + msecs_to_jiffies(LIO_SC_MAX_TMO_MS); |
---|
80 | 79 | |
---|
81 | 80 | return sc; |
---|
82 | 81 | } |
---|
.. | .. |
---|
92 | 91 | ndata->reqtype); |
---|
93 | 92 | } |
---|
94 | 93 | |
---|
95 | | -static void octnet_link_ctrl_callback(struct octeon_device *oct, |
---|
96 | | - u32 status, |
---|
97 | | - void *sc_ptr) |
---|
98 | | -{ |
---|
99 | | - struct octeon_soft_command *sc = (struct octeon_soft_command *)sc_ptr; |
---|
100 | | - struct octnic_ctrl_pkt *nctrl; |
---|
101 | | - |
---|
102 | | - nctrl = (struct octnic_ctrl_pkt *)sc->ctxptr; |
---|
103 | | - |
---|
104 | | - /* Call the callback function if status is zero (meaning OK) or status |
---|
105 | | - * contains a firmware status code bigger than zero (meaning the |
---|
106 | | - * firmware is reporting an error). |
---|
107 | | - * If no response was expected, status is OK if the command was posted |
---|
108 | | - * successfully. |
---|
109 | | - */ |
---|
110 | | - if ((!status || status > FIRMWARE_STATUS_CODE(0)) && nctrl->cb_fn) { |
---|
111 | | - nctrl->status = status; |
---|
112 | | - nctrl->cb_fn(nctrl); |
---|
113 | | - } |
---|
114 | | - |
---|
115 | | - octeon_free_soft_command(oct, sc); |
---|
116 | | -} |
---|
117 | | - |
---|
118 | 94 | static inline struct octeon_soft_command |
---|
119 | 95 | *octnic_alloc_ctrl_pkt_sc(struct octeon_device *oct, |
---|
120 | 96 | struct octnic_ctrl_pkt *nctrl) |
---|
.. | .. |
---|
127 | 103 | uddsize = (u32)(nctrl->ncmd.s.more * 8); |
---|
128 | 104 | |
---|
129 | 105 | datasize = OCTNET_CMD_SIZE + uddsize; |
---|
130 | | - rdatasize = (nctrl->wait_time) ? 16 : 0; |
---|
| 106 | + rdatasize = 16; |
---|
131 | 107 | |
---|
132 | 108 | sc = (struct octeon_soft_command *) |
---|
133 | | - octeon_alloc_soft_command(oct, datasize, rdatasize, |
---|
134 | | - sizeof(struct octnic_ctrl_pkt)); |
---|
| 109 | + octeon_alloc_soft_command(oct, datasize, rdatasize, 0); |
---|
135 | 110 | |
---|
136 | 111 | if (!sc) |
---|
137 | 112 | return NULL; |
---|
138 | | - |
---|
139 | | - memcpy(sc->ctxptr, nctrl, sizeof(struct octnic_ctrl_pkt)); |
---|
140 | 113 | |
---|
141 | 114 | data = (u8 *)sc->virtdptr; |
---|
142 | 115 | |
---|
.. | .. |
---|
154 | 127 | octeon_prepare_soft_command(oct, sc, OPCODE_NIC, OPCODE_NIC_CMD, |
---|
155 | 128 | 0, 0, 0); |
---|
156 | 129 | |
---|
157 | | - sc->callback = octnet_link_ctrl_callback; |
---|
158 | | - sc->callback_arg = sc; |
---|
159 | | - sc->wait_time = nctrl->wait_time; |
---|
| 130 | + init_completion(&sc->complete); |
---|
| 131 | + sc->sc_status = OCTEON_REQUEST_PENDING; |
---|
160 | 132 | |
---|
161 | 133 | return sc; |
---|
162 | 134 | } |
---|
.. | .. |
---|
199 | 171 | } |
---|
200 | 172 | |
---|
201 | 173 | spin_unlock_bh(&oct->cmd_resp_wqlock); |
---|
| 174 | + |
---|
| 175 | + if (nctrl->ncmd.s.cmdgroup == 0) { |
---|
| 176 | + switch (nctrl->ncmd.s.cmd) { |
---|
| 177 | + /* caller holds lock, can not sleep */ |
---|
| 178 | + case OCTNET_CMD_CHANGE_DEVFLAGS: |
---|
| 179 | + case OCTNET_CMD_SET_MULTI_LIST: |
---|
| 180 | + case OCTNET_CMD_SET_UC_LIST: |
---|
| 181 | + WRITE_ONCE(sc->caller_is_done, true); |
---|
| 182 | + return retval; |
---|
| 183 | + } |
---|
| 184 | + } |
---|
| 185 | + |
---|
| 186 | + retval = wait_for_sc_completion_timeout(oct, sc, 0); |
---|
| 187 | + if (retval) |
---|
| 188 | + return (retval); |
---|
| 189 | + |
---|
| 190 | + nctrl->sc_status = sc->sc_status; |
---|
| 191 | + retval = nctrl->sc_status; |
---|
| 192 | + if (nctrl->cb_fn) |
---|
| 193 | + nctrl->cb_fn(nctrl); |
---|
| 194 | + |
---|
| 195 | + WRITE_ONCE(sc->caller_is_done, true); |
---|
| 196 | + |
---|
202 | 197 | return retval; |
---|
203 | 198 | } |
---|