summaryrefslogtreecommitdiff
path: root/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/westbridge/astoria/block/cyasblkdev_queue.c')
-rw-r--r--drivers/staging/westbridge/astoria/block/cyasblkdev_queue.c417
1 files changed, 0 insertions, 417 deletions
diff --git a/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.c b/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.c
deleted file mode 100644
index d1996a27515e..000000000000
--- a/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/* cyanblkdev_queue.h - Antioch Linux Block Driver queue source file
-## ===========================
-## Copyright (C) 2010 Cypress Semiconductor
-##
-## This program is free software; you can redistribute it and/or
-## modify it under the terms of the GNU General Public License
-## as published by the Free Software Foundation; either version 2
-## of the License, or (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 51 Franklin Street, Fifth Floor,
-## Boston, MA 02110-1301, USA.
-## ===========================
-*/
-
-/*
- * Request queue handling for Antioch block device driver.
- * Based on the mmc queue handling code by Russell King in the
- * linux 2.6.10 kernel.
- */
-
-/*
- * linux/drivers/mmc/mmc_queue.c
- *
- * Copyright (C) 2003 Russell King, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/module.h>
-#include <linux/blkdev.h>
-
-#include "cyasblkdev_queue.h"
-
-#define CYASBLKDEV_QUEUE_EXIT (1 << 0)
-#define CYASBLKDEV_QUEUE_SUSPENDED (1 << 1)
-#define CY_AS_USE_ASYNC_API
-
-
-
-/* print flags by name */
-const char *rq_flag_bit_names[] = {
- "REQ_RW", /* not set, read. set, write */
- "REQ_FAILFAST", /* no low level driver retries */
- "REQ_SORTED", /* elevator knows about this request */
- "REQ_SOFTBARRIER", /* may not be passed by ioscheduler */
- "REQ_HARDBARRIER", /* may not be passed by drive either */
- "REQ_FUA", /* forced unit access */
- "REQ_NOMERGE", /* don't touch this for merging */
- "REQ_STARTED", /* drive already may have started this one */
- "REQ_DONTPREP", /* don't call prep for this one */
- "REQ_QUEUED", /* uses queueing */
- "REQ_ELVPRIV", /* elevator private data attached */
- "REQ_FAILED", /* set if the request failed */
- "REQ_QUIET", /* don't worry about errors */
- "REQ_PREEMPT", /* set for "ide_preempt" requests */
- "REQ_ORDERED_COLOR",/* is before or after barrier */
- "REQ_RW_SYNC", /* request is sync (O_DIRECT) */
- "REQ_ALLOCED", /* request came from our alloc pool */
- "REQ_RW_META", /* metadata io request */
- "REQ_COPY_USER", /* contains copies of user pages */
- "REQ_NR_BITS", /* stops here */
-};
-
-void verbose_rq_flags(int flags)
-{
- int i;
- uint32_t j;
- j = 1;
- for (i = 0; i < 32; i++) {
- if (flags & j)
- DBGPRN("<1>%s", rq_flag_bit_names[i]);
- j = j << 1;
- }
-}
-
-
-/*
- * Prepare a -BLK_DEV request. Essentially, this means passing the
- * preparation off to the media driver. The media driver will
- * create request to CyAsDev.
- */
-static int cyasblkdev_prep_request(
- struct request_queue *q, struct request *req)
-{
- DBGPRN_FUNC_NAME;
-
- /* we only like normal block requests.*/
- if (req->cmd_type != REQ_TYPE_FS && !(req->cmd_flags & REQ_DISCARD)) {
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message("%s:%x bad request received\n",
- __func__, current->pid);
- #endif
-
- blk_dump_rq_flags(req, "cyasblkdev bad request");
- return BLKPREP_KILL;
- }
-
- req->cmd_flags |= REQ_DONTPREP;
-
- return BLKPREP_OK;
-}
-
-/* queue worker thread */
-static int cyasblkdev_queue_thread(void *d)
-{
- DECLARE_WAITQUEUE(wait, current);
- struct cyasblkdev_queue *bq = d;
- struct request_queue *q = bq->queue;
- u32 qth_pid;
-
- DBGPRN_FUNC_NAME;
-
- /*
- * set iothread to ensure that we aren't put to sleep by
- * the process freezing. we handle suspension ourselves.
- */
- daemonize("cyasblkdev_queue_thread");
-
- /* signal to queue_init() so it could contnue */
- complete(&bq->thread_complete);
-
- down(&bq->thread_sem);
- add_wait_queue(&bq->thread_wq, &wait);
-
- qth_pid = current->pid;
-
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message(
- "%s:%x started, bq:%p, q:%p\n", __func__, qth_pid, bq, q);
- #endif
-
- do {
- struct request *req = NULL;
-
- /* the thread wants to be woken up by signals as well */
- set_current_state(TASK_INTERRUPTIBLE);
-
- spin_lock_irq(q->queue_lock);
-
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message(
- "%s: for bq->queue is null\n", __func__);
- #endif
-
- if (!bq->req) {
- /* chk if queue is plugged */
- if (!blk_queue_plugged(q)) {
- bq->req = req = blk_fetch_request(q);
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message(
- "%s: blk_fetch_request:%x\n",
- __func__, (uint32_t)req);
- #endif
- } else {
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message(
- "%s: queue plugged, "
- "skip blk_fetch()\n", __func__);
- #endif
- }
- }
- spin_unlock_irq(q->queue_lock);
-
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message(
- "%s: checking if request queue is null\n", __func__);
- #endif
-
- if (!req) {
- if (bq->flags & CYASBLKDEV_QUEUE_EXIT) {
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message(
- "%s:got QUEUE_EXIT flag\n", __func__);
- #endif
-
- break;
- }
-
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message(
- "%s: request queue is null, goto sleep, "
- "thread_sem->count=%d\n",
- __func__, bq->thread_sem.count);
- if (spin_is_locked(q->queue_lock)) {
- cy_as_hal_print_message("%s: queue_lock "
- "is locked, need to release\n", __func__);
- spin_unlock(q->queue_lock);
-
- if (spin_is_locked(q->queue_lock))
- cy_as_hal_print_message(
- "%s: unlock did not work\n",
- __func__);
- } else {
- cy_as_hal_print_message(
- "%s: checked lock, is not locked\n",
- __func__);
- }
- #endif
-
- up(&bq->thread_sem);
-
- /* yields to the next rdytorun proc,
- * then goes back to sleep*/
- schedule();
- down(&bq->thread_sem);
-
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message(
- "%s: wake_up,continue\n",
- __func__);
- #endif
- continue;
- }
-
- /* new req received, issue it to the driver */
- set_current_state(TASK_RUNNING);
-
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message(
- "%s: issued a RQ:%x\n",
- __func__, (uint32_t)req);
- #endif
-
- bq->issue_fn(bq, req);
-
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message(
- "%s: bq->issue_fn() returned\n",
- __func__);
- #endif
-
-
- } while (1);
-
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&bq->thread_wq, &wait);
- up(&bq->thread_sem);
-
- complete_and_exit(&bq->thread_complete, 0);
-
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message("%s: is finished\n", __func__);
- #endif
-
- return 0;
-}
-
-/*
- * Generic request handler. it is called for any queue on a
- * particular host. When the host is not busy, we look for a request
- * on any queue on this host, and attempt to issue it. This may
- * not be the queue we were asked to process.
- */
-static void cyasblkdev_request(struct request_queue *q)
-{
- struct cyasblkdev_queue *bq = q->queuedata;
- DBGPRN_FUNC_NAME;
-
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message(
- "%s new request on cyasblkdev_queue_t bq:=%x\n",
- __func__, (uint32_t)bq);
- #endif
-
- if (!bq->req) {
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message("%s wake_up(&bq->thread_wq)\n",
- __func__);
- #endif
-
- /* wake up cyasblkdev_queue worker thread*/
- wake_up(&bq->thread_wq);
- } else {
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message("%s: don't wake Q_thr, bq->req:%x\n",
- __func__, (uint32_t)bq->req);
- #endif
- }
-}
-
-/*
- * cyasblkdev_init_queue - initialise a queue structure.
- * @bq: cyasblkdev queue
- * @dev: CyAsDeviceHandle to attach this queue
- * @lock: queue lock
- *
- * Initialise a cyasblkdev_request queue.
- */
-
-/* MAX NUMBER OF SECTORS PER REQUEST **/
-#define Q_MAX_SECTORS 128
-
-/* MAX NUMBER OF PHYS SEGMENTS (entries in the SG list)*/
-#define Q_MAX_SGS 16
-
-int cyasblkdev_init_queue(struct cyasblkdev_queue *bq, spinlock_t *lock)
-{
- int ret;
-
- DBGPRN_FUNC_NAME;
-
- /* 1st param is a function that wakes up the queue thread */
- bq->queue = blk_init_queue(cyasblkdev_request, lock);
- if (!bq->queue)
- return -ENOMEM;
-
- blk_queue_prep_rq(bq->queue, cyasblkdev_prep_request);
-
- blk_queue_bounce_limit(bq->queue, BLK_BOUNCE_ANY);
- blk_queue_max_hw_sectors(bq->queue, Q_MAX_SECTORS);
-
- /* As of now, we have the HAL/driver support to
- * merge scattered segments and handle them simultaneously.
- * so, setting the max_phys_segments to 8. */
- /*blk_queue_max_phys_segments(bq->queue, Q_MAX_SGS);
- blk_queue_max_hw_segments(bq->queue, Q_MAX_SGS);*/
- blk_queue_max_segments(bq->queue, Q_MAX_SGS);
-
- /* should be < then HAL can handle */
- blk_queue_max_segment_size(bq->queue, 512*Q_MAX_SECTORS);
-
- bq->queue->queuedata = bq;
- bq->req = NULL;
-
- init_completion(&bq->thread_complete);
- init_waitqueue_head(&bq->thread_wq);
- sema_init(&bq->thread_sem, 1);
-
- ret = kernel_thread(cyasblkdev_queue_thread, bq, CLONE_KERNEL);
- if (ret >= 0) {
- /* wait until the thread is spawned */
- wait_for_completion(&bq->thread_complete);
-
- /* reinitialize the completion */
- init_completion(&bq->thread_complete);
- ret = 0;
- goto out;
- }
-
-out:
- return ret;
-}
-EXPORT_SYMBOL(cyasblkdev_init_queue);
-
-/*called from blk_put() */
-void cyasblkdev_cleanup_queue(struct cyasblkdev_queue *bq)
-{
- DBGPRN_FUNC_NAME;
-
- bq->flags |= CYASBLKDEV_QUEUE_EXIT;
- wake_up(&bq->thread_wq);
- wait_for_completion(&bq->thread_complete);
-
- blk_cleanup_queue(bq->queue);
-}
-EXPORT_SYMBOL(cyasblkdev_cleanup_queue);
-
-
-/**
- * cyasblkdev_queue_suspend - suspend a CyAsBlkDev request queue
- * @bq: CyAsBlkDev queue to suspend
- *
- * Stop the block request queue, and wait for our thread to
- * complete any outstanding requests. This ensures that we
- * won't suspend while a request is being processed.
- */
-void cyasblkdev_queue_suspend(struct cyasblkdev_queue *bq)
-{
- struct request_queue *q = bq->queue;
- unsigned long flags;
-
- DBGPRN_FUNC_NAME;
-
- if (!(bq->flags & CYASBLKDEV_QUEUE_SUSPENDED)) {
- bq->flags |= CYASBLKDEV_QUEUE_SUSPENDED;
-
- spin_lock_irqsave(q->queue_lock, flags);
- blk_stop_queue(q);
- spin_unlock_irqrestore(q->queue_lock, flags);
-
- down(&bq->thread_sem);
- }
-}
-EXPORT_SYMBOL(cyasblkdev_queue_suspend);
-
-/*cyasblkdev_queue_resume - resume a previously suspended
- * CyAsBlkDev request queue @bq: CyAsBlkDev queue to resume */
-void cyasblkdev_queue_resume(struct cyasblkdev_queue *bq)
-{
- struct request_queue *q = bq->queue;
- unsigned long flags;
-
- DBGPRN_FUNC_NAME;
-
- if (bq->flags & CYASBLKDEV_QUEUE_SUSPENDED) {
- bq->flags &= ~CYASBLKDEV_QUEUE_SUSPENDED;
-
- up(&bq->thread_sem);
-
- spin_lock_irqsave(q->queue_lock, flags);
- blk_start_queue(q);
- spin_unlock_irqrestore(q->queue_lock, flags);
- }
-}
-EXPORT_SYMBOL(cyasblkdev_queue_resume);
-
-/*[]*/