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

📄 qla1280.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
DRIVER_UNLOCK    DEBUG(printk("RESET returning %d\n", result));     COMTRACE('r')    LEAVE("qla1280_reset");    return( result );}/************************************************************************** * qla1200_biosparam *   Return the disk geometry for the given SCSI device. **************************************************************************/intqla1280_biosparam(Disk *disk, kdev_t dev, int geom[]){    int heads, sectors, cylinders;            heads = 64;    sectors = 32;    cylinders = disk->capacity / (heads * sectors);    if (cylinders > 1024)    {        heads = 255;        sectors = 63;        cylinders = disk->capacity / (heads * sectors);        /* if (cylinders > 1023)        cylinders = 1023; */    }    geom[0] = heads;    geom[1] = sectors;    geom[2] = cylinders;    return (0);}/************************************************************************** * qla1280_intr_handler *   Handles the H/W interrupt **************************************************************************/void qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs){#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,95)    unsigned long cpu_flags = 0;#endif    scsi_qla_host_t *ha;    u_short    data;    device_reg_t *reg;    ENTER_INTR("qla1280_intr_handler");    COMTRACE('I')    ha = (scsi_qla_host_t *) dev_id;    if(!ha)    {        printk(KERN_INFO "scsi(): Interrupt with NULL host ptr\n");        COMTRACE('X')        return;    }#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,95)    spin_lock_irqsave(&io_request_lock, cpu_flags);    if(test_and_set_bit(QLA1280_IN_ISR_BIT, &ha->flags))    {        COMTRACE('X')        spin_unlock_irqrestore(&io_request_lock, cpu_flags);        return;    }    ha->isr_count++;    reg = ha->iobase;     /* disable our interrupt. */    WRT_REG_WORD(&reg->ictrl, 0);     data = qla1280_debounce_register(&reg->istatus);    /* Check for pending interrupts. */    if ( !(data & RISC_INT) )    {        /* spurious interrupts can happen legally */        DEBUG(printk("scsi(%d): Spurious interrupt - ignoring\n",(int)ha->host_no));        COMTRACE('X')    }    else      qla1280_isr(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last);    if (ha->done_q_first)        qla1280_done(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last);    clear_bit(QLA1280_IN_ISR_BIT, &ha->flags);    spin_unlock_irqrestore(&io_request_lock, cpu_flags);#else  /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) */    if( test_bit(QLA1280_IN_ISR_BIT, (int *)&ha->flags) )    {          COMTRACE('X')          printk(KERN_INFO "scsi(%d): Already in interrupt - returning \n", (int)ha->host_no);          return;    }    set_bit(QLA1280_IN_ISR_BIT, (int *)&ha->flags);    ha->isr_count++;    reg = ha->iobase;     /* disable our interrupt. */    WRT_REG_WORD(&reg->ictrl, 0);     data = qla1280_debounce_register(&reg->istatus);    /* Check for pending interrupts. */    if ( !(data & RISC_INT) )    {        /* spurious interrupts can happen legally */        DEBUG(printk("scsi(%d): Spurious interrupt - ignoring\n",(int)ha->host_no));        COMTRACE('X')    }    else     qla1280_isr(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last);    /* if no work to do then call the SCSI mid-level right away */    if( ha->done_q_first )        qla1280_done(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last);    /* Schedule the DPC routine */    if (ha->flags.isp_abort_needed || ha->flags.reset_marker ||            ha->done_q_first        )        {            ha->run_qla_bh.data = (void *) ha;            ha->run_qla_bh.routine = qla1280_do_dpc;              COMTRACE('P')             schedule_task(&ha->run_qla_bh);            ha->flags.dpc_sched = TRUE;        }        clear_bit(QLA1280_IN_ISR_BIT, (int *)&ha->flags);#endif     /* enable our interrupt. */        WRT_REG_WORD(&reg->ictrl, ISP_EN_INT + ISP_EN_RISC);        COMTRACE('i')          LEAVE_INTR("qla1280_intr_handler");}/************************************************************************** *   qla1280_do_dpc * * Description: * This routine is a task that is schedule by the interrupt handler  * to perform the background processing for interrupts.  We put it  * on a task queue that is consumed whenever the scheduler runs; that's * so you can do anything (i.e. put the process to sleep etc).  In fact, the  * mid-level tries to sleep when it reaches the driver threshold  * "host->can_queue". This can cause a panic if we were in our interrupt * code . **************************************************************************/static void qla1280_do_dpc(void *p){    scsi_qla_host_t *ha = (scsi_qla_host_t *) p;#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95)    unsigned long cpu_flags = 0;#endif    COMTRACE('p')  #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95)    spin_lock_irqsave(&io_request_lock, cpu_flags);#endif    if (ha->flags.isp_abort_needed)        qla1280_abort_isp(ha);    if (ha->flags.reset_marker)        qla1280_rst_aen(ha);    if (ha->done_q_first)        qla1280_done(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last);    ha->flags.dpc_sched = FALSE;#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95)    spin_unlock_irqrestore(&io_request_lock, cpu_flags);#endif}/************************************************************************** *   qla1280_device_queue_depth * * Description: *   Determines the queue depth for a given device.  There are two ways *   a queue depth can be obtained for a tagged queueing device.  One *   way is the default queue depth which is determined by whether *   If it is defined, then it is used *   as the default queue depth.  Otherwise, we use either 4 or 8 as the *   default queue depth (dependent on the number of hardware SCBs). **************************************************************************/STATIC void qla1280_device_queue_depth(scsi_qla_host_t *p, Scsi_Device *device){    int default_depth = 3;    int bus = device->channel;    int target = device->id;    device->queue_depth = default_depth;    if (device->tagged_supported &&        (p->bus_settings[bus].qtag_enables & (BIT_0 << target)) )    {        device->tagged_queue = 1;        device->current_tag = 0;        device->queue_depth = p->bus_settings[bus].hiwat;         /* device->queue_depth = 20; */        printk(KERN_INFO "scsi(%d:%d:%d:%d): Enabled tagged queuing, queue depth %d.\n",                (int)p->host_no, device->channel, device->id,                device->lun, device->queue_depth);    }    qla12160_get_target_parameters(p, bus, target, device->lun);}/************************************************************************** *   qla1280_select_queue_depth * *   Sets the queue depth for each SCSI device hanging off the input *   host adapter.  We use a queue depth of 2 for devices that do not *   support tagged queueing. **************************************************************************/STATIC voidqla1280_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs){    Scsi_Device *device;    scsi_qla_host_t  *p = (scsi_qla_host_t *) host->hostdata;    ENTER("qla1280_select_queue_depth");    for (device = scsi_devs; device != NULL; device = device->next)    {        if (device->host == host)            qla1280_device_queue_depth(p, device);    }    LEAVE("qla1280_select_queue_depth");}/*--------------------------**** Driver Support Routines  ****--------------------------*/#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)/* * mdelay *      Delay in milliseconds  * * Input: *      milliseconds  = delay  */STATIC inline void mdelay(int milliseconds){    int i;    for(i=0; i<milliseconds; i++)        udelay(1000);}#endif/* * qla1280_done *      Process completed commands. * * Input: *      ha           = adapter block pointer. *      done_q_first = done queue first pointer. *      done_q_last  = done queue last pointer. */STATIC voidqla1280_done(scsi_qla_host_t *ha, srb_t **done_q_first, srb_t **done_q_last){    srb_t           *sp;    scsi_lu_t       *q;    uint32_t        b, t, l;    Scsi_Cmnd  *cmd;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)    unsigned long cpu_flags = 0;#endif    ENTER("qla1280_done");    COMTRACE('D')     DRIVER_LOCK     while (*done_q_first !=  NULL)    {        /* remove command from done list */                sp = *done_q_first;        if (!(*done_q_first = sp->s_next))            *done_q_last = NULL;        else            (*done_q_first)->s_prev = NULL;                cmd = sp->cmd;        b = SCSI_BUS_32(cmd);        t = SCSI_TCN_32(cmd);        l = SCSI_LUN_32(cmd);        q = LU_Q(ha, b, t, l);        /* Decrement outstanding commands on device. */        if (q->q_outcnt)            q->q_outcnt--;        if (q->q_outcnt < ha->bus_settings[b].hiwat)        {            q->q_flag &= ~QLA1280_QBUSY;        }                q->resp_time += jiffies - sp->r_start;                /* Lun bookkeeping information */        q->act_time += jiffies - sp->u_start;        q->io_cnt++;        if( sp->dir & BIT_5 )         q->r_cnt++;        else         q->w_cnt++;        switch ( (CMD_RESULT(cmd)>>16))        {            case DID_RESET:                q->q_flag &= ~QLA1280_QRESET;                /* Issue marker command. */                qla1280_marker(ha, b, t, 0, MK_SYNC_ID);                 break;            case DID_ABORT:                sp->flags &= ~SRB_ABORT_PENDING;                sp->flags |= SRB_ABORTED;                if (sp->flags & SRB_TIMEOUT)                    CMD_RESULT(sp->cmd)= DID_TIME_OUT << 16;                break;            default:                break;        }        /* Call the mid-level driver interrupt handler */        CMD_HANDLE(sp->cmd) = (unsigned char *) 0;        ha->actthreads--;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)        sti();         (*(cmd)->scsi_done)(cmd);        cli(); #else        (*(cmd)->scsi_done)(cmd);#endif        qla1280_next(ha, q, b);    }    DRIVER_UNLOCK     COMTRACE('d')     LEAVE("qla1280_done");}/* * Translates a ISP error to a Linux SCSI error */STATIC int qla1280_return_status( sts_entry_t *sts, Scsi_Cmnd       *cp){    int host_status = DID_ERROR;#if DEBUG_QLA1280_INTR    STATIC char *reason[] =    {        "DID_OK",                "DID_NO_CONNECT",                "DID_BUS_BUSY",                "DID_TIME_OUT",                "DID_BAD_TARGET",                "DID_ABORT",                "DID_PARITY",                "DID_ERROR",                "DID_RESET",                "DID_BAD_INTR"    };#endif /* DEBUG_QLA1280_INTR */    ENTER("qla1280_return_status");#if DEBUG_QLA1280_INTR    /*    DEBUG(printk("qla1280_return_status: compl status = 0x%04x\n", sts->c

⌨️ 快捷键说明

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