static int acm_write_start(struct acm *acm, int wbn) { unsigned long flags; struct acm_wb *wb; int rc; spin_lock_irqsave(&acm->write_lock, flags); if (!acm->dev) { spin_unlock_irqrestore(&acm->write_lock, flags); return -ENODEV; } if (!acm->write_ready) { spin_unlock_irqrestore(&acm->write_lock, flags); return 0; /* A white lie */ } wb = &acm->wb[wbn]; if(acm_wb_is_avail(acm) <= 1) acm->write_ready = 0; dbg("%s susp_count: %d", __FUNCTION__, acm->susp_count); if (acm->susp_count) { acm->old_ready = acm->write_ready; acm->delayed_wb = wb; acm->write_ready = 0; schedule_work(&acm->waker); spin_unlock_irqrestore(&acm->write_lock, flags); return 0; /* A white lie */ } usb_mark_last_busy(acm->dev); if (!acm_wb_is_used(acm, wbn)) { spin_unlock_irqrestore(&acm->write_lock, flags); return 0; } rc = acm_start_wb(acm, wb); spin_unlock_irqrestore(&acm->write_lock, flags); return rc; }
/* * Poke write. */ static int acm_write_start(struct acm *acm) { unsigned long flags; int wbn; struct acm_wb *wb; int rc; spin_lock_irqsave(&acm->write_lock, flags); if (!acm->dev) { spin_unlock_irqrestore(&acm->write_lock, flags); return -ENODEV; } if (!acm->write_ready) { spin_unlock_irqrestore(&acm->write_lock, flags); return 0; /* A white lie */ } wbn = acm->write_current; if (!acm_wb_is_used(acm, wbn)) { spin_unlock_irqrestore(&acm->write_lock, flags); return 0; } wb = &acm->wb[wbn]; acm->write_ready = 0; spin_unlock_irqrestore(&acm->write_lock, flags); acm->writeurb->transfer_buffer = wb->buf; acm->writeurb->transfer_dma = wb->dmah; acm->writeurb->transfer_buffer_length = wb->len; acm->writeurb->dev = acm->dev; if ((rc = usb_submit_urb(acm->writeurb, GFP_ATOMIC)) < 0) { dbg("usb_submit_urb(write bulk) failed: %d", rc); acm_write_done(acm); } return rc; }