Пишу драйвер для одного PCI устройства, для ядра 2.4.32. Устройство 
представляет собой отладочную плату TI. Драйвер запрашивает у 
устройства передачу данных по DMA. Для этого он записывает в mailbox 
команду, необходимые данные и вызывает прерывание. Далее устройство 
считывает mailbox и выставляет ответное прерывание, что данные 
прочитаны, и начинает передавать данные через DMA. По окончании 
передачи данных выставляется второе прерывание. Из юзерспейса запрос 
данных от устройства происходит через IOCTL. В программе из 
юзерйспейса я создаю нить pthread и в неё дергую ioctl устройства, 
проблема в том что если я корректно завершаю работу приложения и 
дожидаюсь завершения нити все работает хорошо, но стоит мне убить 
приложение некорректно (через kill) или закрыть терминал, то компьютер
 наглухо виснет. Еще проблема в том что драйвер не работает на SMP 
машинах :) Ниже привожу код ioctl
case IOCTL_GETRAW:
        volatile DM64LCPCI_pciRegs *  pciRegs  = (DM64LCPCI_pciRegs *)
        ((Uint32) regVirt + (DM64LCPCI_PCIREG_BASE - 0x01C00000));
        int i,n,CommandCode;
        SC_GT_ELEMENT *sglmb;
        char *data;
        int *r=((int*)ioctl_param);
        
        DECLARE_WAITQUEUE(wait, current);
        CommandCode = RW_CMD_READ_RAW_FRAME;
        
#ifdef _USE_DEBUG        
        printk("Board: got Xfer CMD %i\n",CommandCode);
#endif        
        // Here we lock our spin
        spin_lock(&sl);
        
        if (!expack[CommandCode])
            init_waitqueue_head(wq+CommandCode);
        
        expack[CommandCode]=RW_CARD_CMD(CommandCode);
        expack[0]=RW_CARD_CMD(CommandCode);
        mb->HostRequest.CommandCode=RW_HOST_CMD(CommandCode);
        mb->HostRequest.Info=1;
        mb->CardRequest[CommandCode].CommandCode=NULL_CMD;
        mb->CardRequest[CommandCode].Info=0;
        mb->CardRequest[0].CommandCode=NULL_CMD;
        
        sglmb = mb->Sc_Gt_Element;
        sglmb->Adress = cpu_to_le32(virt_to_bus(pvksdev->raw_buf));
        sglmb->Length = cpu_to_le32(0x100000);
        
#ifdef _USE_DEBUG        
        printk("Board: phys of xferBuf = 0x%x\n", mb->Sc_Gt_Element[0].Adress);
        printk("Board: len of xferBuf = 0x%x\n", mb->Sc_Gt_Element[0].Length);
        printk("Board: set IRQ%i 4 DSP\n", CommandCode);
#endif        
        pciRegs->PCISTATSET = TRIGGER_DSPINT_MASK;
        sti();
        
        for(i=0;i<0x10000;i++)
        {
            if(expack[0]==0x3AEB1C)
            {
#ifdef _USE_DEBUG                
                printk("Board: SGL%i read after %i waiting",CommandCode,i);
#endif                
                break;
            }
        }
        
        if(expack[0]!=0x3AEB1C)
        {
#ifdef _USE_DEBUG                
            printk("Board: cant get SGL%i read!!!",CommandCode);return -2101;
#endif
        }
#ifdef _USE_DEBUG                
        printk("Board: releasing spinlock%i...",CommandCode);
#endif
        cli();
        spin_unlock(&sl);
            
        if(expack[CommandCode]!=0x3AEB1C)
        {
            set_current_state(TASK_INTERRUPTIBLE);
            add_wait_queue(wq+CommandCode, &wait);
            schedule();
            sti();
            if(signal_pending(current))
            {
#ifdef _USE_DEBUG                
                printk("Board: signal%i pending\n",CommandCode);
#endif
                return -2100;
            }
            else
            {
#ifdef _USE_DEBUG                
                printk("Board: signal%i not pending\n",CommandCode);
#endif
            }
            remove_wait_queue(wq+CommandCode, &wait);
        }
        else
        {
#ifdef _USE_DEBUG                
            printk("Board: Xfer%i ALREADY done: no need wait\n",CommandCode);
#endif
        }
            
        n=mb->CardRequest[CommandCode].Info;
#ifdef _USE_DEBUG                
        printk("Board: Receive %d bytes of raw frame\n", n);
#endif        
        
        if (n > 0 && n < 0x100000)
            copy_to_user(r, (const void*)pvksdev->raw_buf, n);
            
        return n;
       
    }
И еще ниже обработчик прерывания от платы:
static void ISR_handler5 (int irq, void * arg, struct pt_regs * flags)
{
    Uint32 status = HAL_CheckPciInterrupt ()  ;
    volatile DM64LCPCI_pciRegs * pciRegs = (DM64LCPCI_pciRegs *)((Uint32)regVirt+ (DM64LCPCI_PCIREG_BASE - 0x01c00000));
    int i,j,k,l,m,n;
    IO_REQUEST*r=(IO_REQUEST*)&mb->HostRequest;
    
    if (status == 1)
    {
#ifdef _USE_DEBUG                
        printk ("Board: Got DSPIRQ\n") ;
#endif
        r = (IO_REQUEST*)&mb->CardRequest;
        for( i = 0; i < 5; i++)
        {
            if((j=r->CommandCode) != NULL_CMD)
            {
                if(expack[i]==j)
                {
                    expack[i]=0x3AEB1C;
                    if(i)
                    {
#ifdef _USE_DEBUG                
                        printk("Board: WAKE ch%i ioQ.\n",i);
#endif                        
                        wake_up_interruptible(wq+i);}
                    else
                    {
#ifdef _USE_DEBUG                
                        printk("Board: SGL ch%i OK.\n",j&0xFF);
#endif                    
                    }
                }
                else
                {
                    r->CommandCode=NULL_CMD;
                }
                r->CommandCode=NULL_CMD;
            }
        r++;
        }
    HAL_PciClearDspInterrupt () ;
    }
    return;
}
Буду признателен за любые советы и замечания.


    
      Ответ на:
      
          комментарий
        от idle 
  
    
      Ответ на:
      
          комментарий
        от cobold 
  

    
      Ответ на:
      
          комментарий
        от anonymous 
  
    
      Ответ на:
      
          комментарий
        от idle 
  
    
      Ответ на:
      
          комментарий
        от anonymous 
  
    
        Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.
      
Похожие темы
- Форум проблема с обработкой прерывания (2006)
- Форум Определение серийного номера HDD (2004)
- Форум Определение серийного номера HDD (2004)
- Форум Определение серийного номера HDD (2004)
- Форум Валиден ли код? (2018)
- Форум Исследование CryEngine 2 SDK 1.4.0 (2012)
- Форум Драйвер чтения и записи (2013)
- Форум Обработчик прерывания драйвера UART не вызывается (2015)
- Форум вызов generic_make_request из обработчика запросов блочного устройства (2019)
- Форум Отключается обработка прерывания в 2.6.Х (2008)