| .. | .. |
|---|
| 48 | 48 | { |
|---|
| 49 | 49 | if (!port_scan_backoff) |
|---|
| 50 | 50 | return 0; |
|---|
| 51 | | - return get_random_int() % port_scan_backoff; |
|---|
| 51 | + return prandom_u32_max(port_scan_backoff); |
|---|
| 52 | 52 | } |
|---|
| 53 | 53 | |
|---|
| 54 | 54 | static void zfcp_fc_port_scan_time(struct zfcp_adapter *adapter) |
|---|
| .. | .. |
|---|
| 145 | 145 | |
|---|
| 146 | 146 | static int zfcp_fc_wka_port_get(struct zfcp_fc_wka_port *wka_port) |
|---|
| 147 | 147 | { |
|---|
| 148 | + int ret = -EIO; |
|---|
| 149 | + |
|---|
| 148 | 150 | if (mutex_lock_interruptible(&wka_port->mutex)) |
|---|
| 149 | 151 | return -ERESTARTSYS; |
|---|
| 150 | 152 | |
|---|
| 151 | 153 | if (wka_port->status == ZFCP_FC_WKA_PORT_OFFLINE || |
|---|
| 152 | 154 | wka_port->status == ZFCP_FC_WKA_PORT_CLOSING) { |
|---|
| 153 | 155 | wka_port->status = ZFCP_FC_WKA_PORT_OPENING; |
|---|
| 154 | | - if (zfcp_fsf_open_wka_port(wka_port)) |
|---|
| 156 | + if (zfcp_fsf_open_wka_port(wka_port)) { |
|---|
| 157 | + /* could not even send request, nothing to wait for */ |
|---|
| 155 | 158 | wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE; |
|---|
| 159 | + goto out; |
|---|
| 160 | + } |
|---|
| 156 | 161 | } |
|---|
| 157 | 162 | |
|---|
| 158 | | - mutex_unlock(&wka_port->mutex); |
|---|
| 159 | | - |
|---|
| 160 | | - wait_event(wka_port->completion_wq, |
|---|
| 163 | + wait_event(wka_port->opened, |
|---|
| 161 | 164 | wka_port->status == ZFCP_FC_WKA_PORT_ONLINE || |
|---|
| 162 | 165 | wka_port->status == ZFCP_FC_WKA_PORT_OFFLINE); |
|---|
| 163 | 166 | |
|---|
| 164 | 167 | if (wka_port->status == ZFCP_FC_WKA_PORT_ONLINE) { |
|---|
| 165 | 168 | atomic_inc(&wka_port->refcount); |
|---|
| 166 | | - return 0; |
|---|
| 169 | + ret = 0; |
|---|
| 170 | + goto out; |
|---|
| 167 | 171 | } |
|---|
| 168 | | - return -EIO; |
|---|
| 172 | +out: |
|---|
| 173 | + mutex_unlock(&wka_port->mutex); |
|---|
| 174 | + return ret; |
|---|
| 169 | 175 | } |
|---|
| 170 | 176 | |
|---|
| 171 | 177 | static void zfcp_fc_wka_port_offline(struct work_struct *work) |
|---|
| .. | .. |
|---|
| 181 | 187 | |
|---|
| 182 | 188 | wka_port->status = ZFCP_FC_WKA_PORT_CLOSING; |
|---|
| 183 | 189 | if (zfcp_fsf_close_wka_port(wka_port)) { |
|---|
| 190 | + /* could not even send request, nothing to wait for */ |
|---|
| 184 | 191 | wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE; |
|---|
| 185 | | - wake_up(&wka_port->completion_wq); |
|---|
| 192 | + goto out; |
|---|
| 186 | 193 | } |
|---|
| 194 | + wait_event(wka_port->closed, |
|---|
| 195 | + wka_port->status == ZFCP_FC_WKA_PORT_OFFLINE); |
|---|
| 187 | 196 | out: |
|---|
| 188 | 197 | mutex_unlock(&wka_port->mutex); |
|---|
| 189 | 198 | } |
|---|
| .. | .. |
|---|
| 193 | 202 | if (atomic_dec_return(&wka_port->refcount) != 0) |
|---|
| 194 | 203 | return; |
|---|
| 195 | 204 | /* wait 10 milliseconds, other reqs might pop in */ |
|---|
| 196 | | - schedule_delayed_work(&wka_port->work, HZ / 100); |
|---|
| 205 | + queue_delayed_work(wka_port->adapter->work_queue, &wka_port->work, |
|---|
| 206 | + msecs_to_jiffies(10)); |
|---|
| 197 | 207 | } |
|---|
| 198 | 208 | |
|---|
| 199 | 209 | static void zfcp_fc_wka_port_init(struct zfcp_fc_wka_port *wka_port, u32 d_id, |
|---|
| 200 | 210 | struct zfcp_adapter *adapter) |
|---|
| 201 | 211 | { |
|---|
| 202 | | - init_waitqueue_head(&wka_port->completion_wq); |
|---|
| 212 | + init_waitqueue_head(&wka_port->opened); |
|---|
| 213 | + init_waitqueue_head(&wka_port->closed); |
|---|
| 203 | 214 | |
|---|
| 204 | 215 | wka_port->adapter = adapter; |
|---|
| 205 | 216 | wka_port->d_id = d_id; |
|---|
| .. | .. |
|---|
| 325 | 336 | |
|---|
| 326 | 337 | /** |
|---|
| 327 | 338 | * zfcp_fc_incoming_els - handle incoming ELS |
|---|
| 328 | | - * @fsf_req - request which contains incoming ELS |
|---|
| 339 | + * @fsf_req: request which contains incoming ELS |
|---|
| 329 | 340 | */ |
|---|
| 330 | 341 | void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req) |
|---|
| 331 | 342 | { |
|---|
| .. | .. |
|---|
| 621 | 632 | put_device(&port->dev); |
|---|
| 622 | 633 | } |
|---|
| 623 | 634 | |
|---|
| 635 | +/** |
|---|
| 636 | + * zfcp_fc_sg_free_table - free memory used by scatterlists |
|---|
| 637 | + * @sg: pointer to scatterlist |
|---|
| 638 | + * @count: number of scatterlist which are to be free'ed |
|---|
| 639 | + * the scatterlist are expected to reference pages always |
|---|
| 640 | + */ |
|---|
| 641 | +static void zfcp_fc_sg_free_table(struct scatterlist *sg, int count) |
|---|
| 642 | +{ |
|---|
| 643 | + int i; |
|---|
| 644 | + |
|---|
| 645 | + for (i = 0; i < count; i++, sg = sg_next(sg)) |
|---|
| 646 | + if (sg) |
|---|
| 647 | + free_page((unsigned long) sg_virt(sg)); |
|---|
| 648 | + else |
|---|
| 649 | + break; |
|---|
| 650 | +} |
|---|
| 651 | + |
|---|
| 652 | +/** |
|---|
| 653 | + * zfcp_fc_sg_setup_table - init scatterlist and allocate, assign buffers |
|---|
| 654 | + * @sg: pointer to struct scatterlist |
|---|
| 655 | + * @count: number of scatterlists which should be assigned with buffers |
|---|
| 656 | + * of size page |
|---|
| 657 | + * |
|---|
| 658 | + * Returns: 0 on success, -ENOMEM otherwise |
|---|
| 659 | + */ |
|---|
| 660 | +static int zfcp_fc_sg_setup_table(struct scatterlist *sg, int count) |
|---|
| 661 | +{ |
|---|
| 662 | + void *addr; |
|---|
| 663 | + int i; |
|---|
| 664 | + |
|---|
| 665 | + sg_init_table(sg, count); |
|---|
| 666 | + for (i = 0; i < count; i++, sg = sg_next(sg)) { |
|---|
| 667 | + addr = (void *) get_zeroed_page(GFP_KERNEL); |
|---|
| 668 | + if (!addr) { |
|---|
| 669 | + zfcp_fc_sg_free_table(sg, i); |
|---|
| 670 | + return -ENOMEM; |
|---|
| 671 | + } |
|---|
| 672 | + sg_set_buf(sg, addr, PAGE_SIZE); |
|---|
| 673 | + } |
|---|
| 674 | + return 0; |
|---|
| 675 | +} |
|---|
| 676 | + |
|---|
| 624 | 677 | static struct zfcp_fc_req *zfcp_fc_alloc_sg_env(int buf_num) |
|---|
| 625 | 678 | { |
|---|
| 626 | 679 | struct zfcp_fc_req *fc_req; |
|---|
| .. | .. |
|---|
| 629 | 682 | if (!fc_req) |
|---|
| 630 | 683 | return NULL; |
|---|
| 631 | 684 | |
|---|
| 632 | | - if (zfcp_sg_setup_table(&fc_req->sg_rsp, buf_num)) { |
|---|
| 685 | + if (zfcp_fc_sg_setup_table(&fc_req->sg_rsp, buf_num)) { |
|---|
| 633 | 686 | kmem_cache_free(zfcp_fc_req_cache, fc_req); |
|---|
| 634 | 687 | return NULL; |
|---|
| 635 | 688 | } |
|---|
| .. | .. |
|---|
| 787 | 840 | break; |
|---|
| 788 | 841 | } |
|---|
| 789 | 842 | } |
|---|
| 790 | | - zfcp_sg_free_table(&fc_req->sg_rsp, buf_num); |
|---|
| 843 | + zfcp_fc_sg_free_table(&fc_req->sg_rsp, buf_num); |
|---|
| 791 | 844 | kmem_cache_free(zfcp_fc_req_cache, fc_req); |
|---|
| 792 | 845 | out: |
|---|
| 793 | 846 | zfcp_fc_wka_port_put(&adapter->gs->ds); |
|---|