Enscript Output

extractedLnx/linux-2.5.68/drivers/scsi/gdth.c_gdth_ioctl.c

static int gdth_ioctl(struct inode *inode, struct file *filep,
                      unsigned int cmd, unsigned long arg)
{
    gdth_ha_str *ha; 
#if LINUX_VERSION_CODE >= 0x020503
    Scsi_Request *srp;
    Scsi_Cmnd *scp;
    Scsi_Device *sdev;
#elif LINUX_VERSION_CODE >= 0x020322
    Scsi_Cmnd *scp;
    Scsi_Device *sdev;
#else
    Scsi_Cmnd scp;
    Scsi_Device sdev;
#endif
    ulong flags;
    char cmnd[MAX_COMMAND_SIZE];   
    memset(cmnd, 0xff, 12);
    
    TRACE(("gdth_ioctl() cmd 0x%x\n", cmd));
 
    switch (cmd) {
      case GDTIOCTL_CTRCNT:
      { 
        int cnt = gdth_ctr_count;
        put_user(cnt, (int *)arg);
        break;
      }

      case GDTIOCTL_DRVERS:
      { 
        int ver = (GDTH_VERSION<<8) | GDTH_SUBVERSION;
        put_user(ver, (int *)arg);
        break;
      }
      
      case GDTIOCTL_OSVERS:
      { 
        gdth_ioctl_osvers osv; 

        osv.version = (unchar)(LINUX_VERSION_CODE >> 16);
        osv.subversion = (unchar)(LINUX_VERSION_CODE >> 8);
        osv.revision = (ushort)(LINUX_VERSION_CODE & 0xff);
        copy_to_user((char *)arg, &osv, sizeof(gdth_ioctl_osvers));
        break;
      }

      case GDTIOCTL_CTRTYPE:
      { 
        gdth_ioctl_ctrtype ctrt;
        
        if (copy_from_user(&ctrt, (char *)arg, sizeof(gdth_ioctl_ctrtype)) ||
            ctrt.ionode >= gdth_ctr_count)
            return -EFAULT;
        ha = HADATA(gdth_ctr_tab[ctrt.ionode]);
        if (ha->type == GDT_ISA || ha->type == GDT_EISA) {
            ctrt.type = (unchar)((ha->stype>>20) - 0x10);
        } else {
            if (ha->type != GDT_PCIMPR) {
                ctrt.type = (unchar)((ha->stype<<4) + 6);
            } else {
                ctrt.type = 
                    (ha->oem_id == OEM_ID_INTEL ? 0xfd : 0xfe);
                if (ha->stype >= 0x300)
                    ctrt.ext_type = 0x6000 | ha->subdevice_id;
                else 
                    ctrt.ext_type = 0x6000 | ha->stype;
            }
            ctrt.device_id = ha->stype;
            ctrt.sub_device_id = ha->subdevice_id;
        }
        ctrt.info = ha->brd_phys;
        ctrt.oem_id = ha->oem_id;
        if (copy_to_user((char *)arg, &ctrt, sizeof(gdth_ioctl_ctrtype)))
            return -EFAULT;
        break;
      }
        
      case GDTIOCTL_GENERAL:
      {
        gdth_ioctl_general gen;
        char *buf = NULL;
        ulong32 paddr; 
        int hanum;
        
        if (copy_from_user(&gen, (char *)arg, sizeof(gdth_ioctl_general)) ||
            gen.ionode >= gdth_ctr_count)
            return -EFAULT;
        hanum = gen.ionode; 
        ha = HADATA(gdth_ctr_tab[hanum]);
        if (gen.data_len + gen.sense_len != 0) {
            if (!(buf = gdth_ioctl_alloc(hanum, gen.data_len + gen.sense_len, 
                                         FALSE, &paddr)))
                return -EFAULT;
            if (copy_from_user(buf, (char *)arg + sizeof(gdth_ioctl_general),  
                               gen.data_len + gen.sense_len)) {
                gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
                return -EFAULT;
            }

            if (gen.command.OpCode == GDT_IOCTL) {
                gen.command.u.ioctl.p_param = paddr;
            } else if (gen.command.Service == CACHESERVICE) {
                if (ha->cache_feat & SCATTER_GATHER) {
                    gen.command.u.cache.DestAddr = 0xffffffff;
                    gen.command.u.cache.sg_canz = 1;
                    gen.command.u.cache.sg_lst[0].sg_ptr = paddr;
                    gen.command.u.cache.sg_lst[0].sg_len = gen.data_len;
                    gen.command.u.cache.sg_lst[1].sg_len = 0;
                } else {
                    gen.command.u.cache.DestAddr = paddr;
                    gen.command.u.cache.sg_canz = 0;
                }
            } else if (gen.command.Service == SCSIRAWSERVICE) {
                if (ha->raw_feat & SCATTER_GATHER) {
                    gen.command.u.raw.sdata = 0xffffffff;
                    gen.command.u.raw.sg_ranz = 1;
                    gen.command.u.raw.sg_lst[0].sg_ptr = paddr;
                    gen.command.u.raw.sg_lst[0].sg_len = gen.data_len;
                    gen.command.u.raw.sg_lst[1].sg_len = 0;
                } else {
                    gen.command.u.raw.sdata = paddr;
                    gen.command.u.raw.sg_ranz = 0;
                }
                gen.command.u.raw.sense_data = paddr + gen.data_len;

            } else {
                gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
                return -EFAULT;
            }
        }

#if LINUX_VERSION_CODE >= 0x020503
        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
        srp  = scsi_allocate_request(sdev);
        if (!srp)
            return -ENOMEM;
        srp->sr_cmd_len = 12;
        srp->sr_use_sg = 0;
        gdth_do_req(srp, &gen.command, cmnd, gen.timeout);
        gen.status = srp->sr_command->SCp.Status;
        gen.info = srp->sr_command->SCp.Message;
        scsi_release_request(srp);
        scsi_free_host_dev(sdev);
#elif LINUX_VERSION_CODE >= 0x020322
        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
        scp  = scsi_allocate_device(sdev, 1, FALSE);
        if (!scp)
            return -ENOMEM;
        scp->cmd_len = 12;
        scp->use_sg = 0;
        gdth_do_cmd(scp, &gen.command, cmnd, gen.timeout);
        gen.status = scp->SCp.Status;
        gen.info = scp->SCp.Message;
        scsi_release_command(scp);
        scsi_free_host_dev(sdev);
#else
        memset(&sdev,0,sizeof(Scsi_Device));
        memset(&scp, 0,sizeof(Scsi_Cmnd));
        sdev.host = scp.host = gdth_ctr_tab[hanum];
        sdev.id = scp.target = sdev.host->this_id;
        scp.device = &sdev;
        gdth_do_cmd(&scp, &gen.command, cmnd, gen.timeout);
        gen.status = scp.SCp.Status;
        gen.info = scp.SCp.Message;
#endif

        if (copy_to_user((char *)arg + sizeof(gdth_ioctl_general), buf, 
                         gen.data_len + gen.sense_len)) {
            gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
            return -EFAULT; 
        } 
        if (copy_to_user((char *)arg, &gen, 
            sizeof(gdth_ioctl_general) - sizeof(gdth_cmd_str))) {
            gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
            return -EFAULT;
        }
        gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
        break;
      }
 
      case GDTIOCTL_EVENT:
      {
        gdth_ioctl_event evt;
        gdth_ha_str *ha;
        ulong flags;

        if (copy_from_user(&evt, (char *)arg, sizeof(gdth_ioctl_event)) ||
            evt.ionode >= gdth_ctr_count)
            return -EFAULT;
        ha = HADATA(gdth_ctr_tab[evt.ionode]);

        if (evt.erase == 0xff) {
            if (evt.event.event_source == ES_TEST)
                evt.event.event_data.size=sizeof(evt.event.event_data.eu.test); 
            else if (evt.event.event_source == ES_DRIVER)
                evt.event.event_data.size=sizeof(evt.event.event_data.eu.driver); 
            else if (evt.event.event_source == ES_SYNC)
                evt.event.event_data.size=sizeof(evt.event.event_data.eu.sync); 
            else
                evt.event.event_data.size=sizeof(evt.event.event_data.eu.async);
            GDTH_LOCK_HA(ha, flags);
            gdth_store_event(ha, evt.event.event_source, evt.event.event_idx,
                             &evt.event.event_data);
            GDTH_UNLOCK_HA(ha, flags);
        } else if (evt.erase == 0xfe) {
            gdth_clear_events();
        } else if (evt.erase == 0) {
            evt.handle = gdth_read_event(ha, evt.handle, &evt.event);
        } else {
            gdth_readapp_event(ha, evt.erase, &evt.event);
        }     
        if (copy_to_user((char *)arg, &evt, sizeof(gdth_ioctl_event)))
            return -EFAULT;
        break;
      }

      case GDTIOCTL_LOCKDRV:
      {
        gdth_ioctl_lockdrv ldrv;
        unchar i, j;

        if (copy_from_user(&ldrv, (char *)arg, sizeof(gdth_ioctl_lockdrv)) ||
            ldrv.ionode >= gdth_ctr_count)
            return -EFAULT;
        ha = HADATA(gdth_ctr_tab[ldrv.ionode]);
 
        for (i = 0; i < ldrv.drive_cnt && i < MAX_HDRIVES; ++i) {
            j = ldrv.drives[i];
            if (j >= MAX_HDRIVES || !ha->hdr[j].present)
                continue;
            if (ldrv.lock) {
                GDTH_LOCK_HA(ha, flags);
                ha->hdr[j].lock = 1;
                GDTH_UNLOCK_HA(ha, flags);
                gdth_wait_completion(ldrv.ionode, ha->bus_cnt, j); 
                gdth_stop_timeout(ldrv.ionode, ha->bus_cnt, j); 
            } else {
                GDTH_LOCK_HA(ha, flags);
                ha->hdr[j].lock = 0;
                GDTH_UNLOCK_HA(ha, flags);
                gdth_start_timeout(ldrv.ionode, ha->bus_cnt, j); 
                gdth_next(ldrv.ionode); 
            }
        } 
        break;
      }

      case GDTIOCTL_LOCKCHN:
      {
        gdth_ioctl_lockchn lchn;
        unchar i, j;

        if (copy_from_user(&lchn, (char *)arg, sizeof(gdth_ioctl_lockchn)) ||
            lchn.ionode >= gdth_ctr_count)
            return -EFAULT;
        ha = HADATA(gdth_ctr_tab[lchn.ionode]);
        
        i = lchn.channel;
        if (i < ha->bus_cnt) {
            if (lchn.lock) {
                GDTH_LOCK_HA(ha, flags);
                ha->raw[i].lock = 1;
                GDTH_UNLOCK_HA(ha, flags);
                for (j = 0; j < ha->tid_cnt; ++j) {
                    gdth_wait_completion(lchn.ionode, i, j); 
                    gdth_stop_timeout(lchn.ionode, i, j); 
                }
            } else {
                GDTH_LOCK_HA(ha, flags);
                ha->raw[i].lock = 0;
                GDTH_UNLOCK_HA(ha, flags);
                for (j = 0; j < ha->tid_cnt; ++j) {
                    gdth_start_timeout(lchn.ionode, i, j); 
                    gdth_next(lchn.ionode); 
                }
            }
        } 
        break;
      }

      case GDTIOCTL_RESCAN:
      {
        gdth_ioctl_rescan rsc;
        gdth_cmd_str cmd;
        ushort i, status, hdr_cnt;
        ulong32 info;
        int hanum, cyls, hds, secs;
        
        if (copy_from_user(&rsc, (char *)arg, sizeof(gdth_ioctl_rescan)) ||
            rsc.ionode >= gdth_ctr_count)
            return -EFAULT;
        hanum = rsc.ionode;
        ha = HADATA(gdth_ctr_tab[hanum]);

#if LINUX_VERSION_CODE >= 0x020503
        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
        srp  = scsi_allocate_request(sdev);
        if (!srp)
            return -ENOMEM;
        srp->sr_cmd_len = 12;
        srp->sr_use_sg = 0;
#elif LINUX_VERSION_CODE >= 0x020322
        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
        scp  = scsi_allocate_device(sdev, 1, FALSE);
        if (!scp)
            return -ENOMEM;
        scp->cmd_len = 12;
        scp->use_sg = 0;
#else
        memset(&sdev,0,sizeof(Scsi_Device));
        memset(&scp, 0,sizeof(Scsi_Cmnd));
        sdev.host = scp.host = gdth_ctr_tab[hanum];
        sdev.id = scp.target = sdev.host->this_id;
        scp.device = &sdev;
#endif
     
        if (rsc.flag == 0) {
            /* old method: re-init. cache service */
            cmd.Service = CACHESERVICE;
            cmd.OpCode = GDT_INIT;
            cmd.u.cache.DeviceNo = LINUX_OS;
#if LINUX_VERSION_CODE >= 0x020503
            gdth_do_req(srp, &cmd, cmnd, 30);
            status = (ushort)srp->sr_command->SCp.Status;
            info = (ulong32)srp->sr_command->SCp.Message;
#elif LINUX_VERSION_CODE >= 0x020322
            gdth_do_cmd(scp, &cmd, cmnd, 30);
            status = (ushort)scp->SCp.Status;
            info = (ulong32)scp->SCp.Message;
#else
            gdth_do_cmd(&scp, &cmd, cmnd, 30);
            status = (ushort)scp.SCp.Status;
            info = (ulong32)scp.SCp.Message;
#endif
            i = 0;
            hdr_cnt = (status == S_OK ? (ushort)info : 0);
        } else {
            i = rsc.hdr_no;
            hdr_cnt = i + 1;
        }
        for (; i < hdr_cnt && i < MAX_HDRIVES; ++i) {
            cmd.Service = CACHESERVICE;
            cmd.OpCode = GDT_INFO;
            cmd.u.cache.DeviceNo = i;
#if LINUX_VERSION_CODE >= 0x020503
            gdth_do_req(srp, &cmd, cmnd, 30);
            status = (ushort)srp->sr_command->SCp.Status;
            info = (ulong32)srp->sr_command->SCp.Message;
#elif LINUX_VERSION_CODE >= 0x020322
            gdth_do_cmd(scp, &cmd, cmnd, 30);
            status = (ushort)scp->SCp.Status;
            info = (ulong32)scp->SCp.Message;
#else
            gdth_do_cmd(&scp, &cmd, cmnd, 30);
            status = (ushort)scp.SCp.Status;
            info = (ulong32)scp.SCp.Message;
#endif
            GDTH_LOCK_HA(ha, flags);
            rsc.hdr_list[i].bus = ha->virt_bus;
            rsc.hdr_list[i].target = i;
            rsc.hdr_list[i].lun = 0;
            if (status != S_OK) {
                ha->hdr[i].present = FALSE;
            } else {
                ha->hdr[i].present = TRUE;
                ha->hdr[i].size = info;
                /* evaluate mapping */
                ha->hdr[i].size &= ~SECS32;
                gdth_eval_mapping(ha->hdr[i].size,&cyls,&hds,&secs); 
                ha->hdr[i].heads = hds;
                ha->hdr[i].secs = secs;
                /* round size */
                ha->hdr[i].size = cyls * hds * secs;
            }
            GDTH_UNLOCK_HA(ha, flags);
            if (status != S_OK)
                continue; 

            /* devtype, cluster info, R/W attribs */
            cmd.Service = CACHESERVICE;
            cmd.OpCode = GDT_DEVTYPE;
            cmd.u.cache.DeviceNo = i;
#if LINUX_VERSION_CODE >= 0x020503
            gdth_do_req(srp, &cmd, cmnd, 30);
            status = (ushort)srp->sr_command->SCp.Status;
            info = (ulong32)srp->sr_command->SCp.Message;
#elif LINUX_VERSION_CODE >= 0x020322
            gdth_do_cmd(scp, &cmd, cmnd, 30);
            status = (ushort)scp->SCp.Status;
            info = (ulong32)scp->SCp.Message;
#else
            gdth_do_cmd(&scp, &cmd, cmnd, 30);
            status = (ushort)scp.SCp.Status;
            info = (ulong32)scp.SCp.Message;
#endif
            GDTH_LOCK_HA(ha, flags);
            ha->hdr[i].devtype = (status == S_OK ? (ushort)info : 0);
            GDTH_UNLOCK_HA(ha, flags);

            cmd.Service = CACHESERVICE;
            cmd.OpCode = GDT_CLUST_INFO;
            cmd.u.cache.DeviceNo = i;
#if LINUX_VERSION_CODE >= 0x020503
            gdth_do_req(srp, &cmd, cmnd, 30);
            status = (ushort)srp->sr_command->SCp.Status;
            info = (ulong32)srp->sr_command->SCp.Message;
#elif LINUX_VERSION_CODE >= 0x020322
            gdth_do_cmd(scp, &cmd, cmnd, 30);
            status = (ushort)scp->SCp.Status;
            info = (ulong32)scp->SCp.Message;
#else
            gdth_do_cmd(&scp, &cmd, cmnd, 30);
            status = (ushort)scp.SCp.Status;
            info = (ulong32)scp.SCp.Message;
#endif
            GDTH_LOCK_HA(ha, flags);
            ha->hdr[i].cluster_type = 
                ((status == S_OK && !shared_access) ? (ushort)info : 0);
            GDTH_UNLOCK_HA(ha, flags);
            rsc.hdr_list[i].cluster_type = ha->hdr[i].cluster_type;

            cmd.Service = CACHESERVICE;
            cmd.OpCode = GDT_RW_ATTRIBS;
            cmd.u.cache.DeviceNo = i;
#if LINUX_VERSION_CODE >= 0x020503
            gdth_do_req(srp, &cmd, cmnd, 30);
            status = (ushort)srp->sr_command->SCp.Status;
            info = (ulong32)srp->sr_command->SCp.Message;
#elif LINUX_VERSION_CODE >= 0x020322
            gdth_do_cmd(scp, &cmd, cmnd, 30);
            status = (ushort)scp->SCp.Status;
            info = (ulong32)scp->SCp.Message;
#else
            gdth_do_cmd(&scp, &cmd, cmnd, 30);
            status = (ushort)scp.SCp.Status;
            info = (ulong32)scp.SCp.Message;
#endif
            GDTH_LOCK_HA(ha, flags);
            ha->hdr[i].rw_attribs = (status == S_OK ? (ushort)info : 0);
            GDTH_UNLOCK_HA(ha, flags);
        }
#if LINUX_VERSION_CODE >= 0x020503
        scsi_release_request(srp);
        scsi_free_host_dev(sdev);
#elif LINUX_VERSION_CODE >= 0x020322
        scsi_release_command(scp);
        scsi_free_host_dev(sdev);
#endif       
 
        if (copy_to_user((char *)arg, &rsc, sizeof(gdth_ioctl_rescan)))
            return -EFAULT;
        break;
      }
  
      case GDTIOCTL_HDRLIST:
      {
        gdth_ioctl_rescan rsc;
        gdth_cmd_str cmd;
        gdth_ha_str *ha;
        unchar i;
        int hanum;
        
        if (copy_from_user(&rsc, (char *)arg, sizeof(gdth_ioctl_rescan)) ||
            rsc.ionode >= gdth_ctr_count)
            return -EFAULT;
        hanum = rsc.ionode;
        ha = HADATA(gdth_ctr_tab[hanum]);
   
#if LINUX_VERSION_CODE >= 0x020503
        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
        srp  = scsi_allocate_request(sdev);
        if (!srp)
            return -ENOMEM;
        srp->sr_cmd_len = 12;
        srp->sr_use_sg = 0;
#elif LINUX_VERSION_CODE >= 0x020322
        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
        scp  = scsi_allocate_device(sdev, 1, FALSE);
        if (!scp)
            return -ENOMEM;
        scp->cmd_len = 12;
        scp->use_sg = 0;
#else
        memset(&sdev,0,sizeof(Scsi_Device));
        memset(&scp, 0,sizeof(Scsi_Cmnd));
        sdev.host = scp.host = gdth_ctr_tab[hanum];
        sdev.id = scp.target = sdev.host->this_id;
        scp.device = &sdev;
#endif

        for (i = 0; i < MAX_HDRIVES; ++i) { 
            if (!ha->hdr[i].present) {
                rsc.hdr_list[i].bus = 0xff; 
                continue;
            } 
            rsc.hdr_list[i].bus = ha->virt_bus;
            rsc.hdr_list[i].target = i;
            rsc.hdr_list[i].lun = 0;
            rsc.hdr_list[i].cluster_type = ha->hdr[i].cluster_type;
            if (ha->hdr[i].cluster_type & CLUSTER_DRIVE) { 
                cmd.Service = CACHESERVICE;
                cmd.OpCode = GDT_CLUST_INFO;
                cmd.u.cache.DeviceNo = i;
#if LINUX_VERSION_CODE >= 0x020503
                gdth_do_req(srp, &cmd, cmnd, 30);
                if (srp->sr_command->SCp.Status == S_OK)
                    rsc.hdr_list[i].cluster_type = srp->sr_command->SCp.Message;
#elif LINUX_VERSION_CODE >= 0x020322
                gdth_do_cmd(scp, &cmd, cmnd, 30);
                if (scp->SCp.Status == S_OK)
                    rsc.hdr_list[i].cluster_type = scp->SCp.Message;
#else
                gdth_do_cmd(&scp, &cmd, cmnd, 30);
                if (scp.SCp.Status == S_OK)
                    rsc.hdr_list[i].cluster_type = scp.SCp.Message;
#endif
            }
        } 
#if LINUX_VERSION_CODE >= 0x020503
        scsi_release_request(srp);
        scsi_free_host_dev(sdev);
#elif LINUX_VERSION_CODE >= 0x020322
        scsi_release_command(scp);
        scsi_free_host_dev(sdev);
#endif       
 
        if (copy_to_user((char *)arg, &rsc, sizeof(gdth_ioctl_rescan)))
            return -EFAULT;
        break;
      }

      case GDTIOCTL_RESET_BUS:
      {
        gdth_ioctl_reset res;
        int hanum, rval;

        if (copy_from_user(&res, (char *)arg, sizeof(gdth_ioctl_reset)) ||
            res.ionode >= gdth_ctr_count)
            return -EFAULT;
        hanum = res.ionode; 

        /* Because we need a Scsi_Cmnd struct., we make a scsi_allocate device also for kernels >=2.5.x */        
#if LINUX_VERSION_CODE >= 0x02053C
        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
        scp  = scsi_get_command(sdev, GFP_KERNEL);
        if (!scp)
            return -ENOMEM;
        scp->cmd_len = 12;
        scp->use_sg = 0;
        scp->device->channel = virt_ctr ? 0 : res.number;
        rval = gdth_eh_bus_reset(scp);
        res.status = (rval == SUCCESS ? S_OK : S_GENERR);
        scsi_put_command(scp);
        scsi_free_host_dev(sdev);
#elif LINUX_VERSION_CODE >= 0x020322
        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
#if LINUX_VERSION_CODE >= 0x020503
        scp  = scsi_allocate_device(sdev, 1);
#else
        scp  = scsi_allocate_device(sdev, 1, FALSE);
#endif
        if (!scp)
            return -ENOMEM;
        scp->cmd_len = 12;
        scp->use_sg = 0;
        scp->channel = virt_ctr ? 0 : res.number;
        rval = gdth_eh_bus_reset(scp);
        res.status = (rval == SUCCESS ? S_OK : S_GENERR);
        scsi_release_command(scp);
        scsi_free_host_dev(sdev);
#elif LINUX_VERSION_CODE >= 0x02015F
        memset(&sdev,0,sizeof(Scsi_Device));
        memset(&scp, 0,sizeof(Scsi_Cmnd));
        sdev.host = scp.host = gdth_ctr_tab[hanum];
        sdev.id = scp.target = sdev.host->this_id;
        scp.device = &sdev;
        scp.channel = virt_ctr ? 0 : res.number;
        rval = gdth_eh_bus_reset(&scp);
        res.status = (rval == SUCCESS ? S_OK : S_GENERR);
#else
        res.status = S_OK;
#endif
        if (copy_to_user((char *)arg, &res, sizeof(gdth_ioctl_reset)))
            return -EFAULT;
        break;
      }

      case GDTIOCTL_RESET_DRV:
      {
        gdth_ioctl_reset res;
        gdth_cmd_str cmd;
        int hanum;

        if (copy_from_user(&res, (char *)arg, sizeof(gdth_ioctl_reset)) ||
            res.ionode >= gdth_ctr_count || res.number >= MAX_HDRIVES)
            return -EFAULT;
        hanum = res.ionode;
        ha = HADATA(gdth_ctr_tab[hanum]);
 
        if (!ha->hdr[res.number].present)
            return 0;
        cmd.Service = CACHESERVICE;
        cmd.OpCode = GDT_CLUST_RESET;
        cmd.u.cache.DeviceNo = res.number;
#if LINUX_VERSION_CODE >= 0x020503
        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
        srp  = scsi_allocate_request(sdev);
        if (!srp)
            return -ENOMEM;
        srp->sr_cmd_len = 12;
        srp->sr_use_sg = 0;
        gdth_do_req(srp, &cmd, cmnd, 30);
        res.status = (ushort)srp->sr_command->SCp.Status;
        scsi_release_request(srp);
        scsi_free_host_dev(sdev);
#elif LINUX_VERSION_CODE >= 0x020322
        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
        scp  = scsi_allocate_device(sdev, 1, FALSE);
        if (!scp)
            return -ENOMEM;
        scp->cmd_len = 12;
        scp->use_sg = 0;
        gdth_do_cmd(scp, &cmd, cmnd, 30);
        res.status = (ushort)scp->SCp.Status;
        scsi_release_command(scp);
        scsi_free_host_dev(sdev);
#else
        memset(&sdev,0,sizeof(Scsi_Device));
        memset(&scp, 0,sizeof(Scsi_Cmnd));
        sdev.host = scp.host = gdth_ctr_tab[hanum];
        sdev.id = scp.target = sdev.host->this_id;
        scp.device = &sdev;
        gdth_do_cmd(&scp, &cmd, cmnd, 30);
        res.status = (ushort)scp.SCp.Status;
#endif
        if (copy_to_user((char *)arg, &res, sizeof(gdth_ioctl_reset)))
            return -EFAULT;
        break;
      }

      default:
        break; 
    }
    return 0;
}

Generated by GNU enscript 1.6.4.