gdth.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:166k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1.                 (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) 
  2.                 continue;
  3.         }
  4.         if (firsttime) {
  5.             if (gdth_test_busy(hanum)) {        /* controller busy ? */
  6.                 TRACE(("gdth_next() controller %d busy !n",hanum));
  7.                 if (!gdth_polling) {
  8.                     GDTH_UNLOCK_HA(ha, flags);
  9.                     return;
  10.                 }
  11.                 while (gdth_test_busy(hanum))
  12.                     gdth_delay(1);
  13.             }   
  14.             firsttime = FALSE;
  15.         }
  16. #if LINUX_VERSION_CODE >= 0x010300
  17.         if (nscp->done != gdth_scsi_done || nscp->cmnd[0] != 0xff) 
  18. #endif
  19.         {
  20.         if (nscp->SCp.phase == -1) {
  21.             nscp->SCp.phase = CACHESERVICE;           /* default: cache svc. */ 
  22.             if (nscp->cmnd[0] == TEST_UNIT_READY) {
  23.                 TRACE2(("TEST_UNIT_READY Bus %d Id %d LUN %dn", 
  24.                         b, t, nscp->lun));
  25.                 /* TEST_UNIT_READY -> set scan mode */
  26.                 if ((ha->scan_mode & 0x0f) == 0) {
  27.                     if (b == 0 && t == 0 && nscp->lun == 0) {
  28.                         ha->scan_mode |= 1;
  29.                         TRACE2(("Scan mode: 0x%xn", ha->scan_mode));
  30.                     }
  31.                 } else if ((ha->scan_mode & 0x0f) == 1) {
  32.                     if (b == 0 && ((t == 0 && nscp->lun == 1) ||
  33.                          (t == 1 && nscp->lun == 0))) {
  34.                         nscp->SCp.sent_command = GDT_SCAN_START;
  35.                         nscp->SCp.phase = ((ha->scan_mode & 0x10 ? 1:0) << 8) 
  36.                             | SCSIRAWSERVICE;
  37.                         ha->scan_mode = 0x12;
  38.                         TRACE2(("Scan mode: 0x%x (SCAN_START)n", 
  39.                                 ha->scan_mode));
  40.                     } else {
  41.                         ha->scan_mode &= 0x10;
  42.                         TRACE2(("Scan mode: 0x%xn", ha->scan_mode));
  43.                     }                   
  44.                 } else if (ha->scan_mode == 0x12) {
  45.                     if (b == ha->bus_cnt && t == ha->tid_cnt-1) {
  46.                         nscp->SCp.phase = SCSIRAWSERVICE;
  47.                         nscp->SCp.sent_command = GDT_SCAN_END;
  48.                         ha->scan_mode &= 0x10;
  49.                         TRACE2(("Scan mode: 0x%x (SCAN_END)n", 
  50.                                 ha->scan_mode));
  51.                     }
  52.                 }
  53.             }
  54.             if (b == ha->virt_bus && nscp->cmnd[0] != INQUIRY &&
  55.                 nscp->cmnd[0] != READ_CAPACITY && nscp->cmnd[0] != MODE_SENSE &&
  56.                 (ha->hdr[t].cluster_type & CLUSTER_DRIVE)) {
  57.                 /* always GDT_CLUST_INFO! */
  58.                 nscp->SCp.sent_command = GDT_CLUST_INFO;
  59.             }
  60.         }
  61.         }
  62.         if (nscp->SCp.sent_command != -1) {
  63.             if ((nscp->SCp.phase & 0xff) == CACHESERVICE) {
  64.                 if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t)))
  65.                     this_cmd = FALSE;
  66.                 next_cmd = FALSE;
  67.             } else if ((nscp->SCp.phase & 0xff) == SCSIRAWSERVICE) {
  68.                 if (!(cmd_index=gdth_fill_raw_cmd(hanum,nscp,BUS_L2P(ha,b))))
  69.                     this_cmd = FALSE;
  70.                 next_cmd = FALSE;
  71.             } else {
  72.                 memset((char*)nscp->sense_buffer,0,16);
  73.                 nscp->sense_buffer[0] = 0x70;
  74.                 nscp->sense_buffer[2] = NOT_READY;
  75.                 nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
  76.                 if (!nscp->SCp.have_data_in)
  77.                     nscp->SCp.have_data_in++;
  78.                 else {
  79.                     GDTH_UNLOCK_HA(ha,flags);
  80.                     /* io_request_lock already active ! */
  81.                     nscp->scsi_done(nscp);
  82.                     GDTH_LOCK_HA(ha,flags);
  83.                 }
  84.             }
  85.         } else
  86. #if LINUX_VERSION_CODE >= 0x010300
  87.         if (nscp->done == gdth_scsi_done && nscp->cmnd[0] == 0xff) {
  88.             if (!(cmd_index=gdth_special_cmd(hanum,nscp)))
  89.                 this_cmd = FALSE;
  90.             next_cmd = FALSE;
  91.         } else
  92. #endif
  93.         if (b != ha->virt_bus) {
  94.             if (ha->raw[BUS_L2P(ha,b)].io_cnt[t] >= GDTH_MAX_RAW ||
  95.                 !(cmd_index=gdth_fill_raw_cmd(hanum,nscp,BUS_L2P(ha,b)))) 
  96.                 this_cmd = FALSE;
  97.             else 
  98.                 ha->raw[BUS_L2P(ha,b)].io_cnt[t]++;
  99.         } else if (t >= MAX_HDRIVES || !ha->hdr[t].present || nscp->lun != 0) {
  100.             TRACE2(("Command 0x%x to bus %d id %d lun %d -> IGNOREn",
  101.                     nscp->cmnd[0], b, t, nscp->lun));
  102.             nscp->result = DID_BAD_TARGET << 16;
  103.             if (!nscp->SCp.have_data_in)
  104.                 nscp->SCp.have_data_in++;
  105.             else {
  106.                 GDTH_UNLOCK_HA(ha,flags);
  107.                 /* io_request_lock already active ! */      
  108.                 nscp->scsi_done(nscp);
  109.                 GDTH_LOCK_HA(ha,flags);
  110.             }
  111.         } else {
  112.             switch (nscp->cmnd[0]) {
  113.               case TEST_UNIT_READY:
  114.               case INQUIRY:
  115.               case REQUEST_SENSE:
  116.               case READ_CAPACITY:
  117.               case VERIFY:
  118.               case START_STOP:
  119.               case MODE_SENSE:
  120.                 TRACE(("cache cmd %x/%x/%x/%x/%x/%xn",nscp->cmnd[0],
  121.                        nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3],
  122.                        nscp->cmnd[4],nscp->cmnd[5]));
  123.                 if (ha->hdr[t].media_changed && nscp->cmnd[0] != INQUIRY) {
  124.                     /* return UNIT_ATTENTION */
  125.                     TRACE2(("cmd 0x%x target %d: UNIT_ATTENTIONn",
  126.                              nscp->cmnd[0], t));
  127.                     ha->hdr[t].media_changed = FALSE;
  128.                     memset((char*)nscp->sense_buffer,0,16);
  129.                     nscp->sense_buffer[0] = 0x70;
  130.                     nscp->sense_buffer[2] = UNIT_ATTENTION;
  131.                     nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
  132.                     if (!nscp->SCp.have_data_in)
  133.                         nscp->SCp.have_data_in++;
  134.                     else {
  135.                         GDTH_UNLOCK_HA(ha,flags);
  136.                         /* io_request_lock already active ! */      
  137.                         nscp->scsi_done(nscp);
  138.                         GDTH_LOCK_HA(ha,flags);
  139.                     }
  140.                 } else if (gdth_internal_cache_cmd(hanum,nscp)) {
  141.                     GDTH_UNLOCK_HA(ha,flags);
  142.                     /* io_request_lock already active ! */      
  143.                     nscp->scsi_done(nscp);
  144.                     GDTH_LOCK_HA(ha,flags);
  145.                 }
  146.                 break;
  147.               case ALLOW_MEDIUM_REMOVAL:
  148.                 TRACE(("cache cmd %x/%x/%x/%x/%x/%xn",nscp->cmnd[0],
  149.                        nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3],
  150.                        nscp->cmnd[4],nscp->cmnd[5]));
  151.                 if ( (nscp->cmnd[4]&1) && !(ha->hdr[t].devtype&1) ) {
  152.                     TRACE(("Prevent r. nonremov. drive->do nothingn"));
  153.                     nscp->result = DID_OK << 16;
  154.                     nscp->sense_buffer[0] = 0;
  155.                     if (!nscp->SCp.have_data_in)
  156.                         nscp->SCp.have_data_in++;
  157.                     else {
  158.                         GDTH_UNLOCK_HA(ha,flags);
  159.                         /* io_request_lock already active ! */      
  160.                         nscp->scsi_done(nscp);
  161.                         GDTH_LOCK_HA(ha,flags);
  162.                     }
  163.                 } else {
  164.                     nscp->cmnd[3] = (ha->hdr[t].devtype&1) ? 1:0;
  165.                     TRACE(("Prevent/allow r. %d rem. drive %dn",
  166.                            nscp->cmnd[4],nscp->cmnd[3]));
  167.                     if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t)))
  168.                         this_cmd = FALSE;
  169.                 }
  170.                 break;
  171.                 
  172.               case RESERVE:
  173.               case RELEASE:
  174.                 TRACE2(("cache cmd %sn",nscp->cmnd[0] == RESERVE ?
  175.                         "RESERVE" : "RELEASE"));
  176.                 if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t)))
  177.                     this_cmd = FALSE;
  178.                 break;
  179.                 
  180.               case READ_6:
  181.               case WRITE_6:
  182.               case READ_10:
  183.               case WRITE_10:
  184.                 if (ha->hdr[t].media_changed) {
  185.                     /* return UNIT_ATTENTION */
  186.                     TRACE2(("cmd 0x%x target %d: UNIT_ATTENTIONn",
  187.                              nscp->cmnd[0], t));
  188.                     ha->hdr[t].media_changed = FALSE;
  189.                     memset((char*)nscp->sense_buffer,0,16);
  190.                     nscp->sense_buffer[0] = 0x70;
  191.                     nscp->sense_buffer[2] = UNIT_ATTENTION;
  192.                     nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
  193.                     if (!nscp->SCp.have_data_in)
  194.                         nscp->SCp.have_data_in++;
  195.                     else {
  196.                         GDTH_UNLOCK_HA(ha,flags);
  197.                         /* io_request_lock already active ! */      
  198.                         nscp->scsi_done(nscp);
  199.                         GDTH_LOCK_HA(ha,flags);
  200.                     }
  201.                 } else if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t)))
  202.                     this_cmd = FALSE;
  203.                 break;
  204.               default:
  205.                 TRACE2(("cache cmd %x/%x/%x/%x/%x/%x unknownn",nscp->cmnd[0],
  206.                         nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3],
  207.                         nscp->cmnd[4],nscp->cmnd[5]));
  208.                 printk("GDT: Unknown SCSI command 0x%x to cache service !n",
  209.                        nscp->cmnd[0]);
  210.                 nscp->result = DID_ABORT << 16;
  211.                 if (!nscp->SCp.have_data_in)
  212.                     nscp->SCp.have_data_in++;
  213.                 else {
  214.                     GDTH_UNLOCK_HA(ha,flags);
  215.                     /* io_request_lock already active ! */  
  216.                     nscp->scsi_done(nscp);
  217.                     GDTH_LOCK_HA(ha,flags);
  218.                 }
  219.                 break;
  220.             }
  221.         }
  222.         if (!this_cmd)
  223.             break;
  224.         if (nscp == ha->req_first)
  225.             ha->req_first = pscp = (Scsi_Cmnd *)nscp->SCp.ptr;
  226.         else
  227.             pscp->SCp.ptr = nscp->SCp.ptr;
  228.         if (!next_cmd)
  229.             break;
  230.     }
  231.     if (ha->cmd_cnt > 0) {
  232.         gdth_release_event(hanum);
  233.     }
  234.     GDTH_UNLOCK_HA(ha, flags);
  235.     if (gdth_polling && ha->cmd_cnt > 0) {
  236.         if (!gdth_wait(hanum,cmd_index,POLL_TIMEOUT))
  237.             printk("GDT: Controller %d: Command %d timed out !n",
  238.                    hanum,cmd_index);
  239.     }
  240. }
  241.     
  242. static void gdth_copy_internal_data(Scsi_Cmnd *scp,char *buffer,ushort count)
  243. {
  244.     ushort cpcount,i;
  245.     ushort cpsum,cpnow;
  246.     struct scatterlist *sl;
  247.     cpcount = count<=(ushort)scp->bufflen ? count:(ushort)scp->bufflen;
  248.     if (scp->use_sg) {
  249.         sl = (struct scatterlist *)scp->request_buffer;
  250.         for (i=0,cpsum=0; i<scp->use_sg; ++i,++sl) {
  251.             cpnow = (ushort)sl->length;
  252.             TRACE(("copy_internal() now %d sum %d count %d %dn",
  253.                           cpnow,cpsum,cpcount,(ushort)scp->bufflen));
  254.             if (cpsum+cpnow > cpcount) 
  255.                 cpnow = cpcount - cpsum;
  256.             cpsum += cpnow;
  257.             memcpy((char*)sl->address,buffer,cpnow);
  258.             if (cpsum == cpcount)
  259.                 break;
  260.             buffer += cpnow;
  261.         }
  262.     } else {
  263.         TRACE(("copy_internal() count %dn",cpcount));
  264.         memcpy((char*)scp->request_buffer,buffer,cpcount);
  265.     }
  266. }
  267. static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp)
  268. {
  269.     register gdth_ha_str *ha;
  270.     unchar t;
  271.     gdth_inq_data inq;
  272.     gdth_rdcap_data rdc;
  273.     gdth_sense_data sd;
  274.     gdth_modep_data mpd;
  275.     ha = HADATA(gdth_ctr_tab[hanum]);
  276.     t  = scp->target;
  277.     TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %dn",
  278.            scp->cmnd[0],t));
  279.     switch (scp->cmnd[0]) {
  280.       case TEST_UNIT_READY:
  281.       case VERIFY:
  282.       case START_STOP:
  283.         TRACE2(("Test/Verify/Start hdrive %dn",t));
  284.         break;
  285.       case INQUIRY:
  286.         TRACE2(("Inquiry hdrive %d devtype %dn",
  287.                 t,ha->hdr[t].devtype));
  288.         inq.type_qual = (ha->hdr[t].devtype&4) ? TYPE_ROM:TYPE_DISK;
  289.         /* you can here set all disks to removable, if you want to do
  290.            a flush using the ALLOW_MEDIUM_REMOVAL command */
  291.         inq.modif_rmb = 0x00;
  292.         if ((ha->hdr[t].devtype & 1) ||
  293.             (ha->hdr[t].cluster_type & CLUSTER_DRIVE))
  294.             inq.modif_rmb = 0x80;
  295.         inq.version   = 2;
  296.         inq.resp_aenc = 2;
  297.         inq.add_length= 32;
  298.         if (ha->oem_id == OEM_ID_INTEL)
  299.             strcpy(inq.vendor,"Intel  ");
  300.         else 
  301.             strcpy(inq.vendor,"ICP    ");
  302.         sprintf(inq.product,"Host Drive  #%02d",t);
  303.         strcpy(inq.revision,"   ");
  304.         gdth_copy_internal_data(scp,(char*)&inq,sizeof(gdth_inq_data));
  305.         break;
  306.       case REQUEST_SENSE:
  307.         TRACE2(("Request sense hdrive %dn",t));
  308.         sd.errorcode = 0x70;
  309.         sd.segno     = 0x00;
  310.         sd.key       = NO_SENSE;
  311.         sd.info      = 0;
  312.         sd.add_length= 0;
  313.         gdth_copy_internal_data(scp,(char*)&sd,sizeof(gdth_sense_data));
  314.         break;
  315.       case MODE_SENSE:
  316.         TRACE2(("Mode sense hdrive %dn",t));
  317.         memset((char*)&mpd,0,sizeof(gdth_modep_data));
  318.         mpd.hd.data_length = sizeof(gdth_modep_data);
  319.         mpd.hd.dev_par     = (ha->hdr[t].devtype&2) ? 0x80:0;
  320.         mpd.hd.bd_length   = sizeof(mpd.bd);
  321.         mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16;
  322.         mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8;
  323.         mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff);
  324.         gdth_copy_internal_data(scp,(char*)&mpd,sizeof(gdth_modep_data));
  325.         break;
  326.       case READ_CAPACITY:
  327.         TRACE2(("Read capacity hdrive %dn",t));
  328.         rdc.last_block_no = ntohl(ha->hdr[t].size-1);
  329.         rdc.block_length  = ntohl(SECTOR_SIZE);
  330.         gdth_copy_internal_data(scp,(char*)&rdc,sizeof(gdth_rdcap_data));
  331.         break;
  332.       default:
  333.         TRACE2(("Internal cache cmd 0x%x unknownn",scp->cmnd[0]));
  334.         break;
  335.     }
  336.     scp->result = DID_OK << 16;
  337.     scp->sense_buffer[0] = 0;
  338.     if (!scp->SCp.have_data_in)
  339.         scp->SCp.have_data_in++;
  340.     else 
  341.         return 1;
  342.     return 0;
  343. }
  344.     
  345. static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive)
  346. {
  347.     register gdth_ha_str *ha;
  348.     register gdth_cmd_str *cmdp;
  349.     struct scatterlist *sl;
  350.     ushort i, cnt;
  351.     ulong32 no;
  352.     int cmd_index, read_write;
  353.     ha = HADATA(gdth_ctr_tab[hanum]);
  354.     cmdp = ha->pccb;
  355.     TRACE(("gdth_fill_cache_cmd() cmd 0x%x cmdsize %d hdrive %dn",
  356.                  scp->cmnd[0],scp->cmd_len,hdrive));
  357.     if (ha->type==GDT_EISA && ha->cmd_cnt>0) 
  358.         return 0;
  359.     cmdp->Service = CACHESERVICE;
  360.     cmdp->RequestBuffer = scp;
  361.     /* search free command index */
  362.     if (!(cmd_index=gdth_get_cmd_index(hanum))) {
  363.         TRACE(("GDT: No free command index foundn"));
  364.         return 0;
  365.     }
  366.     /* if it's the first command, set command semaphore */
  367.     if (ha->cmd_cnt == 0)
  368.         gdth_set_sema0(hanum);
  369.     /* fill command */
  370.     read_write = FALSE;
  371.     if (scp->SCp.sent_command != -1) 
  372.         cmdp->OpCode = scp->SCp.sent_command;   /* special cache cmd. */
  373.     else if (scp->cmnd[0] == RESERVE) 
  374.         cmdp->OpCode = GDT_RESERVE_DRV;
  375.     else if (scp->cmnd[0] == RELEASE)
  376.         cmdp->OpCode = GDT_RELEASE_DRV;
  377.     else if (scp->cmnd[0] == ALLOW_MEDIUM_REMOVAL) {
  378.         if (scp->cmnd[4] & 1)                   /* prevent ? */
  379.             cmdp->OpCode = GDT_MOUNT;
  380.         else if (scp->cmnd[3] & 1)              /* removable drive ? */
  381.             cmdp->OpCode = GDT_UNMOUNT;
  382.         else
  383.             cmdp->OpCode = GDT_FLUSH;
  384.     } else if (scp->cmnd[0] == WRITE_6 || scp->cmnd[0] == WRITE_10) {
  385.         read_write = TRUE;
  386.         if (gdth_write_through || ((ha->hdr[hdrive].rw_attribs & 1) && 
  387.                                    (ha->cache_feat & GDT_WR_THROUGH)))
  388.             cmdp->OpCode = GDT_WRITE_THR;
  389.         else
  390.             cmdp->OpCode = GDT_WRITE;
  391.     } else {
  392.         read_write = TRUE;
  393.         cmdp->OpCode = GDT_READ;
  394.     }
  395.     
  396.     cmdp->BoardNode        = LOCALBOARD;
  397.     cmdp->u.cache.DeviceNo = hdrive;
  398.     cmdp->u.cache.BlockNo  = 1;
  399.     cmdp->u.cache.sg_canz  = 0;
  400.     if (read_write) {
  401.         if (scp->cmd_len != 6) {
  402.             memcpy(&no, &scp->cmnd[2], sizeof(ulong32));
  403.             cmdp->u.cache.BlockNo = ntohl(no);
  404.             memcpy(&cnt, &scp->cmnd[7], sizeof(ushort));
  405.             cmdp->u.cache.BlockCnt = (ulong32)ntohs(cnt);
  406.         } else {
  407.             memcpy(&no, &scp->cmnd[0], sizeof(ulong32));
  408.             cmdp->u.cache.BlockNo = ntohl(no) & 0x001fffffUL;
  409.             cmdp->u.cache.BlockCnt= scp->cmnd[4]==0 ? 0x100 : scp->cmnd[4];
  410.         }
  411.         if (scp->use_sg) {
  412.             cmdp->u.cache.DestAddr= 0xffffffff;
  413.             sl = (struct scatterlist *)scp->request_buffer;
  414.             for (i=0; i<scp->use_sg; ++i,++sl) {
  415.                 cmdp->u.cache.sg_lst[i].sg_ptr = virt_to_bus(sl->address);
  416.                 cmdp->u.cache.sg_lst[i].sg_len = (ulong32)sl->length;
  417.             }
  418.             cmdp->u.cache.sg_canz = (ulong32)i;
  419. #ifdef GDTH_STATISTICS
  420.             if (max_sg < (ulong32)i) {
  421.                 max_sg = (ulong32)i;
  422.                 TRACE3(("GDT: max_sg = %dn",i));
  423.             }
  424. #endif
  425.             if (i<GDTH_MAXSG)
  426.                 cmdp->u.cache.sg_lst[i].sg_len = 0;
  427.         } else {
  428.             if (ha->cache_feat & SCATTER_GATHER) {
  429.                 cmdp->u.cache.DestAddr = 0xffffffff;
  430.                 cmdp->u.cache.sg_canz = 1;
  431.                 cmdp->u.cache.sg_lst[0].sg_ptr = 
  432.                     virt_to_bus(scp->request_buffer);
  433.                 cmdp->u.cache.sg_lst[0].sg_len = scp->request_bufflen;
  434.                 cmdp->u.cache.sg_lst[1].sg_len = 0;
  435.             } else {
  436.                 cmdp->u.cache.DestAddr  = virt_to_bus(scp->request_buffer);
  437.                 cmdp->u.cache.sg_canz= 0;
  438.             }
  439.         }
  440.     }
  441.     TRACE(("cache cmd: addr. %x sganz %x sgptr0 %x sglen0 %xn",
  442.            cmdp->u.cache.DestAddr,cmdp->u.cache.sg_canz,
  443.            cmdp->u.cache.sg_lst[0].sg_ptr,
  444.            cmdp->u.cache.sg_lst[0].sg_len));
  445.     TRACE(("cache cmd: cmd %d blockno. %d, blockcnt %dn",
  446.            cmdp->OpCode,cmdp->u.cache.BlockNo,cmdp->u.cache.BlockCnt));
  447.     /* evaluate command size, check space */
  448.     ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.cache.sg_lst) +
  449.         (ushort)cmdp->u.cache.sg_canz * sizeof(gdth_sg_str);
  450.     if (ha->cmd_len & 3)
  451.         ha->cmd_len += (4 - (ha->cmd_len & 3));
  452.     if (ha->cmd_cnt > 0) {
  453.         if ((ha->cmd_offs_dpmem + ha->cmd_len + DPMEM_COMMAND_OFFSET) >
  454.             ha->ic_all_size) {
  455.             TRACE2(("gdth_fill_cache() DPMEM overflown"));
  456.             ha->cmd_tab[cmd_index-2].cmnd = UNUSED_CMND;
  457.             return 0;
  458.         }
  459.     }
  460.     /* copy command */
  461.     gdth_copy_command(hanum);
  462.     return cmd_index;
  463. }
  464. static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b)
  465. {
  466.     register gdth_ha_str *ha;
  467.     register gdth_cmd_str *cmdp;
  468.     struct scatterlist *sl;
  469.     ushort i;
  470.     int cmd_index;
  471.     unchar t,l;
  472.     ha = HADATA(gdth_ctr_tab[hanum]);
  473.     t = scp->target;
  474.     l = scp->lun;
  475.     cmdp = ha->pccb;
  476.     TRACE(("gdth_fill_raw_cmd() cmd 0x%x bus %d ID %d LUN %dn",
  477.            scp->cmnd[0],b,t,l));
  478.     if (ha->type==GDT_EISA && ha->cmd_cnt>0) 
  479.         return 0;
  480.     cmdp->Service = SCSIRAWSERVICE;
  481.     cmdp->RequestBuffer = scp;
  482.     /* search free command index */
  483.     if (!(cmd_index=gdth_get_cmd_index(hanum))) {
  484.         TRACE(("GDT: No free command index foundn"));
  485.         return 0;
  486.     }
  487.     /* if it's the first command, set command semaphore */
  488.     if (ha->cmd_cnt == 0)
  489.         gdth_set_sema0(hanum);
  490.     /* fill command */  
  491.     if (scp->SCp.sent_command != -1) {
  492.         cmdp->OpCode           = scp->SCp.sent_command; /* special raw cmd. */
  493.         cmdp->BoardNode        = LOCALBOARD;
  494.         cmdp->u.raw.direction  = (scp->SCp.phase >> 8);
  495.         TRACE2(("special raw cmd 0x%x param 0x%xn", 
  496.                 cmdp->OpCode, cmdp->u.raw.direction));
  497.         /* evaluate command size */
  498.         ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw.sg_lst);
  499.     } else {
  500.         cmdp->OpCode           = GDT_WRITE;             /* always */
  501.         cmdp->BoardNode        = LOCALBOARD;
  502.         cmdp->u.raw.reserved   = 0;
  503.         cmdp->u.raw.mdisc_time = 0;
  504.         cmdp->u.raw.mcon_time  = 0;
  505.         cmdp->u.raw.clen       = scp->cmd_len;
  506.         cmdp->u.raw.target     = t;
  507.         cmdp->u.raw.lun        = l;
  508.         cmdp->u.raw.bus        = b;
  509.         cmdp->u.raw.priority   = 0;
  510.         cmdp->u.raw.link_p     = 0;
  511.         cmdp->u.raw.sdlen      = scp->request_bufflen;
  512.         cmdp->u.raw.sense_len  = 16;
  513.         cmdp->u.raw.sense_data = virt_to_bus(scp->sense_buffer);
  514.         cmdp->u.raw.direction  = 
  515.             gdth_direction_tab[scp->cmnd[0]]==DOU ? GDTH_DATA_OUT:GDTH_DATA_IN;
  516.         memcpy(cmdp->u.raw.cmd,scp->cmnd,12);
  517.         if (scp->use_sg) {
  518.             cmdp->u.raw.sdata  = 0xffffffff;
  519.             sl = (struct scatterlist *)scp->request_buffer;
  520.             for (i=0; i<scp->use_sg; ++i,++sl) {
  521.                 cmdp->u.raw.sg_lst[i].sg_ptr = virt_to_bus(sl->address);
  522.                 cmdp->u.raw.sg_lst[i].sg_len = (ulong32)sl->length;
  523.             }
  524.             cmdp->u.raw.sg_ranz = (ulong32)i;
  525. #ifdef GDTH_STATISTICS
  526.             if (max_sg < (ulong32)i) {
  527.                 max_sg = (ulong32)i;
  528.                 TRACE3(("GDT: max_sg = %dn",i));
  529.             }
  530. #endif
  531.             if (i<GDTH_MAXSG)
  532.                 cmdp->u.raw.sg_lst[i].sg_len = 0;
  533.         } else {
  534.             if (ha->raw_feat & SCATTER_GATHER) {
  535.                 cmdp->u.raw.sdata  = 0xffffffff;
  536.                 cmdp->u.raw.sg_ranz= 1;
  537.                 cmdp->u.raw.sg_lst[0].sg_ptr = virt_to_bus(scp->request_buffer);
  538.                 cmdp->u.raw.sg_lst[0].sg_len = scp->request_bufflen;
  539.                 cmdp->u.raw.sg_lst[1].sg_len = 0;
  540.             } else {
  541.                 cmdp->u.raw.sdata  = virt_to_bus(scp->request_buffer);
  542.                 cmdp->u.raw.sg_ranz= 0;
  543.             }
  544.         }
  545.         TRACE(("raw cmd: addr. %x sganz %x sgptr0 %x sglen0 %xn",
  546.                cmdp->u.raw.sdata,cmdp->u.raw.sg_ranz,
  547.                cmdp->u.raw.sg_lst[0].sg_ptr,
  548.                cmdp->u.raw.sg_lst[0].sg_len));
  549.         /* evaluate command size */
  550.         ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw.sg_lst) +
  551.             (ushort)cmdp->u.raw.sg_ranz * sizeof(gdth_sg_str);
  552.     }
  553.     /* check space */
  554.     if (ha->cmd_len & 3)
  555.         ha->cmd_len += (4 - (ha->cmd_len & 3));
  556.     if (ha->cmd_cnt > 0) {
  557.         if ((ha->cmd_offs_dpmem + ha->cmd_len + DPMEM_COMMAND_OFFSET) >
  558.             ha->ic_all_size) {
  559.             TRACE2(("gdth_fill_raw() DPMEM overflown"));
  560.             ha->cmd_tab[cmd_index-2].cmnd = UNUSED_CMND;
  561.             return 0;
  562.         }
  563.     }
  564.     /* copy command */
  565.     gdth_copy_command(hanum);
  566.     return cmd_index;
  567. }
  568. static int gdth_special_cmd(int hanum,Scsi_Cmnd *scp)
  569. {
  570.     register gdth_ha_str *ha;
  571.     register gdth_cmd_str *cmdp;
  572.     int cmd_index;
  573.     ha  = HADATA(gdth_ctr_tab[hanum]);
  574.     cmdp= ha->pccb;
  575.     TRACE2(("gdth_special_cmd(): "));
  576.     if (ha->type==GDT_EISA && ha->cmd_cnt>0) 
  577.         return 0;
  578.     memcpy( cmdp, scp->request_buffer, sizeof(gdth_cmd_str));
  579.     cmdp->RequestBuffer = scp;
  580.     /* search free command index */
  581.     if (!(cmd_index=gdth_get_cmd_index(hanum))) {
  582.         TRACE(("GDT: No free command index foundn"));
  583.         return 0;
  584.     }
  585.     /* if it's the first command, set command semaphore */
  586.     if (ha->cmd_cnt == 0)
  587.        gdth_set_sema0(hanum);
  588.     /* evaluate command size, check space */
  589.     if (cmdp->OpCode == GDT_IOCTL) {
  590.         TRACE2(("IOCTLn"));
  591.         ha->cmd_len = 
  592.             GDTOFFSOF(gdth_cmd_str,u.ioctl.p_param) + sizeof(ulong32);
  593.     } else if (cmdp->Service == CACHESERVICE) {
  594.         TRACE2(("cache command %dn",cmdp->OpCode));
  595.         ha->cmd_len = 
  596.             GDTOFFSOF(gdth_cmd_str,u.cache.sg_lst) + sizeof(gdth_sg_str);
  597.     } else if (cmdp->Service == SCSIRAWSERVICE) {
  598.         TRACE2(("raw command %d/%dn",cmdp->OpCode,cmdp->u.raw.cmd[0]));
  599.         ha->cmd_len = 
  600.             GDTOFFSOF(gdth_cmd_str,u.raw.sg_lst) + sizeof(gdth_sg_str);
  601.     }
  602.     if (ha->cmd_len & 3)
  603.         ha->cmd_len += (4 - (ha->cmd_len & 3));
  604.     if (ha->cmd_cnt > 0) {
  605.         if ((ha->cmd_offs_dpmem + ha->cmd_len + DPMEM_COMMAND_OFFSET) >
  606.             ha->ic_all_size) {
  607.             TRACE2(("gdth_special_cmd() DPMEM overflown"));
  608.             ha->cmd_tab[cmd_index-2].cmnd = UNUSED_CMND;
  609.             return 0;
  610.         }
  611.     }
  612.     /* copy command */
  613.     gdth_copy_command(hanum);
  614.     return cmd_index;
  615. }    
  616. /* Controller event handling functions */
  617. static gdth_evt_str *gdth_store_event(gdth_ha_str *ha, ushort source, 
  618.                                       ushort idx, gdth_evt_data *evt)
  619. {
  620.     gdth_evt_str *e;
  621.     struct timeval tv;
  622.     /* no GDTH_LOCK_HA() ! */
  623.     TRACE2(("gdth_store_event() source %d idx %dn", source, idx));
  624.     if (source == 0)                        /* no source -> no event */
  625.         return 0;
  626.     if (ebuffer[elastidx].event_source == source &&
  627.         ebuffer[elastidx].event_idx == idx &&
  628.         ((evt->size != 0 && ebuffer[elastidx].event_data.size != 0 &&
  629.             !memcmp((char *)&ebuffer[elastidx].event_data.eu,
  630.             (char *)&evt->eu, evt->size)) ||
  631.         (evt->size == 0 && ebuffer[elastidx].event_data.size == 0 &&
  632.             !strcmp((char *)&ebuffer[elastidx].event_data.event_string,
  633.             (char *)&evt->event_string)))) { 
  634.         e = &ebuffer[elastidx];
  635.         do_gettimeofday(&tv);
  636.         e->last_stamp = tv.tv_sec;
  637.         ++e->same_count;
  638.     } else {
  639.         if (ebuffer[elastidx].event_source != 0) {  /* entry not free ? */
  640.             ++elastidx;
  641.             if (elastidx == MAX_EVENTS)
  642.                 elastidx = 0;
  643.             if (elastidx == eoldidx) {              /* reached mark ? */
  644.                 ++eoldidx;
  645.                 if (eoldidx == MAX_EVENTS)
  646.                     eoldidx = 0;
  647.             }
  648.         }
  649.         e = &ebuffer[elastidx];
  650.         e->event_source = source;
  651.         e->event_idx = idx;
  652.         do_gettimeofday(&tv);
  653.         e->first_stamp = e->last_stamp = tv.tv_sec;
  654.         e->same_count = 1;
  655.         e->event_data = *evt;
  656.         e->application = 0;
  657.     }
  658.     return e;
  659. }
  660. static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr)
  661. {
  662.     gdth_evt_str *e;
  663.     int eindex;
  664.     ulong flags;
  665.     TRACE2(("gdth_read_event() handle %dn", handle));
  666.     GDTH_LOCK_HA(ha, flags);
  667.     if (handle == -1)
  668.         eindex = eoldidx;
  669.     else
  670.         eindex = handle;
  671.     estr->event_source = 0;
  672.     if (eindex >= MAX_EVENTS) {
  673.         GDTH_UNLOCK_HA(ha, flags);
  674.         return eindex;
  675.     }
  676.     e = &ebuffer[eindex];
  677.     if (e->event_source != 0) {
  678.         if (eindex != elastidx) {
  679.             if (++eindex == MAX_EVENTS)
  680.                 eindex = 0;
  681.         } else {
  682.             eindex = -1;
  683.         }
  684.         memcpy(estr, e, sizeof(gdth_evt_str));
  685.     }
  686.     GDTH_UNLOCK_HA(ha, flags);
  687.     return eindex;
  688. }
  689. static void gdth_readapp_event(gdth_ha_str *ha,
  690.                                unchar application, gdth_evt_str *estr)
  691. {
  692.     gdth_evt_str *e;
  693.     int eindex;
  694.     ulong flags;
  695.     unchar found = FALSE;
  696.     TRACE2(("gdth_readapp_event() app. %dn", application));
  697.     GDTH_LOCK_HA(ha, flags);
  698.     eindex = eoldidx;
  699.     for (;;) {
  700.         e = &ebuffer[eindex];
  701.         if (e->event_source == 0)
  702.             break;
  703.         if ((e->application & application) == 0) {
  704.             e->application |= application;
  705.             found = TRUE;
  706.             break;
  707.         }
  708.         if (eindex == elastidx)
  709.             break;
  710.         if (++eindex == MAX_EVENTS)
  711.             eindex = 0;
  712.     }
  713.     if (found)
  714.         memcpy(estr, e, sizeof(gdth_evt_str));
  715.     else
  716.         estr->event_source = 0;
  717.     GDTH_UNLOCK_HA(ha, flags);
  718. }
  719. static void gdth_clear_events()
  720. {
  721.     TRACE(("gdth_clear_events()"));
  722.     eoldidx = elastidx = 0;
  723.     ebuffer[0].event_source = 0;
  724. }
  725. /* SCSI interface functions */
  726. #if LINUX_VERSION_CODE >= 0x010346
  727. static void gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs)
  728. #else
  729. static void gdth_interrupt(int irq,struct pt_regs *regs)
  730. #endif
  731. {
  732.     register gdth_ha_str *ha;
  733.     gdt6m_dpram_str *dp6m_ptr;
  734.     gdt6_dpram_str *dp6_ptr;
  735.     gdt2_dpram_str *dp2_ptr;
  736.     Scsi_Cmnd *scp;
  737.     int hanum, rval, i;
  738.     unchar IStatus;
  739.     ushort Service;
  740.     ulong flags = 0;
  741.     TRACE(("gdth_interrupt() IRQ %dn",irq));
  742.     /* if polling and not from gdth_wait() -> return */
  743.     if (gdth_polling) {
  744.         if (!gdth_from_wait) {
  745.             return;
  746.         }
  747.     }
  748.     if (!gdth_polling)
  749.         GDTH_LOCK_HA((gdth_ha_str *)dev_id,flags);
  750.     wait_index = 0;
  751.     /* search controller */
  752.     if ((hanum = gdth_get_status(&IStatus,irq)) == -1) {
  753.         /* spurious interrupt */
  754.         if (!gdth_polling)
  755.             GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
  756.         return;
  757.     }
  758. #ifdef GDTH_STATISTICS
  759.     ++act_ints;
  760. #endif
  761.     
  762.     ha = HADATA(gdth_ctr_tab[hanum]);
  763.     if (ha->type == GDT_EISA) {
  764.         if (IStatus & 0x80) {                       /* error flag */
  765.             IStatus &= ~0x80;
  766.             ha->status = inw(ha->bmic + MAILBOXREG+8);
  767.             TRACE2(("gdth_interrupt() error %d/%dn",IStatus,ha->status));
  768.         } else                                      /* no error */
  769.             ha->status = S_OK;
  770.         ha->info = inl(ha->bmic + MAILBOXREG+12);
  771.         ha->service = inw(ha->bmic + MAILBOXREG+10);
  772.         ha->info2 = inl(ha->bmic + MAILBOXREG+4);
  773.         outb(0xff, ha->bmic + EDOORREG);            /* acknowledge interrupt */
  774.         outb(0x00, ha->bmic + SEMA1REG);            /* reset status semaphore */
  775.     } else if (ha->type == GDT_ISA) {
  776.         dp2_ptr = (gdt2_dpram_str *)ha->brd;
  777.         if (IStatus & 0x80) {                       /* error flag */
  778.             IStatus &= ~0x80;
  779.             ha->status = gdth_readw(&dp2_ptr->u.ic.Status);
  780.             TRACE2(("gdth_interrupt() error %d/%dn",IStatus,ha->status));
  781.         } else                                      /* no error */
  782.             ha->status = S_OK;
  783.         ha->info = gdth_readl(&dp2_ptr->u.ic.Info[0]);
  784.         ha->service = gdth_readw(&dp2_ptr->u.ic.Service);
  785.         ha->info2 = gdth_readl(&dp2_ptr->u.ic.Info[1]);
  786.         gdth_writeb(0xff, &dp2_ptr->io.irqdel);     /* acknowledge interrupt */
  787.         gdth_writeb(0, &dp2_ptr->u.ic.Cmd_Index);   /* reset command index */
  788.         gdth_writeb(0, &dp2_ptr->io.Sema1);         /* reset status semaphore */
  789.     } else if (ha->type == GDT_PCI) {
  790.         dp6_ptr = (gdt6_dpram_str *)ha->brd;
  791.         if (IStatus & 0x80) {                       /* error flag */
  792.             IStatus &= ~0x80;
  793.             ha->status = gdth_readw(&dp6_ptr->u.ic.Status);
  794.             TRACE2(("gdth_interrupt() error %d/%dn",IStatus,ha->status));
  795.         } else                                      /* no error */
  796.             ha->status = S_OK;
  797.         ha->info = gdth_readl(&dp6_ptr->u.ic.Info[0]);
  798.         ha->service = gdth_readw(&dp6_ptr->u.ic.Service);
  799.         ha->info2 = gdth_readl(&dp6_ptr->u.ic.Info[1]);
  800.         gdth_writeb(0xff, &dp6_ptr->io.irqdel);     /* acknowledge interrupt */
  801.         gdth_writeb(0, &dp6_ptr->u.ic.Cmd_Index);   /* reset command index */
  802.         gdth_writeb(0, &dp6_ptr->io.Sema1);         /* reset status semaphore */
  803.     } else if (ha->type == GDT_PCINEW) {
  804.         if (IStatus & 0x80) {                       /* error flag */
  805.             IStatus &= ~0x80;
  806.             ha->status = inw(PTR2USHORT(&ha->plx->status));
  807.             TRACE2(("gdth_interrupt() error %d/%dn",IStatus,ha->status));
  808.         } else
  809.             ha->status = S_OK;
  810.         ha->info = inl(PTR2USHORT(&ha->plx->info[0]));
  811.         ha->service = inw(PTR2USHORT(&ha->plx->service));
  812.         ha->info2 = inl(PTR2USHORT(&ha->plx->info[1]));
  813.         outb(0xff, PTR2USHORT(&ha->plx->edoor_reg)); 
  814.         outb(0x00, PTR2USHORT(&ha->plx->sema1_reg)); 
  815.     } else if (ha->type == GDT_PCIMPR) {
  816.         dp6m_ptr = (gdt6m_dpram_str *)ha->brd;
  817.         if (IStatus & 0x80) {                       /* error flag */
  818.             IStatus &= ~0x80;
  819.             ha->status = gdth_readw(&dp6m_ptr->i960r.status);
  820.             TRACE2(("gdth_interrupt() error %d/%dn",IStatus,ha->status));
  821.         } else                                      /* no error */
  822.             ha->status = S_OK;
  823.         ha->info = gdth_readl(&dp6m_ptr->i960r.info[0]);
  824.         ha->service = gdth_readw(&dp6m_ptr->i960r.service);
  825.         ha->info2 = gdth_readl(&dp6m_ptr->i960r.info[1]);
  826.         /* event string */
  827.         if (IStatus == ASYNCINDEX) {
  828.             if (ha->service != SCREENSERVICE &&
  829.                 (ha->fw_vers & 0xff) >= 0x1a) {
  830.                 ha->dvr.severity =   
  831.                     gdth_readb(&((gdt6m_dpram_str *)ha->brd)->i960r.severity);
  832.                 for (i = 0; i < 256; ++i) {
  833.                     ha->dvr.event_string[i] = gdth_readb
  834.                         (&((gdt6m_dpram_str *)ha->brd)->i960r.evt_str[i]);
  835.                     if (ha->dvr.event_string[i] == 0)
  836.                         break;
  837.                 }
  838.             }
  839.         }
  840.         gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg);
  841.         gdth_writeb(0, &dp6m_ptr->i960r.sema1_reg);
  842.     } else {
  843.         TRACE2(("gdth_interrupt() unknown controller typen"));
  844.         if (!gdth_polling)
  845.             GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
  846.         return;
  847.     }
  848.     TRACE(("gdth_interrupt() index %d stat %d info %dn",
  849.            IStatus,ha->status,ha->info));
  850.     if (gdth_from_wait) {
  851.         wait_hanum = hanum;
  852.         wait_index = (int)IStatus;
  853.     }
  854.     if (IStatus == ASYNCINDEX) {
  855.         TRACE2(("gdth_interrupt() async. eventn"));
  856.         gdth_async_event(hanum);
  857.         if (!gdth_polling)
  858.             GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
  859.         gdth_next(hanum);
  860.         return;
  861.     } 
  862.     if (IStatus == SPEZINDEX) {
  863.         TRACE2(("Service unknown or not initialized !n"));
  864.         ha->dvr.size = sizeof(ha->dvr.eu.driver);
  865.         ha->dvr.eu.driver.ionode = hanum;
  866.         gdth_store_event(ha, ES_DRIVER, 4, &ha->dvr);
  867.         if (!gdth_polling)
  868.             GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
  869.         return;
  870.     }
  871.     scp     = ha->cmd_tab[IStatus-2].cmnd;
  872.     Service = ha->cmd_tab[IStatus-2].service;
  873.     ha->cmd_tab[IStatus-2].cmnd = UNUSED_CMND;
  874.     if (scp == UNUSED_CMND) {
  875.         TRACE2(("gdth_interrupt() index to unused command (%d)n",IStatus));
  876.         ha->dvr.size = sizeof(ha->dvr.eu.driver);
  877.         ha->dvr.eu.driver.ionode = hanum;
  878.         ha->dvr.eu.driver.index = IStatus;
  879.         gdth_store_event(ha, ES_DRIVER, 1, &ha->dvr);
  880.         if (!gdth_polling)
  881.             GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
  882.         return;
  883.     }
  884.     if (scp == INTERNAL_CMND) {
  885.         TRACE(("gdth_interrupt() answer to internal commandn"));
  886.         if (!gdth_polling)
  887.             GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
  888.         return;
  889.     }
  890.     TRACE(("gdth_interrupt() sync. statusn"));
  891.     rval = gdth_sync_event(hanum,Service,IStatus,scp);
  892.     if (!gdth_polling)
  893.         GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
  894.     if (rval == 2) {
  895.         gdth_putq(hanum,scp,scp->SCp.this_residual);
  896.     } else if (rval == 1) {
  897.         GDTH_LOCK_SCSI_DONE(flags);
  898.         scp->scsi_done(scp);
  899.         GDTH_UNLOCK_SCSI_DONE(flags);
  900.     }
  901.     gdth_next(hanum);
  902. }
  903. static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
  904. {
  905.     register gdth_ha_str *ha;
  906.     gdth_msg_str *msg;
  907.     gdth_cmd_str *cmdp;
  908.     unchar b;
  909.     ha   = HADATA(gdth_ctr_tab[hanum]);
  910.     cmdp = ha->pccb;
  911.     TRACE(("gdth_sync_event() serv %d status %dn",
  912.            service,ha->status));
  913.     if (service == SCREENSERVICE) {
  914.         msg  = (gdth_msg_str *)ha->pscratch;
  915.         ha->scratch_busy = FALSE;
  916.         TRACE(("len: %d, answer: %d, ext: %d, alen: %dn",
  917.                msg->msg_len,msg->msg_answer,msg->msg_ext,msg->msg_alen));
  918.         if (msg->msg_len)
  919.             if (!(msg->msg_answer && msg->msg_ext)) {
  920.                 msg->msg_text[msg->msg_len] = '';
  921.                 printk("%s",msg->msg_text);
  922.             }
  923.         if (msg->msg_ext && !msg->msg_answer) {
  924.             while (gdth_test_busy(hanum))
  925.                 gdth_delay(0);
  926.             cmdp->Service       = SCREENSERVICE;
  927.             cmdp->RequestBuffer = SCREEN_CMND;
  928.             gdth_get_cmd_index(hanum);
  929.             gdth_set_sema0(hanum);
  930.             cmdp->OpCode        = GDT_READ;
  931.             cmdp->BoardNode     = LOCALBOARD;
  932.             cmdp->u.screen.reserved  = 0;
  933.             cmdp->u.screen.su.msg.msg_handle= msg->msg_handle;
  934.             cmdp->u.screen.su.msg.msg_addr  = virt_to_bus(msg);
  935.             ha->scratch_busy = TRUE;
  936.             ha->cmd_offs_dpmem = 0;
  937.             ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) 
  938.                 + sizeof(ulong32);
  939.             ha->cmd_cnt = 0;
  940.             gdth_copy_command(hanum);
  941.             gdth_release_event(hanum);
  942.             return 0;
  943.         }
  944.         if (msg->msg_answer && msg->msg_alen) {
  945.             /* default answers (getchar() not possible) */
  946.             if (msg->msg_alen == 1) {
  947.                 msg->msg_alen = 0;
  948.                 msg->msg_len = 1;
  949.                 msg->msg_text[0] = 0;
  950.             } else {
  951.                 msg->msg_alen -= 2;
  952.                 msg->msg_len = 2;
  953.                 msg->msg_text[0] = 1;
  954.                 msg->msg_text[1] = 0;
  955.             }
  956.             msg->msg_ext    = 0;
  957.             msg->msg_answer = 0;
  958.             while (gdth_test_busy(hanum))
  959.                 gdth_delay(0);
  960.             cmdp->Service       = SCREENSERVICE;
  961.             cmdp->RequestBuffer = SCREEN_CMND;
  962.             gdth_get_cmd_index(hanum);
  963.             gdth_set_sema0(hanum);
  964.             cmdp->OpCode        = GDT_WRITE;
  965.             cmdp->BoardNode     = LOCALBOARD;
  966.             cmdp->u.screen.reserved  = 0;
  967.             cmdp->u.screen.su.msg.msg_handle= msg->msg_handle;
  968.             cmdp->u.screen.su.msg.msg_addr  = virt_to_bus(msg);
  969.             ha->scratch_busy = TRUE;
  970.             ha->cmd_offs_dpmem = 0;
  971.             ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) 
  972.                 + sizeof(ulong32);
  973.             ha->cmd_cnt = 0;
  974.             gdth_copy_command(hanum);
  975.             gdth_release_event(hanum);
  976.             return 0;
  977.         }
  978.         printk("n");
  979.     } else {
  980.         b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
  981.         if (scp->SCp.sent_command == -1 && b != ha->virt_bus) {
  982.             ha->raw[BUS_L2P(ha,b)].io_cnt[scp->target]--;
  983.         }
  984.         /* cache or raw service */
  985.         if (ha->status == S_OK) {
  986.             scp->SCp.Status = S_OK;
  987.             scp->SCp.Message = ha->info;
  988.             if (scp->SCp.sent_command != -1) {
  989.                 TRACE2(("gdth_sync_event(): special cmd 0x%x OKn",
  990.                         scp->SCp.sent_command));
  991.                 /* special commands GDT_CLUST_INFO/GDT_MOUNT ? */
  992.                 if (scp->SCp.sent_command == GDT_CLUST_INFO) {
  993.                     ha->hdr[scp->target].cluster_type = (unchar)ha->info;
  994.                     if (!(ha->hdr[scp->target].cluster_type & 
  995.                         CLUSTER_MOUNTED)) {
  996.                         /* NOT MOUNTED -> MOUNT */
  997.                         scp->SCp.sent_command = GDT_MOUNT;
  998.                         if (ha->hdr[scp->target].cluster_type & 
  999.                             CLUSTER_RESERVED) {
  1000.                             /* cluster drive RESERVED (on the other node) */
  1001.                             scp->SCp.phase = -2;      /* reservation conflict */
  1002.                         }
  1003.                     } else {
  1004.                         scp->SCp.sent_command = -1;
  1005.                     }
  1006.                 } else {
  1007.                     if (scp->SCp.sent_command == GDT_MOUNT) {
  1008.                         ha->hdr[scp->target].cluster_type |= CLUSTER_MOUNTED;
  1009.                         ha->hdr[scp->target].media_changed = TRUE;
  1010.                     } else if (scp->SCp.sent_command == GDT_UNMOUNT) {
  1011.                         ha->hdr[scp->target].cluster_type &= ~CLUSTER_MOUNTED;
  1012.                         ha->hdr[scp->target].media_changed = TRUE;
  1013.                     } 
  1014.                     scp->SCp.sent_command = -1;
  1015.                 }
  1016.                 /* retry */
  1017.                 scp->SCp.this_residual = HIGH_PRI;
  1018.                 return 2;
  1019.             } else {
  1020.                 /* RESERVE/RELEASE ? */
  1021.                 if (scp->cmnd[0] == RESERVE) {
  1022.                     ha->hdr[scp->target].cluster_type |= CLUSTER_RESERVED;
  1023.                 } else if (scp->cmnd[0] == RELEASE) {
  1024.                     ha->hdr[scp->target].cluster_type &= ~CLUSTER_RESERVED;
  1025.                 }           
  1026.                 scp->result = DID_OK << 16;
  1027.                 scp->sense_buffer[0] = 0;
  1028.             }
  1029.         } else if (ha->status == S_BSY) {
  1030.             TRACE2(("Controller busy -> retry !n"));
  1031.             scp->SCp.Status = S_BSY;
  1032.             scp->SCp.Message = ha->info;
  1033.             if (scp->SCp.sent_command == GDT_MOUNT)
  1034.                 scp->SCp.sent_command = GDT_CLUST_INFO;
  1035.             /* retry */
  1036.             return 2;
  1037.         } else {
  1038.             scp->SCp.Status = ha->status;
  1039.             scp->SCp.Message = ha->info;
  1040.             if (scp->SCp.sent_command != -1) {
  1041.                 TRACE2(("gdth_sync_event(): special cmd 0x%x error 0x%xn",
  1042.                         scp->SCp.sent_command, ha->status));
  1043.                 if (scp->SCp.sent_command == GDT_SCAN_START ||
  1044.                     scp->SCp.sent_command == GDT_SCAN_END) {
  1045.                     scp->SCp.sent_command = -1;
  1046.                     /* retry */
  1047.                     scp->SCp.this_residual = HIGH_PRI;
  1048.                     return 2;
  1049.                 }
  1050.                 memset((char*)scp->sense_buffer,0,16);
  1051.                 scp->sense_buffer[0] = 0x70;
  1052.                 scp->sense_buffer[2] = NOT_READY;
  1053.                 scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
  1054.             } else if (service == CACHESERVICE) {
  1055.                 if (ha->status == S_CACHE_UNKNOWN &&
  1056.                     (ha->hdr[scp->target].cluster_type & 
  1057.                      CLUSTER_RESERVE_STATE) == CLUSTER_RESERVE_STATE) {
  1058.                     /* bus reset -> force GDT_CLUST_INFO */
  1059.                     ha->hdr[scp->target].cluster_type &= ~CLUSTER_RESERVED;
  1060.                 }
  1061.                 memset((char*)scp->sense_buffer,0,16);
  1062.                 scp->sense_buffer[0] = 0x70;
  1063.                 scp->sense_buffer[2] = NOT_READY;
  1064.                 scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
  1065. #if LINUX_VERSION_CODE >= 0x010300
  1066.                 if (scp->done != gdth_scsi_done)
  1067. #endif  
  1068.                 {
  1069.                     ha->dvr.size = sizeof(ha->dvr.eu.sync);
  1070.                     ha->dvr.eu.sync.ionode  = hanum;
  1071.                     ha->dvr.eu.sync.service = service;
  1072.                     ha->dvr.eu.sync.status  = ha->status;
  1073.                     ha->dvr.eu.sync.info    = ha->info;
  1074.                     ha->dvr.eu.sync.hostdrive = scp->target;
  1075.                     if (ha->status >= 0x8000)
  1076.                         gdth_store_event(ha, ES_SYNC, 0, &ha->dvr);
  1077.                     else
  1078.                         gdth_store_event(ha, ES_SYNC, service, &ha->dvr);
  1079.                 }
  1080.             } else {
  1081.                 /* sense buffer filled from controller firmware (DMA) */
  1082.                 if (ha->status != S_RAW_SCSI || ha->info >= 0x100) {
  1083.                     scp->result = DID_BAD_TARGET << 16;
  1084.                 } else {
  1085.                     scp->result = (DID_OK << 16) | ha->info;
  1086.                 }
  1087.             }
  1088.         }
  1089.         if (!scp->SCp.have_data_in)
  1090.             scp->SCp.have_data_in++;
  1091.         else 
  1092.             return 1;
  1093.     }
  1094.     return 0;
  1095. }
  1096. static char *async_cache_tab[] = {
  1097. /* 0*/  "110002020204020604"
  1098.         "GDT HA %u, service %u, async. status %u/%lu unknown",
  1099. /* 1*/  "110002020204020604"
  1100.         "GDT HA %u, service %u, async. status %u/%lu unknown",
  1101. /* 2*/  "0500020604"
  1102.         "GDT HA %u, Host Drive %lu not ready",
  1103. /* 3*/  "0500020604"
  1104.         "GDT HA %u, Host Drive %lu: REASSIGN not successful and/or data error on reassigned blocks. Drive may crash in the future and should be replaced",
  1105. /* 4*/  "0500020604"
  1106.         "GDT HA %u, mirror update on Host Drive %lu failed",
  1107. /* 5*/  "0500020604"
  1108.         "GDT HA %u, Mirror Drive %lu failed",
  1109. /* 6*/  "0500020604"
  1110.         "GDT HA %u, Mirror Drive %lu: REASSIGN not successful and/or data error on reassigned blocks. Drive may crash in the future and should be replaced",
  1111. /* 7*/  "0500020604"
  1112.         "GDT HA %u, Host Drive %lu write protected",
  1113. /* 8*/  "0500020604"
  1114.         "GDT HA %u, media changed in Host Drive %lu",
  1115. /* 9*/  "0500020604"
  1116.         "GDT HA %u, Host Drive %lu is offline",
  1117. /*10*/  "0500020604"
  1118.         "GDT HA %u, media change of Mirror Drive %lu",
  1119. /*11*/  "0500020604"
  1120.         "GDT HA %u, Mirror Drive %lu is write protected",
  1121. /*12*/  "0500020604"
  1122.         "GDT HA %u, general error on Host Drive %lu. Please check the devices of this drive!",
  1123. /*13*/  "07000206021002"
  1124.         "GDT HA %u, Array Drive %u: Cache Drive %u failed",
  1125. /*14*/  "0500020602"
  1126.         "GDT HA %u, Array Drive %u: FAIL state entered",
  1127. /*15*/  "0500020602"
  1128.         "GDT HA %u, Array Drive %u: error",
  1129. /*16*/  "07000206021002"
  1130.         "GDT HA %u, Array Drive %u: failed drive replaced by Cache Drive %u",
  1131. /*17*/  "0500020602"
  1132.         "GDT HA %u, Array Drive %u: parity build failed",
  1133. /*18*/  "0500020602"
  1134.         "GDT HA %u, Array Drive %u: drive rebuild failed",
  1135. /*19*/  "0500021002"
  1136.         "GDT HA %u, Test of Hot Fix %u failed",
  1137. /*20*/  "0500020602"
  1138.         "GDT HA %u, Array Drive %u: drive build finished successfully",
  1139. /*21*/  "0500020602"
  1140.         "GDT HA %u, Array Drive %u: drive rebuild finished successfully",
  1141. /*22*/  "07000206021002"
  1142.         "GDT HA %u, Array Drive %u: Hot Fix %u activated",
  1143. /*23*/  "0500020602"
  1144.         "GDT HA %u, Host Drive %u: processing of i/o aborted due to serious drive error",
  1145. /*24*/  "0500021002"
  1146.         "GDT HA %u, mirror update on Cache Drive %u completed",
  1147. /*25*/  "0500021002"
  1148.         "GDT HA %u, mirror update on Cache Drive %lu failed",
  1149. /*26*/  "0500020602"
  1150.         "GDT HA %u, Array Drive %u: drive rebuild started",
  1151. /*27*/  "0500021201"
  1152.         "GDT HA %u, Fault bus %u: SHELF OK detected",
  1153. /*28*/  "0500021201"
  1154.         "GDT HA %u, Fault bus %u: SHELF not OK detected",
  1155. /*29*/  "07000212011301"
  1156.         "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug started",
  1157. /*30*/  "07000212011301"
  1158.         "GDT HA %u, Fault bus %u, ID %u: new disk detected",
  1159. /*31*/  "07000212011301"
  1160.         "GDT HA %u, Fault bus %u, ID %u: old disk detected",
  1161. /*32*/  "07000212011301"
  1162.         "GDT HA %u, Fault bus %u, ID %u: plugging an active disk is illegal",
  1163. /*33*/  "07000212011301"
  1164.         "GDT HA %u, Fault bus %u, ID %u: illegal device detected",
  1165. /*34*/  "110002120113010604"
  1166.         "GDT HA %u, Fault bus %u, ID %u: insufficient disk capacity (%lu MB required)",
  1167. /*35*/  "07000212011301"
  1168.         "GDT HA %u, Fault bus %u, ID %u: disk write protected",
  1169. /*36*/  "07000212011301"
  1170.         "GDT HA %u, Fault bus %u, ID %u: disk not available",
  1171. /*37*/  "07000212010604"
  1172.         "GDT HA %u, Fault bus %u: swap detected (%lu)",
  1173. /*38*/  "07000212011301"
  1174.         "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug finished successfully",
  1175. /*39*/  "07000212011301"
  1176.         "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug aborted due to user Hot Plug",
  1177. /*40*/  "07000212011301"
  1178.         "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug aborted",
  1179. /*41*/  "07000212011301"
  1180.         "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug for Hot Fix started",
  1181. /*42*/  "0500020602"
  1182.         "GDT HA %u, Array Drive %u: drive build started",
  1183. /*43*/  "030002"
  1184.         "GDT HA %u, DRAM parity error detected",
  1185. /*44*/  "0500020602"
  1186.         "GDT HA %u, Mirror Drive %u: update started",
  1187. /*45*/  "07000206021002"
  1188.         "GDT HA %u, Mirror Drive %u: Hot Fix %u activated",
  1189. /*46*/  "0500020602"
  1190.         "GDT HA %u, Array Drive %u: no matching Pool Hot Fix Drive available",
  1191. /*47*/  "0500020602"
  1192.         "GDT HA %u, Array Drive %u: Pool Hot Fix Drive available",
  1193. /*48*/  "0500020602"
  1194.         "GDT HA %u, Mirror Drive %u: no matching Pool Hot Fix Drive available",
  1195. /*49*/  "0500020602"
  1196.         "GDT HA %u, Mirror Drive %u: Pool Hot Fix Drive available",
  1197. /*50*/  "07000212011301"
  1198.         "GDT HA %u, SCSI bus %u, ID %u: IGNORE_WIDE_RESIDUE message received",
  1199. /*51*/  "0500020602"
  1200.         "GDT HA %u, Array Drive %u: expand started",
  1201. /*52*/  "0500020602"
  1202.         "GDT HA %u, Array Drive %u: expand finished successfully",
  1203. /*53*/  "0500020602"
  1204.         "GDT HA %u, Array Drive %u: expand failed",
  1205. /*54*/  "030002"
  1206.         "GDT HA %u, CPU temperature critical",
  1207. /*55*/  "030002"
  1208.         "GDT HA %u, CPU temperature OK",
  1209. /*56*/  "0500020604"
  1210.         "GDT HA %u, Host drive %lu created",
  1211. /*57*/  "0500020602"
  1212.         "GDT HA %u, Array Drive %u: expand restarted",
  1213. /*58*/  "0500020602"
  1214.         "GDT HA %u, Array Drive %u: expand stopped",
  1215. /*59*/  "0500021002"
  1216.         "GDT HA %u, Mirror Drive %u: drive build quited",
  1217. /*60*/  "0500020602"
  1218.         "GDT HA %u, Array Drive %u: parity build quited",
  1219. /*61*/  "0500020602"
  1220.         "GDT HA %u, Array Drive %u: drive rebuild quited",
  1221. /*62*/  "0500020602"
  1222.         "GDT HA %u, Array Drive %u: parity verify started",
  1223. /*63*/  "0500020602"
  1224.         "GDT HA %u, Array Drive %u: parity verify done",
  1225. /*64*/  "0500020602"
  1226.         "GDT HA %u, Array Drive %u: parity verify failed",
  1227. /*65*/  "0500020602"
  1228.         "GDT HA %u, Array Drive %u: parity error detected",
  1229. /*66*/  "0500020602"
  1230.         "GDT HA %u, Array Drive %u: parity verify quited",
  1231. /*67*/  "0500020602"
  1232.         "GDT HA %u, Host Drive %u reserved",
  1233. /*68*/  "0500020602"
  1234.         "GDT HA %u, Host Drive %u mounted and released",
  1235. /*69*/  "0500020602"
  1236.         "GDT HA %u, Host Drive %u released",
  1237. /*70*/  "030002"
  1238.         "GDT HA %u, DRAM error detected and corrected with ECC",
  1239. /*71*/  "030002"
  1240.         "GDT HA %u, Uncorrectable DRAM error detected with ECC",
  1241. /*72*/  "110002120113011401"
  1242.         "GDT HA %u, SCSI bus %u, ID %u, LUN %u: reassigning block",
  1243. /*73*/  "0500020602"
  1244.         "GDT HA %u, Host drive %u resetted locally",
  1245. /*74*/  "0500020602"
  1246.         "GDT HA %u, Host drive %u resetted remotely",
  1247. /*75*/  "030002"
  1248.         "GDT HA %u, async. status 75 unknown",
  1249. };
  1250. static int gdth_async_event(int hanum)
  1251. {
  1252.     gdth_ha_str *ha;
  1253.     gdth_msg_str *msg;
  1254.     gdth_cmd_str *cmdp;
  1255.     int cmd_index;
  1256.     ha  = HADATA(gdth_ctr_tab[hanum]);
  1257.     cmdp= ha->pccb;
  1258.     msg = (gdth_msg_str *)ha->pscratch;
  1259.     TRACE2(("gdth_async_event() ha %d serv %dn",
  1260.             hanum,ha->service));
  1261.     if (ha->service == SCREENSERVICE) {
  1262.         if (ha->status == MSG_REQUEST) {
  1263.             while (gdth_test_busy(hanum))
  1264.                 gdth_delay(0);
  1265.             cmdp->Service       = SCREENSERVICE;
  1266.             cmdp->RequestBuffer = SCREEN_CMND;
  1267.             cmd_index = gdth_get_cmd_index(hanum);
  1268.             gdth_set_sema0(hanum);
  1269.             cmdp->OpCode        = GDT_READ;
  1270.             cmdp->BoardNode     = LOCALBOARD;
  1271.             cmdp->u.screen.reserved  = 0;
  1272.             cmdp->u.screen.su.msg.msg_handle= MSG_INV_HANDLE;
  1273.             cmdp->u.screen.su.msg.msg_addr  = virt_to_bus(msg);
  1274.             ha->scratch_busy = TRUE;
  1275.             ha->cmd_offs_dpmem = 0;
  1276.             ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) 
  1277.                 + sizeof(ulong32);
  1278.             ha->cmd_cnt = 0;
  1279.             gdth_copy_command(hanum);
  1280.             if (ha->type == GDT_EISA)
  1281.                 printk("[EISA slot %d] ",(ushort)ha->brd_phys);
  1282.             else if (ha->type == GDT_ISA)
  1283.                 printk("[DPMEM 0x%4X] ",(ushort)ha->brd_phys);
  1284.             else 
  1285.                 printk("[PCI %d/%d] ",(ushort)(ha->brd_phys>>8),
  1286.                        (ushort)((ha->brd_phys>>3)&0x1f));
  1287.             gdth_release_event(hanum);
  1288.         }
  1289.     } else {
  1290.         if (ha->type == GDT_PCIMPR && 
  1291.             (ha->fw_vers & 0xff) >= 0x1a) {
  1292.             ha->dvr.size = 0;
  1293.             ha->dvr.eu.async.ionode = hanum;
  1294.             ha->dvr.eu.async.status  = ha->status;
  1295.             /* severity and event_string already set! */
  1296.         } else {        
  1297.             ha->dvr.size = sizeof(ha->dvr.eu.async);
  1298.             ha->dvr.eu.async.ionode   = hanum;
  1299.             ha->dvr.eu.async.service = ha->service;
  1300.             ha->dvr.eu.async.status  = ha->status;
  1301.             ha->dvr.eu.async.info    = ha->info;
  1302.             *(ulong32 *)ha->dvr.eu.async.scsi_coord  = ha->info2;
  1303.         }
  1304.         gdth_store_event( ha, ES_ASYNC, ha->service, &ha->dvr );
  1305.         gdth_log_event( &ha->dvr, NULL );
  1306.     
  1307.         /* new host drive from expand? */
  1308.         if (ha->service == CACHESERVICE && ha->status == 56) {
  1309.             TRACE2(("gdth_async_event(): new host drive %d createdn",
  1310.                     (ushort)ha->info));
  1311.             /* gdth_analyse_hdrive(hanum, (ushort)ha->info); */
  1312.         }   
  1313.     }
  1314.     return 1;
  1315. }
  1316. static void gdth_log_event(gdth_evt_data *dvr, char *buffer)
  1317. {
  1318.     gdth_stackframe stack;
  1319.     char *f = NULL;
  1320.     int i,j;
  1321.     TRACE2(("gdth_log_event()n"));
  1322.     if (dvr->size == 0) {
  1323.         if (buffer == NULL) {
  1324.             printk("Adapter %d: %sn",dvr->eu.async.ionode,dvr->event_string); 
  1325.         } else {
  1326.             sprintf(buffer,"Adapter %d: %sn",
  1327.                 dvr->eu.async.ionode,dvr->event_string); 
  1328.         }
  1329.     } else if (dvr->eu.async.service == CACHESERVICE && 
  1330.         INDEX_OK(dvr->eu.async.status, async_cache_tab)) {
  1331.         TRACE2(("GDT: Async. event cache service, event no.: %dn",
  1332.                 dvr->eu.async.status));
  1333.         
  1334.         f = async_cache_tab[dvr->eu.async.status];
  1335.         
  1336.         /* i: parameter to push, j: stack element to fill */
  1337.         for (j=0,i=1; i < f[0]; i+=2) {
  1338.             switch (f[i+1]) {
  1339.               case 4:
  1340.                 stack.b[j++] = *(ulong32*)&dvr->eu.stream[(int)f[i]];
  1341.                 break;
  1342.               case 2:
  1343.                 stack.b[j++] = *(ushort*)&dvr->eu.stream[(int)f[i]];
  1344.                 break;
  1345.               case 1:
  1346.                 stack.b[j++] = *(unchar*)&dvr->eu.stream[(int)f[i]];
  1347.                 break;
  1348.               default:
  1349.                 break;
  1350.             }
  1351.         }
  1352.         
  1353.         if (buffer == NULL) {
  1354.             printk(&f[(int)f[0]],stack); 
  1355.             printk("n");
  1356.         } else {
  1357.             sprintf(buffer,&f[(int)f[0]],stack); 
  1358.         }
  1359.     } else {
  1360.         if (buffer == NULL) {
  1361.             printk("GDT HA %u, Unknown async. event service %d event no. %dn",
  1362.                    dvr->eu.async.ionode,dvr->eu.async.service,dvr->eu.async.status);
  1363.         } else {
  1364.             sprintf(buffer,"GDT HA %u, Unknown async. event service %d event no. %d",
  1365.                     dvr->eu.async.ionode,dvr->eu.async.service,dvr->eu.async.status);
  1366.         }
  1367.     }
  1368. }
  1369. #ifdef GDTH_STATISTICS
  1370. void gdth_timeout(ulong data)
  1371. {
  1372.     ulong32 i;
  1373.     Scsi_Cmnd *nscp;
  1374.     gdth_ha_str *ha;
  1375.     ulong flags;
  1376.     int hanum = 0;
  1377.     ha = HADATA(gdth_ctr_tab[hanum]);
  1378.     GDTH_LOCK_HA(ha, flags);
  1379.     for (act_stats=0,i=0; i<GDTH_MAXCMDS; ++i) 
  1380.         if (ha->cmd_tab[i].cmnd != UNUSED_CMND)
  1381.             ++act_stats;
  1382.     for (act_rq=0,nscp=ha->req_first; nscp; nscp=(Scsi_Cmnd*)nscp->SCp.ptr)
  1383.         ++act_rq;
  1384.     TRACE2(("gdth_to(): ints %d, ios %d, act_stats %d, act_rq %dn",
  1385.             act_ints, act_ios, act_stats, act_rq));
  1386.     act_ints = act_ios = 0;
  1387.     gdth_timer.expires = jiffies + 30 * HZ;
  1388.     add_timer(&gdth_timer);
  1389.     GDTH_UNLOCK_HA(ha, flags);
  1390. }
  1391. #endif
  1392. GDTH_INITFUNC(void, internal_setup(char *str,int *ints))
  1393. {
  1394.     int i, argc;
  1395.     char *cur_str, *argv;
  1396.     TRACE2(("internal_setup() str %s ints[0] %dn", 
  1397.             str ? str:"NULL", ints ? ints[0]:0));
  1398.     /* read irq[] from ints[] */
  1399.     if (ints) {
  1400.         argc = ints[0];
  1401.         if (argc > 0) {
  1402.             if (argc > MAXHA)
  1403.                 argc = MAXHA;
  1404.             for (i = 0; i < argc; ++i)
  1405.                 irq[i] = ints[i+1];
  1406.         }
  1407.     }
  1408.     /* analyse string */
  1409.     argv = str;
  1410.     while (argv && (cur_str = strchr(argv, ':'))) {
  1411.         int val = 0, c = *++cur_str;
  1412.         
  1413.         if (c == 'n' || c == 'N')
  1414.             val = 0;
  1415.         else if (c == 'y' || c == 'Y')
  1416.             val = 1;
  1417.         else
  1418.             val = (int)simple_strtoul(cur_str, NULL, 0);
  1419.         if (!strncmp(argv, "disable:", 8))
  1420.             disable = val;
  1421.         else if (!strncmp(argv, "reserve_mode:", 13))
  1422.             reserve_mode = val;
  1423.         else if (!strncmp(argv, "reverse_scan:", 13))
  1424.             reverse_scan = val;
  1425.         else if (!strncmp(argv, "hdr_channel:", 12))
  1426.             hdr_channel = val;
  1427.         else if (!strncmp(argv, "max_ids:", 8))
  1428.             max_ids = val;
  1429.         else if (!strncmp(argv, "rescan:", 7))
  1430.             rescan = val;
  1431.         else if (!strncmp(argv, "virt_ctr:", 9))
  1432.             virt_ctr = val;
  1433.         else if (!strncmp(argv, "shared_access:", 14))
  1434.             shared_access = val;
  1435.         else if (!strncmp(argv, "reserve_list:", 13)) {
  1436.             reserve_list[0] = val;
  1437.             for (i = 1; i < MAX_RES_ARGS; i++) {
  1438.                 cur_str = strchr(cur_str, ',');
  1439.                 if (!cur_str)
  1440.                     break;
  1441.                 if (!isdigit((int)*++cur_str)) {
  1442.                     --cur_str;          
  1443.                     break;
  1444.                 }
  1445.                 reserve_list[i] = 
  1446.                     (int)simple_strtoul(cur_str, NULL, 0);
  1447.             }
  1448.             if (!cur_str)
  1449.                 break;
  1450.             argv = ++cur_str;
  1451.             continue;
  1452.         }
  1453.         if ((argv = strchr(argv, ',')))
  1454.             ++argv;
  1455.     }
  1456. }
  1457. GDTH_INITFUNC(int, option_setup(char *str))
  1458. {
  1459.     int ints[MAXHA];
  1460.     char *cur = str;
  1461.     int i = 1;
  1462.     TRACE2(("option_setup() str %sn", str ? str:"NULL")); 
  1463.     while (cur && isdigit(*cur) && i <= MAXHA) {
  1464.         ints[i++] = simple_strtoul(cur, NULL, 0);
  1465.         if ((cur = strchr(cur, ',')) != NULL) cur++;
  1466.     }
  1467.     ints[0] = i - 1;
  1468.     internal_setup(cur, ints);
  1469.     return 1;
  1470. }
  1471. GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
  1472. {
  1473.     struct Scsi_Host *shp;
  1474.     gdth_ha_str *ha;
  1475.     ulong32 isa_bios;
  1476.     ushort eisa_slot;
  1477.     int i,hanum,cnt,ctr;
  1478.     unchar b;
  1479.     
  1480.  
  1481. #ifdef DEBUG_GDTH
  1482.     printk("GDT: This driver contains debugging information !! Trace level = %dn",
  1483.         DebugState);
  1484.     printk("     Destination of debugging information: ");
  1485. #ifdef __SERIAL__
  1486. #ifdef __COM2__
  1487.     printk("Serial port COM2n");
  1488. #else
  1489.     printk("Serial port COM1n");
  1490. #endif
  1491. #else
  1492.     printk("Consolen");
  1493. #endif
  1494.     gdth_delay(3000);
  1495. #endif
  1496.     TRACE(("gdth_detect()n"));
  1497.     if (disable) {
  1498.         printk("GDT: Controller driver disabled from command line !n");
  1499.         return 0;
  1500.     }
  1501.     /* initializations */
  1502.     gdth_polling = TRUE; b = 0;
  1503.     gdth_clear_events();
  1504.     /* scanning for controllers, at first: ISA controller */
  1505.     for (isa_bios=0xc8000UL; isa_bios<=0xd8000UL; isa_bios+=0x8000UL) {
  1506.         if (gdth_ctr_count >= MAXHA) 
  1507.             break;
  1508.         if (gdth_search_isa(isa_bios)) {        /* controller found */
  1509.             shp = scsi_register(shtp,sizeof(gdth_ext_str));
  1510.             ha = HADATA(shp);
  1511.             if (!gdth_init_isa(isa_bios,ha)) {
  1512.                 scsi_unregister(shp);
  1513.                 continue;
  1514.             }
  1515. #ifdef __ia64__
  1516.             break;
  1517. #else
  1518.             /* controller found and initialized */
  1519.             printk("Configuring GDT-ISA HA at BIOS 0x%05X IRQ %u DRQ %un",
  1520.                    isa_bios,ha->irq,ha->drq);
  1521. #if LINUX_VERSION_CODE >= 0x010346 
  1522.             if (request_irq(ha->irq,gdth_interrupt,SA_INTERRUPT,"gdth",ha))
  1523. #else
  1524.             if (request_irq(ha->irq,gdth_interrupt,SA_INTERRUPT,"gdth")) 
  1525. #endif
  1526.             {
  1527.                 printk("GDT-ISA: Unable to allocate IRQn");
  1528.                 scsi_unregister(shp);
  1529.                 continue;
  1530.             }
  1531.             if (request_dma(ha->drq,"gdth")) {
  1532.                 printk("GDT-ISA: Unable to allocate DMA channeln");
  1533. #if LINUX_VERSION_CODE >= 0x010346 
  1534.                 free_irq(ha->irq,ha);
  1535. #else
  1536.                 free_irq(ha->irq);
  1537. #endif
  1538.                 scsi_unregister(shp);
  1539.                 continue;
  1540.             }
  1541.             set_dma_mode(ha->drq,DMA_MODE_CASCADE);
  1542.             enable_dma(ha->drq);
  1543.             shp->unchecked_isa_dma = 1;
  1544.             shp->irq = ha->irq;
  1545.             shp->dma_channel = ha->drq;
  1546.             hanum = gdth_ctr_count;         
  1547.             gdth_ctr_tab[gdth_ctr_count++] = shp;
  1548.             gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
  1549.             NUMDATA(shp)->hanum = (ushort)hanum;
  1550.             NUMDATA(shp)->busnum= 0;
  1551.             ha->pccb = CMDDATA(shp);
  1552. #if LINUX_VERSION_CODE >= 0x020322
  1553.             ha->pscratch = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, 
  1554.                                                      GDTH_SCRATCH_ORD);
  1555. #else
  1556.             ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
  1557. #endif
  1558.             ha->scratch_busy = FALSE;
  1559.             ha->req_first = NULL;
  1560.             ha->tid_cnt = MAX_HDRIVES;
  1561.             if (max_ids > 0 && max_ids < ha->tid_cnt)
  1562.                 ha->tid_cnt = max_ids;
  1563.             for (i=0; i<GDTH_MAXCMDS; ++i)
  1564.                 ha->cmd_tab[i].cmnd = UNUSED_CMND;
  1565.             ha->scan_mode = rescan ? 0x10 : 0;
  1566.             if (ha->pscratch == NULL || !gdth_search_drives(hanum)) {
  1567.                 printk("GDT-ISA: Error during device scann");
  1568.                 --gdth_ctr_count;
  1569.                 --gdth_ctr_vcount;
  1570.                 if (ha->pscratch != NULL)
  1571. #if LINUX_VERSION_CODE >= 0x020322
  1572.                     free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD);
  1573. #else
  1574.                     scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
  1575. #endif
  1576. #if LINUX_VERSION_CODE >= 0x010346 
  1577.                 free_irq(ha->irq,ha);
  1578. #else
  1579.                 free_irq(ha->irq);
  1580. #endif
  1581.                 scsi_unregister(shp);
  1582.                 continue;
  1583.             }
  1584.             if (hdr_channel < 0 || hdr_channel > ha->bus_cnt)
  1585.                 hdr_channel = ha->bus_cnt;
  1586.             ha->virt_bus = hdr_channel;
  1587. #if LINUX_VERSION_CODE >= 0x020000
  1588.             shp->max_id      = ha->tid_cnt;
  1589.             shp->max_lun     = MAXLUN;
  1590.             shp->max_channel = virt_ctr ? 0 : ha->bus_cnt;
  1591.             if (virt_ctr)  
  1592. #endif
  1593.             {
  1594.                 virt_ctr = 1;
  1595.                 /* register addit. SCSI channels as virtual controllers */
  1596.                 for (b = 1; b < ha->bus_cnt + 1; ++b) {
  1597.                     shp = scsi_register(shtp,sizeof(gdth_num_str));
  1598.                     shp->unchecked_isa_dma = 1;
  1599.                     shp->irq = ha->irq;
  1600.                     shp->dma_channel = ha->drq;
  1601.                     gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
  1602.                     NUMDATA(shp)->hanum = (ushort)hanum;
  1603.                     NUMDATA(shp)->busnum = b;
  1604.                 }
  1605.             }  
  1606.             GDTH_INIT_LOCK_HA(ha);
  1607.             gdth_enable_int(hanum);
  1608. #endif /* !__ia64__ */
  1609.         }
  1610.     }
  1611.     /* scanning for EISA controllers */
  1612.     for (eisa_slot=0x1000; eisa_slot<=0x8000; eisa_slot+=0x1000) {
  1613.         if (gdth_ctr_count >= MAXHA) 
  1614.             break;
  1615.         if (gdth_search_eisa(eisa_slot)) {      /* controller found */
  1616.             shp = scsi_register(shtp,sizeof(gdth_ext_str));
  1617.             ha = HADATA(shp);
  1618.             if (!gdth_init_eisa(eisa_slot,ha)) {
  1619.                 scsi_unregister(shp);
  1620.                 continue;
  1621.             }
  1622.             /* controller found and initialized */
  1623.             printk("Configuring GDT-EISA HA at Slot %d IRQ %un",
  1624.                    eisa_slot>>12,ha->irq);
  1625. #if LINUX_VERSION_CODE >= 0x010346 
  1626.             if (request_irq(ha->irq,gdth_interrupt,SA_INTERRUPT,"gdth",ha))
  1627. #else
  1628.             if (request_irq(ha->irq,gdth_interrupt,SA_INTERRUPT,"gdth")) 
  1629. #endif
  1630.             {
  1631.                 printk("GDT-EISA: Unable to allocate IRQn");
  1632.                 scsi_unregister(shp);
  1633.                 continue;
  1634.             }
  1635.             shp->unchecked_isa_dma = 0;
  1636.             shp->irq = ha->irq;
  1637.             shp->dma_channel = 0xff;
  1638.             hanum = gdth_ctr_count;
  1639.             gdth_ctr_tab[gdth_ctr_count++] = shp;
  1640.             gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
  1641.             NUMDATA(shp)->hanum = (ushort)hanum;
  1642.             NUMDATA(shp)->busnum= 0;
  1643.             TRACE2(("EISA detect Bus 0: hanum %dn",
  1644.                     NUMDATA(shp)->hanum));
  1645.             ha->pccb = CMDDATA(shp);
  1646. #if LINUX_VERSION_CODE >= 0x020322
  1647.             ha->pscratch = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, 
  1648.                                                      GDTH_SCRATCH_ORD);
  1649. #else
  1650.             ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
  1651. #endif
  1652.             ha->scratch_busy = FALSE;
  1653.             ha->req_first = NULL;
  1654.             ha->tid_cnt = MAX_HDRIVES;
  1655.             if (max_ids > 0 && max_ids < ha->tid_cnt)
  1656.                 ha->tid_cnt = max_ids;
  1657.             for (i=0; i<GDTH_MAXCMDS; ++i)
  1658.                 ha->cmd_tab[i].cmnd = UNUSED_CMND;
  1659.             ha->scan_mode = rescan ? 0x10 : 0;
  1660.             if (ha->pscratch == NULL || !gdth_search_drives(hanum)) {
  1661.                 printk("GDT-EISA: Error during device scann");
  1662.                 --gdth_ctr_count;
  1663.                 --gdth_ctr_vcount;
  1664.                 if (ha->pscratch != NULL)
  1665. #if LINUX_VERSION_CODE >= 0x020322
  1666.                     free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD);
  1667. #else
  1668.                     scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
  1669. #endif
  1670. #if LINUX_VERSION_CODE >= 0x010346 
  1671.                 free_irq(ha->irq,ha);
  1672. #else
  1673.                 free_irq(ha->irq);
  1674. #endif
  1675.                 scsi_unregister(shp);
  1676.                 continue;
  1677.             }
  1678.             if (hdr_channel < 0 || hdr_channel > ha->bus_cnt)
  1679.                 hdr_channel = ha->bus_cnt;
  1680.             ha->virt_bus = hdr_channel;
  1681. #if LINUX_VERSION_CODE >= 0x020000
  1682.             shp->max_id      = ha->tid_cnt;
  1683.             shp->max_lun     = MAXLUN;
  1684.             shp->max_channel = virt_ctr ? 0 : ha->bus_cnt;
  1685.             if (virt_ctr)  
  1686. #endif
  1687.             {
  1688.                 virt_ctr = 1;
  1689.                 /* register addit. SCSI channels as virtual controllers */
  1690.                 for (b = 1; b < ha->bus_cnt + 1; ++b) {
  1691.                     shp = scsi_register(shtp,sizeof(gdth_num_str));
  1692.                     shp->unchecked_isa_dma = 0;
  1693.                     shp->irq = ha->irq;
  1694.                     shp->dma_channel = 0xff;
  1695.                     gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
  1696.                     NUMDATA(shp)->hanum = (ushort)hanum;
  1697.                     NUMDATA(shp)->busnum = b;
  1698.                 }
  1699.             }  
  1700.             GDTH_INIT_LOCK_HA(ha);
  1701.             gdth_enable_int(hanum);
  1702.         }
  1703.     }
  1704.     /* scanning for PCI controllers */
  1705. #if LINUX_VERSION_CODE >= 0x2015C
  1706.     if (pci_present())
  1707. #else
  1708.     if (pcibios_present())
  1709. #endif
  1710.     {
  1711.         gdth_pci_str pcistr[MAXHA];
  1712.         cnt = gdth_search_pci(pcistr);
  1713.         gdth_sort_pci(pcistr,cnt);
  1714.         for (ctr = 0; ctr < cnt; ++ctr) {
  1715.             if (gdth_ctr_count >= MAXHA)
  1716.                 break;
  1717.             shp = scsi_register(shtp,sizeof(gdth_ext_str));
  1718.             ha = HADATA(shp);
  1719.             if (!gdth_init_pci(&pcistr[ctr],ha)) {
  1720.                 scsi_unregister(shp);
  1721.                 continue;
  1722.             }
  1723.             /* controller found and initialized */
  1724.             printk("Configuring GDT-PCI HA at %d/%d IRQ %un",
  1725.                    pcistr[ctr].bus,PCI_SLOT(pcistr[ctr].device_fn),ha->irq);
  1726. #if LINUX_VERSION_CODE >= 0x010346 
  1727.             if (request_irq(ha->irq, gdth_interrupt,
  1728.                             SA_INTERRUPT|SA_SHIRQ, "gdth", ha))
  1729. #else
  1730.             if (request_irq(ha->irq, gdth_interrupt,
  1731.                             SA_INTERRUPT|SA_SHIRQ, "gdth")) 
  1732. #endif
  1733.             {
  1734.                 printk("GDT-PCI: Unable to allocate IRQn");
  1735.                 scsi_unregister(shp);
  1736.                 continue;
  1737.             }
  1738.             shp->unchecked_isa_dma = 0;
  1739.             shp->irq = ha->irq;
  1740.             shp->dma_channel = 0xff;
  1741.             hanum = gdth_ctr_count;
  1742.             gdth_ctr_tab[gdth_ctr_count++] = shp;
  1743.             gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
  1744.             NUMDATA(shp)->hanum = (ushort)hanum;
  1745.             NUMDATA(shp)->busnum= 0;
  1746.             ha->pccb = CMDDATA(shp);
  1747. #if LINUX_VERSION_CODE >= 0x020322
  1748.             ha->pscratch = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, 
  1749.                                                      GDTH_SCRATCH_ORD);
  1750. #else
  1751.             ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
  1752. #endif
  1753.             ha->scratch_busy = FALSE;
  1754.             ha->req_first = NULL;
  1755.             ha->tid_cnt = pcistr[ctr].device_id >= 0x200 ? MAXID : MAX_HDRIVES;
  1756.             if (max_ids > 0 && max_ids < ha->tid_cnt)
  1757.                 ha->tid_cnt = max_ids;
  1758.             for (i=0; i<GDTH_MAXCMDS; ++i)
  1759.                 ha->cmd_tab[i].cmnd = UNUSED_CMND;
  1760.             ha->scan_mode = rescan ? 0x10 : 0;
  1761.             if (ha->pscratch == NULL || !gdth_search_drives(hanum)) {
  1762.                 printk("GDT-PCI: Error during device scann");
  1763.                 --gdth_ctr_count;
  1764.                 --gdth_ctr_vcount;
  1765.                 if (ha->pscratch != NULL)
  1766. #if LINUX_VERSION_CODE >= 0x020322
  1767.                     free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD);
  1768. #else
  1769.                     scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
  1770. #endif
  1771. #if LINUX_VERSION_CODE >= 0x010346 
  1772.                 free_irq(ha->irq,ha);
  1773. #else
  1774.                 free_irq(ha->irq);
  1775. #endif
  1776.                 scsi_unregister(shp);
  1777.                 continue;
  1778.             }
  1779.             if (hdr_channel < 0 || hdr_channel > ha->bus_cnt)
  1780.                 hdr_channel = ha->bus_cnt;
  1781.             ha->virt_bus = hdr_channel;
  1782. #if LINUX_VERSION_CODE >= 0x020000
  1783.             shp->max_id      = ha->tid_cnt;
  1784.             shp->max_lun     = MAXLUN;
  1785.             shp->max_channel = virt_ctr ? 0 : ha->bus_cnt;
  1786.             if (virt_ctr)  
  1787. #endif
  1788.             {
  1789.                 virt_ctr = 1;
  1790.                 /* register addit. SCSI channels as virtual controllers */
  1791.                 for (b = 1; b < ha->bus_cnt + 1; ++b) {
  1792.                     shp = scsi_register(shtp,sizeof(gdth_num_str));
  1793.                     shp->unchecked_isa_dma = 0;
  1794.                     shp->irq = ha->irq;
  1795.                     shp->dma_channel = 0xff;
  1796.                     gdth_ctr_vtab[gdth_ctr_vcount++] = shp;
  1797.                     NUMDATA(shp)->hanum = (ushort)hanum;
  1798.                     NUMDATA(shp)->busnum = b;
  1799.                 }
  1800.             }  
  1801.             GDTH_INIT_LOCK_HA(ha);
  1802.             gdth_enable_int(hanum);
  1803.         }
  1804.     }
  1805.     TRACE2(("gdth_detect() %d controller detectedn",gdth_ctr_count));
  1806.     if (gdth_ctr_count > 0) {
  1807. #ifdef GDTH_STATISTICS
  1808.         TRACE2(("gdth_detect(): Initializing timer !n"));
  1809.         init_timer(&gdth_timer);
  1810.         gdth_timer.expires = jiffies + HZ;
  1811.         gdth_timer.data = 0L;
  1812.         gdth_timer.function = gdth_timeout;
  1813.         add_timer(&gdth_timer);
  1814. #endif
  1815. #if LINUX_VERSION_CODE >= 0x020100
  1816.         register_reboot_notifier(&gdth_notifier);
  1817. #endif
  1818.     }
  1819.     gdth_polling = FALSE;
  1820.     return gdth_ctr_vcount;
  1821. }
  1822. int gdth_release(struct Scsi_Host *shp)
  1823. {
  1824.     int hanum;
  1825.     gdth_ha_str *ha;
  1826.     TRACE2(("gdth_release()n"));
  1827.     if (NUMDATA(shp)->busnum == 0) {
  1828.         hanum = NUMDATA(shp)->hanum;
  1829.         ha    = HADATA(gdth_ctr_tab[hanum]);
  1830. #if LINUX_VERSION_CODE >= 0x010300
  1831.         gdth_flush(hanum);
  1832. #endif
  1833.         if (shp->irq) {
  1834. #if LINUX_VERSION_CODE >= 0x010346
  1835.             free_irq(shp->irq,ha);
  1836. #else
  1837.             free_irq(shp->irq);
  1838. #endif
  1839.         }
  1840. #ifndef __ia64__
  1841.         if (shp->dma_channel != 0xff) {
  1842.             free_dma(shp->dma_channel);
  1843.         }
  1844. #endif
  1845. #if LINUX_VERSION_CODE >= 0x020322
  1846.         free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD);
  1847. #else
  1848.         scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
  1849. #endif
  1850.         gdth_ctr_released++;
  1851.         TRACE2(("gdth_release(): HA %d of %dn", 
  1852.                 gdth_ctr_released, gdth_ctr_count));
  1853.         if (gdth_ctr_released == gdth_ctr_count) {
  1854. #ifdef GDTH_STATISTICS
  1855.             del_timer(&gdth_timer);
  1856. #endif
  1857. #if LINUX_VERSION_CODE >= 0x020100
  1858.             unregister_reboot_notifier(&gdth_notifier);
  1859. #endif
  1860.         }
  1861.     }
  1862.     scsi_unregister(shp);
  1863.     return 0;
  1864. }
  1865.             
  1866. static const char *gdth_ctr_name(int hanum)
  1867. {
  1868.     gdth_ha_str *ha;
  1869.     TRACE2(("gdth_ctr_name()n"));
  1870.     ha    = HADATA(gdth_ctr_tab[hanum]);
  1871.     if (ha->type == GDT_EISA) {
  1872.         switch (ha->stype) {
  1873.           case GDT3_ID:
  1874.             return("GDT3000/3020");
  1875.           case GDT3A_ID:
  1876.             return("GDT3000A/3020A/3050A");
  1877.           case GDT3B_ID:
  1878.             return("GDT3000B/3010A");
  1879.         }
  1880.     } else if (ha->type == GDT_ISA) {
  1881.         return("GDT2000/2020");
  1882.     } else if (ha->type == GDT_PCI) {
  1883.         switch (ha->stype) {
  1884.           case PCI_DEVICE_ID_VORTEX_GDT60x0:
  1885.             return("GDT6000/6020/6050");
  1886.           case PCI_DEVICE_ID_VORTEX_GDT6000B:
  1887.             return("GDT6000B/6010");
  1888.         }
  1889.     } 
  1890.     /* new controllers (GDT_PCINEW, GDT_PCIMPR, ..) use board_info IOCTL! */
  1891.     return("");
  1892. }
  1893. const char *gdth_info(struct Scsi_Host *shp)
  1894. {
  1895.     int hanum;
  1896.     gdth_ha_str *ha;
  1897.     TRACE2(("gdth_info()n"));
  1898.     hanum = NUMDATA(shp)->hanum;
  1899.     ha    = HADATA(gdth_ctr_tab[hanum]);
  1900.     return ((const char *)ha->binfo.type_string);
  1901. }
  1902. /* old error handling */
  1903. int gdth_abort(Scsi_Cmnd *scp)
  1904. {
  1905.     TRACE2(("gdth_abort() reason %dn",scp->abort_reason));
  1906.     return SCSI_ABORT_SNOOZE;
  1907. }
  1908. #if LINUX_VERSION_CODE >= 0x010346
  1909. int gdth_reset(Scsi_Cmnd *scp, unsigned int reset_flags)
  1910. #else
  1911. int gdth_reset(Scsi_Cmnd *scp)
  1912. #endif
  1913. {
  1914.     TRACE2(("gdth_reset()n"));
  1915.     return SCSI_RESET_PUNT;
  1916. }
  1917. #if LINUX_VERSION_CODE >= 0x02015F
  1918. /* new error handling */
  1919. int gdth_eh_abort(Scsi_Cmnd *scp)
  1920. {
  1921.     TRACE2(("gdth_eh_abort()n"));
  1922.     return FAILED;
  1923. }
  1924. int gdth_eh_device_reset(Scsi_Cmnd *scp)
  1925. {
  1926.     TRACE2(("gdth_eh_device_reset()n"));
  1927.     return FAILED;
  1928. }
  1929. int gdth_eh_bus_reset(Scsi_Cmnd *scp)
  1930. {
  1931.     int i, hanum;
  1932.     gdth_ha_str *ha;
  1933.     ulong flags;
  1934.     Scsi_Cmnd *cmnd;
  1935.     unchar b;
  1936.     TRACE2(("gdth_eh_bus_reset()n"));
  1937.     hanum = NUMDATA(scp->host)->hanum;
  1938.     b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
  1939.     ha    = HADATA(gdth_ctr_tab[hanum]);
  1940.     /* clear command tab */
  1941.     GDTH_LOCK_HA(ha, flags);
  1942.     for (i = 0; i < GDTH_MAXCMDS; ++i) {
  1943.         cmnd = ha->cmd_tab[i].cmnd;
  1944.         if (!SPECIAL_SCP(cmnd) && cmnd->channel == b)
  1945.             ha->cmd_tab[i].cmnd = UNUSED_CMND;
  1946.     }
  1947.     GDTH_UNLOCK_HA(ha, flags);
  1948.     if (b == ha->virt_bus) {
  1949.         /* host drives */
  1950.         for (i = 0; i < MAX_HDRIVES; ++i) {
  1951.             if (ha->hdr[i].present) {
  1952.                 GDTH_LOCK_HA(ha, flags);
  1953.                 gdth_polling = TRUE;
  1954.                 while (gdth_test_busy(hanum))
  1955.                     gdth_delay(0);
  1956.                 if (gdth_internal_cmd(hanum, CACHESERVICE, 
  1957.                                       GDT_CLUST_RESET, i, 0, 0))
  1958.                     ha->hdr[i].cluster_type &= ~CLUSTER_RESERVED;
  1959.                 gdth_polling = FALSE;
  1960.                 GDTH_UNLOCK_HA(ha, flags);
  1961.             }
  1962.         }
  1963.     } else {
  1964.         /* raw devices */
  1965.         GDTH_LOCK_HA(ha, flags);
  1966.         for (i = 0; i < MAXID; ++i)
  1967.             ha->raw[BUS_L2P(ha,b)].io_cnt[i] = 0;
  1968.         gdth_polling = TRUE;
  1969.         while (gdth_test_busy(hanum))
  1970.             gdth_delay(0);
  1971.         gdth_internal_cmd(hanum, SCSIRAWSERVICE, GDT_RESET_BUS,
  1972.                           BUS_L2P(ha,b), 0, 0);
  1973.         gdth_polling = FALSE;
  1974.         GDTH_UNLOCK_HA(ha, flags);
  1975.     }
  1976.     return SUCCESS;
  1977. }
  1978. int gdth_eh_host_reset(Scsi_Cmnd *scp)
  1979. {
  1980.     TRACE2(("gdth_eh_host_reset()n"));
  1981.     return FAILED;
  1982. }
  1983. #endif
  1984. #if LINUX_VERSION_CODE >= 0x010300
  1985. int gdth_bios_param(Disk *disk,kdev_t dev,int *ip)
  1986. #else
  1987. int gdth_bios_param(Disk *disk,int dev,int *ip)
  1988. #endif
  1989. {
  1990.     unchar b, t;
  1991.     int hanum;
  1992.     gdth_ha_str *ha;
  1993.     hanum = NUMDATA(disk->device->host)->hanum;
  1994.     b = virt_ctr ? NUMDATA(disk->device->host)->busnum : disk->device->channel;
  1995.     t = disk->device->id;
  1996.     TRACE2(("gdth_bios_param() ha %d bus %d target %dn", hanum, b, t)); 
  1997.     ha = HADATA(gdth_ctr_tab[hanum]);
  1998.     if (b != ha->virt_bus || ha->hdr[t].heads == 0) {
  1999.         /* raw device or host drive without mapping information */
  2000.         TRACE2(("Evaluate mappingn"));
  2001.         gdth_eval_mapping(disk->capacity,&ip[2],&ip[0],&ip[1]);
  2002.     } else {
  2003.         ip[0] = ha->hdr[t].heads;
  2004.         ip[1] = ha->hdr[t].secs;
  2005.         ip[2] = disk->capacity / ip[0] / ip[1];
  2006.     }
  2007.     TRACE2(("gdth_bios_param(): %d heads, %d secs, %d cylsn",
  2008.             ip[0],ip[1],ip[2]));
  2009.     return 0;
  2010. }
  2011. int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *))
  2012. {
  2013.     int hanum;
  2014.     int priority;
  2015.     TRACE(("gdth_queuecommand() cmd 0x%x id %d lun %dn",
  2016.            scp->cmnd[0],scp->target,scp->lun));
  2017.     
  2018.     scp->scsi_done = (void *)done;
  2019.     scp->SCp.have_data_in = 1;
  2020.     scp->SCp.phase = -1;
  2021.     scp->SCp.sent_command = -1;
  2022.     hanum = NUMDATA(scp->host)->hanum;
  2023. #ifdef GDTH_STATISTICS
  2024.     ++act_ios;
  2025. #endif
  2026.     priority = DEFAULT_PRI;
  2027. #if LINUX_VERSION_CODE >= 0x010300
  2028.     if (scp->done == gdth_scsi_done)
  2029.         priority = scp->SCp.this_residual;
  2030. #endif
  2031.     gdth_update_timeout(hanum, scp, scp->timeout_per_command * 6);
  2032.     gdth_putq( hanum, scp, priority );
  2033.     gdth_next( hanum );
  2034.     return 0;
  2035. }
  2036. #if LINUX_VERSION_CODE >= 0x010300
  2037. /* flush routine */
  2038. static void gdth_flush(int hanum)
  2039. {
  2040.     int             i;
  2041.     gdth_ha_str     *ha;
  2042.     gdth_cmd_str    gdtcmd;
  2043. #if LINUX_VERSION_CODE >= 0x020322
  2044.     Scsi_Cmnd       *scp;
  2045.     Scsi_Device     *sdev;
  2046. #else
  2047.     Scsi_Cmnd       scp;
  2048.     Scsi_Device     sdev;
  2049. #endif
  2050.     char            cmnd[MAX_COMMAND_SIZE];   
  2051.     memset(cmnd, 0xff, MAX_COMMAND_SIZE);
  2052.     TRACE2(("gdth_flush() hanum %dn",hanum));
  2053.     ha = HADATA(gdth_ctr_tab[hanum]);
  2054. #if LINUX_VERSION_CODE >= 0x020322
  2055.     sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
  2056.     scp  = scsi_allocate_device(sdev, 1, FALSE);
  2057.     scp->cmd_len = 12;
  2058.     scp->use_sg = 0;
  2059. #else
  2060.     memset(&sdev,0,sizeof(Scsi_Device));
  2061.     memset(&scp, 0,sizeof(Scsi_Cmnd));
  2062.     sdev.host = scp.host = gdth_ctr_tab[hanum];
  2063.     sdev.id = scp.target = sdev.host->this_id;
  2064.     scp.device = &sdev;
  2065. #endif
  2066.     for (i = 0; i < MAX_HDRIVES; ++i) {
  2067.         if (ha->hdr[i].present) {
  2068.             gdtcmd.BoardNode = LOCALBOARD;
  2069.             gdtcmd.Service = CACHESERVICE;
  2070.             gdtcmd.OpCode = GDT_FLUSH;
  2071.             gdtcmd.u.cache.DeviceNo = i;
  2072.             gdtcmd.u.cache.BlockNo = 1;
  2073.             gdtcmd.u.cache.sg_canz = 0;
  2074.             TRACE2(("gdth_flush(): flush ha %d drive %dn", hanum, i));
  2075. #if LINUX_VERSION_CODE >= 0x020322
  2076.             gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
  2077. #else
  2078.             gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
  2079. #endif
  2080.         }
  2081.     }
  2082. #if LINUX_VERSION_CODE >= 0x020322
  2083.     scsi_release_command(scp);
  2084.     scsi_free_host_dev(sdev);
  2085. #endif
  2086. }
  2087. /* shutdown routine */
  2088. #if LINUX_VERSION_CODE >= 0x020100
  2089. static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
  2090. #else
  2091. void gdth_halt(void)
  2092. #endif
  2093. {
  2094.     int             hanum;
  2095. #ifndef __alpha__
  2096.     gdth_cmd_str    gdtcmd;
  2097. #if LINUX_VERSION_CODE >= 0x020322
  2098.     Scsi_Cmnd       *scp;
  2099.     Scsi_Device     *sdev;
  2100. #else
  2101.     Scsi_Cmnd       scp;
  2102.     Scsi_Device     sdev;
  2103. #endif
  2104.     char            cmnd[MAX_COMMAND_SIZE];   
  2105. #endif
  2106. #if LINUX_VERSION_CODE >= 0x020100
  2107.     TRACE2(("gdth_halt() event %dn",(int)event));
  2108.     if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF)
  2109.         return NOTIFY_DONE;
  2110. #else
  2111.     TRACE2(("gdth_halt()n"));
  2112.     if (halt_called) {
  2113.         TRACE2(("already calledn"));
  2114.         return;
  2115.     }
  2116.     halt_called = TRUE;
  2117. #endif
  2118.     printk("GDT: Flushing all host drives .. ");
  2119.     for (hanum = 0; hanum < gdth_ctr_count; ++hanum) {
  2120.         gdth_flush(hanum);
  2121. #ifndef __alpha__
  2122.         /* controller reset */
  2123.         memset(cmnd, 0xff, MAX_COMMAND_SIZE);
  2124. #if LINUX_VERSION_CODE >= 0x020322
  2125.         sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
  2126.         scp  = scsi_allocate_device(sdev, 1, FALSE);
  2127.         scp->cmd_len = 12;
  2128.         scp->use_sg = 0;
  2129. #else
  2130.         memset(&sdev,0,sizeof(Scsi_Device));
  2131.         memset(&scp, 0,sizeof(Scsi_Cmnd));
  2132.         sdev.host = scp.host = gdth_ctr_tab[hanum];
  2133.         sdev.id = scp.target = sdev.host->this_id;
  2134.         scp.device = &sdev;
  2135. #endif
  2136.         gdtcmd.BoardNode = LOCALBOARD;
  2137.         gdtcmd.Service = CACHESERVICE;
  2138.         gdtcmd.OpCode = GDT_RESET;
  2139.         TRACE2(("gdth_halt(): reset controller %dn", hanum));
  2140. #if LINUX_VERSION_CODE >= 0x020322
  2141.         gdth_do_cmd(scp, &gdtcmd, cmnd, 10);
  2142.         scsi_release_command(scp);
  2143.         scsi_free_host_dev(sdev);
  2144. #else
  2145.         gdth_do_cmd(&scp, &gdtcmd, cmnd, 10);
  2146. #endif
  2147. #endif
  2148.     }
  2149.     printk("Done.n");
  2150. #ifdef GDTH_STATISTICS
  2151.     del_timer(&gdth_timer);
  2152. #endif
  2153. #if LINUX_VERSION_CODE >= 0x020100
  2154. #if LINUX_VERSION_CODE < 0x020322
  2155.     unregister_reboot_notifier(&gdth_notifier);
  2156. #endif
  2157.     return NOTIFY_OK;
  2158. #endif
  2159. }
  2160. #endif
  2161. #if LINUX_VERSION_CODE < 0x020400 && !defined(MODULE)
  2162. GDTH_INITFUNC(void, gdth_setup(char *str,int *ints)) 
  2163. {    
  2164.     TRACE2(("gdth_setup() str %s ints[0] %dn", 
  2165.             str ? str:"NULL", ints ? ints[0]:0));
  2166.     internal_setup(str, ints);
  2167. }
  2168. #else
  2169. static Scsi_Host_Template driver_template = GDTH;
  2170. #include "scsi_module.c"
  2171. #ifndef MODULE
  2172. __setup("gdth=", option_setup);
  2173. #endif
  2174. #endif