⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tffsdrv26.c

📁 H3 M-system NAND flash driver in Linux OS, M-DOC driver
💻 C
📖 第 1 页 / 共 5 页
字号:
    {        /* enable interrupt generation in DiskOnChip */        TffsEnableIRQ (&tffsInfo.sockets[0]);    }    STEP++;  /* 4 */    /* Register our major device # (or accept dynamically allocated     * major #).     */    if ((tmp = register_blkdev(tffs_major, tffs_str)) < 0)    {        PrintkError ("Can't get major %d", tffs_major);        cleanup (STEP);        return -EBUSY;    }    if (tffs_major == 0)  /* we asked for dynamic major #, and we got it */        tffs_major = tmp;    PrintkInfo ("use major device number %d", tffs_major);    STEP++; /* 5 */#ifdef CONFIG_PROC_FS    if ((tffsInfo.pProcDir = proc_mkdir(tffs_str, NULL)) == NULL)        { PrintkWarning ("Can't create /proc/%s", tffs_str); }#endif    STEP++; /* 6 */    /* initialize Open/Close mutex in "available" state */    sema_init (&open_close_mutex, 1);    /* init sockets */    for (iSoc = 0; iSoc < FL_SOCKETS; iSoc++)        init_socket (&tffsInfo.sockets[iSoc]);    STEP++; /* 7 */#ifdef CONFIG_PM    tffs_pm_init ();   /* register with Power Manager */#endif    STEP++; /* 8 */    return 0;}/******************************************************************************* *                                                                             * *                         i n i t _ s o c k e t                               * *                                                                             * *  Initialize socket's I/O thread and all socket's disks.                     * *                                                                             * *  Parameters:                                                                * *        psoc      pointer to socket being initialized                        * *                                                                             * *******************************************************************************/static void /* __init */ init_socket ( SocketInfo * psoc ){    int  iDisk;    if (psoc->fFound == 0)        return;    sema_init (&psoc->threadSemaphore, 0);   /* initialized as "not available" */    /* Tell I/O thread to put up psoc->threadSemaphore when it's up and running */    psoc->io_thread_state = 2;    /* start socket's I/O thread */    kernel_thread (socket_io_thread, (void *)psoc, 0);    /* wait until socket's I/O thread is up and running */    down_interruptible (&psoc->threadSemaphore);    /* socket's I/O thread has been started, and is currently waiting for     * I/O requests to be posted to psoc->waitQueueHead.     */    for (iDisk = 0; iDisk < psoc->wDevices; iDisk++)        init_disk (&psoc->pDevices[iDisk]);}/******************************************************************************* *                                                                             * *                         i n i t _ d i s k                                   * *                                                                             * *  Initialize individual disk.  s).                                           * *                                                                             * *  Parameters:                                                                * *        pdisk     pointer to disk                                            * *                                                                             * *******************************************************************************/static void /* __init */ init_disk ( DeviceInfo * pdisk ){    struct gendisk * gd;    int              max_partitions;    /* nobody has opened this disk yet */    pdisk->in_use = 0;#ifdef TFFS_STATISTIC    memset (&pdisk->stat, 0, sizeof(pdisk->stat));#endif#ifdef CONFIG_PROC_FS    procfs_register (pdisk);#endif    /* allocate request queue for this disk */    spin_lock_init (&pdisk->rq_lock);    pdisk->rq = blk_init_queue (disk_request_queue_handler, &pdisk->rq_lock);    if (pdisk->rq == NULL)    {        PrintkError ("blk_init_queue() failed for disk 0x%x", pdisk->bHandle);        return;    }    else        pdisk->rq->queuedata = pdisk;    /* Maximum number of file system partitions that we allow     * on the disk (this doesn't include "raw" disk).     */    max_partitions = ((1 << DEV2PART_SHIFT) - 1);    /* allocate struct gendisk for this disk */    if ((gd = alloc_disk(max_partitions)) == NULL)    {        /* return previously allocated request queue to the system */        blk_cleanup_queue (pdisk->rq);        pdisk->rq = NULL;        PrintkError ("alloc_disk() failed for disk 0x%x", pdisk->bHandle);        return;    }    else        pdisk->gd = gd;    gd->major        = tffs_major;    gd->first_minor  = (pdisk->diskNo * (max_partitions + 1/*"raw" disk entry*/));     gd->fops         = &tffs_bdev_ops;    gd->queue        = pdisk->rq;    gd->private_data = pdisk;    /* name this disk */    snprintf (gd->disk_name, sizeof(gd->disk_name), "%s%c",                         tffs_str, ('a' + (char)(pdisk->diskNo)));    /* specify disk's capacity in 512-byte sectors */    set_capacity (gd, pdisk->dwSize);    /* Tell kernel about this disk. Before add_disk() returns,     * kernel will attempt to read Master Boot Record and parse     * partition table(s) on this disk; it will post I/O requests     * to pdisk->rq, and call disk_request_queue_handler()     * to handle these request.     */    add_disk (gd);}/******************************************************************************* *                                                                             * *                              c l e a n u p                                  * *                                                                             * *  Free all data structures alocated during driver's startup.                 * *                                                                             * *  Parameters:                                                                * *       STEP            specifies which resources to free                     * *                                                                             * *  Returns: void                                                              * *                                                                             * *******************************************************************************/static void  cleanup ( int STEP ){    int iSoc;    if (STEP >= 8)    { #ifdef CONFIG_PM        tffs_pm_exit ();    /* unregister from Power Manager */#endif    }    if (STEP >= 7)    {         /* For every socket, flush all socket's disks, and sleep until socket's         * I/O thread handled all outstanding I/O requests and exited.         */        for (iSoc = 0; iSoc < FL_SOCKETS; iSoc++)        {            if (tffsInfo.sockets[iSoc].fFound != 0)                release_socket (&tffsInfo.sockets[iSoc]);        }    }    if (STEP >= 6)    {#ifdef CONFIG_PROC_FS        remove_proc_entry (tffs_str, NULL);        tffsInfo.pProcDir = NULL;#endif    }    if (STEP >= 5)    {         unregister_blkdev (tffs_major, tffs_str);    }    if (STEP >= 4)    {        /* disable_irq (tffs_irq); */        /* We should tell DiskOnChip to disable interrupt generation, but         * unfortunately TrueFFS currently doesn't provide API for that.         */    }    if (STEP >= 3)    {        /* For all disks of all DiskOnChip sockets, write Quick Mount         * records to them, abs.unmount them, and shut down TrueFFS.         */        TffsCleanup ();    }    if (STEP >= 2)    {        /* if previously installed, remove DiskOnChip interrupt handler */        if (tffs_irq >= 0)            free_irq (tffs_irq, &tffsInfo.sockets[0]);    }}/******************************************************************************* *                                                                             * *                      r e l e a s e _ s o c k e t                            * *                                                                             * *  Release DiskOnChip socket.                                                 * *                                                                             * *  Parameters:                                                                * *        psoc      pointer to socket being released                           * *                                                                             * *  Returns: void                                                              * *                                                                             * *******************************************************************************/static void /* __exit */ release_socket ( SocketInfo * psoc ){    int iDisk;    if (psoc->fFound == 0)        return;    /* Release all socket's disks; this involves flushing all partitions     * on all these disks.     */    for (iDisk = 0; iDisk < psoc->wDevices; iDisk++)        release_disk (&psoc->pDevices[iDisk]);    if (psoc->io_thread_state == 1)  /* I/O thread is running */    {        /* Tell I/O thread to complete handling of all outstanding I/O requests,         * put up psoc->threadSemaphore, and exit.         */        psoc->io_thread_state = 2;        /* in case socket's I/O thread is currently sleeping, wake it up */        wake_up (&psoc->waitQueueHead);        /* now wait for I/O thread to exit */        down_interruptible (&psoc->threadSemaphore);    }}/******************************************************************************* *                                                                             * *                      r e l e a s e _ d i s k                                * *                                                                             * *  Release disk.                                                              * *                                                                             * *  Parameters:                                                                * *        pdisk      pointer to disk being released                            * *                                                                             * *  Returns: void                                                              * *                                                                             * *******************************************************************************/staticvoid /* __exit */ release_disk (DeviceInfo * pdisk){    if (pdisk->gd != NULL)    {        del_gendisk (pdisk->gd);        pdisk->gd = NULL;    }    if (pdisk->rq != NULL)    {        blk_cleanup_queue (pdisk->rq);        pdisk->rq = NULL;    }#ifdef CONFIG_PROC_FS    procfs_unregister (pdisk);#endif}/******************************************************************************* *                                                                             * *                             d i s k _ o p e n                               * *                                                                             * *  Open disk (i.e. block_device_operations.open()).                           * *                                                                             * *  Parameters:                                                                * *                                                                             * *       inode          inode pointer                                          * *       filp           file pointer                                           * *                                                                             * *  Returns: zero if success, otherwise negative error code                    * *                                                                             * *******************************************************************************/staticint  disk_open ( struct inode * inode, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -