static void p9_xosclient_rerror(struct p9_req_t *req) { struct p9_fcall *rcall; u16 tag; struct p9_xos_device *dev = (struct p9_xos_device *)req->aux; struct p9_xos_endpoint *ep = &dev->driver->ep[RD_EP]; unsigned long flags; if (p9_parse_header(req->tc, &req->tc->size, &req->tc->id, &tag, 1)) warning("Failed to decode header !"); kfree(req->tc); spin_lock_irqsave(&dev->driver->ep_lock, flags); p9_xos_deque_push(ep->rqueue, a2n(req->tc->sdata - 8, ep), ep); nb_free_packets++; spin_unlock_irqrestore(&dev->driver->ep_lock, flags); rcall = kmalloc(sizeof(struct p9_fcall) + 32, GFP_KERNEL); p9pdu_reset(rcall); rcall->sdata = (u8 *) (rcall + sizeof(struct p9_fcall)); p9pdu_writef(rcall, 0, "dbwT", 0, P9_RERROR, tag, "9P destination service closed"); p9pdu_finalize(rcall); req->rc = rcall; req->tc = NULL; spin_lock(&dev->lock); dev->ack_count += 1; spin_unlock(&dev->lock); p9_xos_add_write_request(req, 0); }
static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag) { unsigned long flags; int row, col; struct p9_req_t *req; /* This looks up the original request by tag so we know which * buffer to read the data into */ tag++; if (tag >= c->max_tag) { spin_lock_irqsave(&c->lock, flags); /* check again since original check was outside of lock */ while (tag >= c->max_tag) { row = (tag / P9_ROW_MAXTAG); c->reqs[row] = kcalloc(P9_ROW_MAXTAG, sizeof(struct p9_req_t), GFP_ATOMIC); if (!c->reqs[row]) { printk(KERN_ERR "Couldn't grow tag array\n"); return ERR_PTR(-ENOMEM); } for (col = 0; col < P9_ROW_MAXTAG; col++) { c->reqs[row][col].status = REQ_STATUS_IDLE; c->reqs[row][col].tc = NULL; } c->max_tag += P9_ROW_MAXTAG; } spin_unlock_irqrestore(&c->lock, flags); } row = tag / P9_ROW_MAXTAG; col = tag % P9_ROW_MAXTAG; req = &c->reqs[row][col]; if (!req->tc) { req->wq = kmalloc(sizeof(wait_queue_head_t), GFP_KERNEL); if (!req->wq) { printk(KERN_ERR "Couldn't grow tag array\n"); return ERR_PTR(-ENOMEM); } init_waitqueue_head(req->wq); req->tc = kmalloc(sizeof(struct p9_fcall)+c->msize, GFP_KERNEL); req->rc = kmalloc(sizeof(struct p9_fcall)+c->msize, GFP_KERNEL); if ((!req->tc) || (!req->rc)) { printk(KERN_ERR "Couldn't grow tag array\n"); kfree(req->tc); kfree(req->rc); return ERR_PTR(-ENOMEM); } req->tc->sdata = (char *) req->tc + sizeof(struct p9_fcall); req->tc->capacity = c->msize; req->rc->sdata = (char *) req->rc + sizeof(struct p9_fcall); req->rc->capacity = c->msize; } p9pdu_reset(req->tc); p9pdu_reset(req->rc); req->flush_tag = 0; req->tc->tag = tag-1; req->status = REQ_STATUS_ALLOC; return &c->reqs[row][col]; }