Exemple #1
0
static void retry_erase(erase_busy_t *busy, u_int cause)
{
    eraseq_entry_t *erase = busy->erase;
    mtd_request_t req;
    client_t *mtd;
    socket_info_t *s;
    int ret;

    DEBUG(2, "cs: trying erase request 0x%p...\n", busy);
    if (busy->next)
	remove_queue(busy);
    req.Function = MTD_REQ_ERASE | cause;
    req.TransferLength = erase->Size;
    req.DestCardOffset = erase->Offset + erase->Handle->info.CardOffset;
    req.MediaID = erase->Handle->MediaID;
    mtd = erase->Handle->mtd;
    s = SOCKET(mtd);
    mtd->event_callback_args.mtdrequest = &req;
    wacquire(&mtd->mtd_req);
    ret = EVENT(mtd, CS_EVENT_MTD_REQUEST, CS_EVENT_PRI_LOW);
    wrelease(&mtd->mtd_req);
    if (ret == CS_BUSY) {
	DEBUG(2, "  Status = %d, requeueing.\n", req.Status);
	switch (req.Status) {
	case MTD_WAITREQ:
	case MTD_WAITPOWER:
	    insert_queue(&mtd->erase_busy, busy);
	    break;
	case MTD_WAITTIMER:
	case MTD_WAITRDY:
	    if (req.Status == MTD_WAITRDY)
		insert_queue(&s->erase_busy, busy);
	    mod_timer(&busy->timeout, jiffies + req.Timeout*HZ/1000);
	    break;
	}
    } else {
	/* update erase queue status */
	DEBUG(2, "  Ret = %d\n", ret);
	switch (ret) {
	case CS_SUCCESS:
	    erase->State = ERASE_PASSED; break;
	case CS_WRITE_PROTECTED:
	    erase->State = ERASE_MEDIA_WRPROT; break;
	case CS_BAD_OFFSET:
	    erase->State = ERASE_BAD_OFFSET; break;
	case CS_BAD_SIZE:
	    erase->State = ERASE_BAD_SIZE; break;
	case CS_NO_CARD:
	    erase->State = ERASE_BAD_SOCKET; break;
	default:
	    erase->State = ERASE_FAILED; break;
	}
	busy->client->event_callback_args.info = erase;
	EVENT(busy->client, CS_EVENT_ERASE_COMPLETE, CS_EVENT_PRI_LOW);
	kfree(busy);
	/* Resubmit anything waiting for a request to finish */
	wakeup(&mtd->mtd_req);
	retry_erase_list(&mtd->erase_busy, 0);
    }
} /* retry_erase */
Exemple #2
0
static int do_mtd_request(memory_handle_t handle, mtd_request_t *req,
			  caddr_t buf)
{
    int ret, tries;
    client_t *mtd;
    socket_info_t *s;
    
    mtd = handle->mtd;
    if (mtd == NULL)
	return CS_GENERAL_FAILURE;
    s = SOCKET(mtd);
    wacquire(&mtd->mtd_req);
    for (ret = tries = 0; tries < 100; tries++) {
	mtd->event_callback_args.mtdrequest = req;
	mtd->event_callback_args.buffer = buf;
	ret = EVENT(mtd, CS_EVENT_MTD_REQUEST, CS_EVENT_PRI_LOW);
	if (ret != CS_BUSY)
	    break;
	switch (req->Status) {
	case MTD_WAITREQ:
	    /* Not that we should ever need this... */
	    wsleeptimeout(&mtd->mtd_req, HZ);
	    break;
	case MTD_WAITTIMER:
	case MTD_WAITRDY:
	    wsleeptimeout(&mtd->mtd_req, req->Timeout*HZ/1000);
	    req->Function |= MTD_REQ_TIMEOUT;
	    break;
	case MTD_WAITPOWER:
	    wsleep(&mtd->mtd_req);
	    break;
	}
#ifndef __MACOSX__
	if (signal_pending(current))
	    printk(KERN_NOTICE "cs: do_mtd_request interrupted!\n");
#endif
    }
    wrelease(&mtd->mtd_req);
    if (tries == 20) {
	printk(KERN_NOTICE "cs: MTD request timed out!\n");
	ret = CS_GENERAL_FAILURE;
    }
    wakeup(&mtd->mtd_req);
    retry_erase_list(&mtd->erase_busy, 0);
    return ret;
} /* do_mtd_request */