eata_dma_proc.c
Upload User: jlfgdled
Upload Date: 2013-04-10
Package Size: 33168k
Code Size: 13k
Development Platform:

Unix_Linux

  1. void swap_statistics(u8 *p)
  2. {
  3.     u32 y;
  4.     u32 *lp, h_lp;
  5.     u16 *sp, h_sp;
  6.     u8 *bp;
  7.     
  8.     lp = (u32 *)p;
  9.     sp = ((short *)lp) + 1;     /* Convert Header */
  10.     h_sp = *sp = ntohs(*sp);
  11.     lp++;
  12.     do {
  13. sp = (u16 *)lp;   /* Convert SubHeader */
  14. *sp = ntohs(*sp);
  15. bp = (u8 *) lp;
  16. y = *(bp + 3);
  17. lp++;
  18. for (h_lp = (u32)lp; (u32)lp < h_lp + ((u32)*(bp + 3)); lp++)
  19.     *lp = ntohl(*lp);
  20.     }while ((u32)lp < ((u32)p) + 4 + h_sp);
  21. }
  22. /*
  23.  * eata_set_info
  24.  * buffer : pointer to the data that has been written to the hostfile
  25.  * length : number of bytes written to the hostfile
  26.  * HBA_ptr: pointer to the Scsi_Host struct
  27.  */
  28. int eata_set_info(char *buffer, int length, struct Scsi_Host *HBA_ptr)
  29. {
  30.     int orig_length = length;
  31.     if (length >= 8 && strncmp(buffer, "eata_dma", 8) == 0) {
  32. buffer += 9;
  33. length -= 9;
  34. if(length >= 8 && strncmp(buffer, "latency", 7) == 0) {
  35.     SD(HBA_ptr)->do_latency = TRUE;
  36.     return(orig_length);
  37. if(length >=10 && strncmp(buffer, "nolatency", 9) == 0) {
  38.     SD(HBA_ptr)->do_latency = FALSE;
  39.     return(orig_length);
  40. printk("Unknown command:%s length: %dn", buffer, length);
  41.     } else 
  42. printk("Wrong Signature:%10sn", buffer);
  43.     
  44.     return(-EINVAL);
  45. }
  46. /*
  47.  * eata_proc_info
  48.  * inout : decides on the direction of the dataflow and the meaning of the 
  49.  *    variables
  50.  * buffer: If inout==FALSE data is being written to it else read from it
  51.  * *start: If inout==FALSE start of the valid data in the buffer
  52.  * offset: If inout==FALSE offset from the beginning of the imaginary file 
  53.  *    from which we start writing into the buffer
  54.  * length: If inout==FALSE max number of bytes to be written into the buffer 
  55.  *    else number of bytes in the buffer
  56.  */
  57. int eata_proc_info(char *buffer, char **start, off_t offset, int length, 
  58.    int hostno, int inout)
  59. {
  60.     Scsi_Device *scd, *SDev;
  61.     struct Scsi_Host *HBA_ptr;
  62.     Scsi_Request  * scmd;
  63.     char cmnd[MAX_COMMAND_SIZE];
  64.     static u8 buff[512];
  65.     static u8 buff2[512];
  66.     hst_cmd_stat *rhcs, *whcs;
  67.     coco  *cc;
  68.     scsitrans  *st;
  69.     scsimod  *sm;
  70.     hobu  *hb;
  71.     scbu  *sb;
  72.     boty  *bt;
  73.     memco  *mc;
  74.     firm  *fm;
  75.     subinf  *si; 
  76.     pcinf  *pi;
  77.     arrlim  *al;
  78.     int i, x; 
  79.     int   size, len = 0;
  80.     off_t begin = 0;
  81.     off_t pos = 0;
  82.     scd = NULL;
  83.     HBA_ptr = first_HBA;
  84.     for (i = 1; i <= registered_HBAs; i++) {
  85. if (HBA_ptr->host_no == hostno)
  86.     break;
  87. HBA_ptr = SD(HBA_ptr)->next;
  88.     }      
  89.     if(inout == TRUE) /* Has data been written to the file ? */ 
  90. return(eata_set_info(buffer, length, HBA_ptr));
  91.     if (offset == 0)
  92. memset(buff, 0, sizeof(buff));
  93.     cc = (coco *)     (buff + 0x148);
  94.     st = (scsitrans *)(buff + 0x164); 
  95.     sm = (scsimod *)  (buff + 0x16c);
  96.     hb = (hobu *)     (buff + 0x172);
  97.     sb = (scbu *)     (buff + 0x178);
  98.     bt = (boty *)     (buff + 0x17e);
  99.     mc = (memco *)    (buff + 0x186);
  100.     fm = (firm *)     (buff + 0x18e);
  101.     si = (subinf *)   (buff + 0x196); 
  102.     pi = (pcinf *)    (buff + 0x19c);
  103.     al = (arrlim *)   (buff + 0x1a2);
  104.     size = sprintf(buffer+len, "EATA (Extended Attachment) driver version: "
  105.    "%d.%d%sn",VER_MAJOR, VER_MINOR, VER_SUB);
  106.     len += size; pos = begin + len;
  107.     size = sprintf(buffer + len, "queued commands:     %10ldn"
  108.    "processed interrupts:%10ldn", queue_counter, int_counter);
  109.     len += size; pos = begin + len;
  110.     size = sprintf(buffer + len, "nscsi%-2d: HBA %.10sn",
  111.    HBA_ptr->host_no, SD(HBA_ptr)->name);
  112.     len += size; 
  113.     pos = begin + len;
  114.     size = sprintf(buffer + len, "Firmware revision: v%sn", 
  115.    SD(HBA_ptr)->revision);
  116.     len += size;
  117.     pos = begin + len;
  118.     size = sprintf(buffer + len, "Hardware Configuration:n");
  119.     len += size; 
  120.     pos = begin + len;
  121.     
  122.     if(SD(HBA_ptr)->broken_INQUIRY == TRUE) {
  123. if (HBA_ptr->dma_channel == BUSMASTER)
  124.     size = sprintf(buffer + len, "DMA: BUSMASTERn");
  125. else
  126.     size = sprintf(buffer + len, "DMA: %dn", HBA_ptr->dma_channel);
  127. len += size; 
  128. pos = begin + len;
  129. size = sprintf(buffer + len, "Base IO : %#.4xn", (u32) HBA_ptr->base);
  130. len += size; 
  131. pos = begin + len;
  132. size = sprintf(buffer + len, "Host Bus: EISAn"); 
  133. len += size; 
  134. pos = begin + len;
  135.     } else {
  136.         SDev = scsi_get_host_dev(HBA_ptr);
  137.         
  138.         if(SDev == NULL)
  139.             return -ENOMEM;
  140.         
  141. scmd  = scsi_allocate_request(SDev);
  142. if(scmd == NULL)
  143. {
  144.     scsi_free_host_dev(SDev);
  145.     return -ENOMEM;
  146. }
  147. cmnd[0] = LOG_SENSE;
  148. cmnd[1] = 0;
  149. cmnd[2] = 0x33 + (3<<6);
  150. cmnd[3] = 0;
  151. cmnd[4] = 0;
  152. cmnd[5] = 0;
  153.         cmnd[6] = 0;
  154. cmnd[7] = 0x00;
  155. cmnd[8] = 0x66;
  156. cmnd[9] = 0;
  157. scmd->sr_cmd_len = 10;
  158. scmd->sr_data_direction = SCSI_DATA_READ;
  159. /*
  160.  * Do the command and wait for it to finish.
  161.  */
  162. scsi_wait_req (scmd, cmnd, buff + 0x144, 0x66,  
  163.        1 * HZ, 1);
  164. size = sprintf(buffer + len, "IRQ: %2d, %s triggeredn", cc->interrupt,
  165.        (cc->intt == TRUE)?"level":"edge");
  166. len += size; 
  167. pos = begin + len;
  168. if (HBA_ptr->dma_channel == 0xff)
  169.     size = sprintf(buffer + len, "DMA: BUSMASTERn");
  170. else
  171.     size = sprintf(buffer + len, "DMA: %dn", HBA_ptr->dma_channel);
  172. len += size; 
  173. pos = begin + len;
  174. size = sprintf(buffer + len, "CPU: MC680%02d %dMHzn", bt->cpu_type,
  175.        bt->cpu_speed);
  176. len += size; 
  177. pos = begin + len;
  178. size = sprintf(buffer + len, "Base IO : %#.4xn", (u32) HBA_ptr->base);
  179. len += size; 
  180. pos = begin + len;
  181. size = sprintf(buffer + len, "Host Bus: %sn", 
  182.        (SD(HBA_ptr)->bustype == IS_PCI)?"PCI ":
  183.        (SD(HBA_ptr)->bustype == IS_EISA)?"EISA":"ISA ");
  184. len += size; 
  185. pos = begin + len;
  186. size = sprintf(buffer + len, "SCSI Bus:%s%s Speed: %sMB/sec. %sn",
  187.        (sb->wide == TRUE)?" WIDE":"", 
  188.        (sb->dif == TRUE)?" DIFFERENTIAL":"",
  189.        (sb->speed == 0)?"5":(sb->speed == 1)?"10":"20",
  190.        (sb->ext == TRUE)?"With external cable detection":"");
  191. len += size; 
  192. pos = begin + len;
  193. size = sprintf(buffer + len, "SCSI channel expansion Module: %s presentn",
  194.        (bt->sx1 == TRUE)?"SX1 (one channel)":
  195.        ((bt->sx2 == TRUE)?"SX2 (two channels)":"not"));
  196. len += size; 
  197. pos = begin + len;
  198. size = sprintf(buffer + len, "SmartRAID hardware: %spresent.n",
  199.        (cc->srs == TRUE)?"":"not ");
  200. len += size; 
  201. pos = begin + len;
  202. size = sprintf(buffer + len, "    Type: %sn",
  203.        ((cc->key == TRUE)?((bt->dmi == TRUE)?"integrated"
  204.    :((bt->dm4 == TRUE)?"DM401X"
  205.    :(bt->dm4k == TRUE)?"DM4000"
  206.    :"-"))
  207.    :"-"));
  208. len += size; 
  209. pos = begin + len;
  210. size = sprintf(buffer + len, "    Max array groups:              %dn",
  211.        (al->code == 0x0e)?al->max_groups:7);
  212. len += size; 
  213. pos = begin + len;
  214. size = sprintf(buffer + len, "    Max drives per RAID 0 array:   %dn",
  215.        (al->code == 0x0e)?al->raid0_drv:7);
  216. len += size; 
  217. pos = begin + len;
  218. size = sprintf(buffer + len, "    Max drives per RAID 3/5 array: %dn",
  219.        (al->code == 0x0e)?al->raid35_drv:7);
  220. len += size; 
  221. pos = begin + len;
  222. size = sprintf(buffer + len, "Cache Module: %spresent.n",
  223.        (cc->csh)?"":"not ");
  224. len += size; 
  225. pos = begin + len;
  226. size = sprintf(buffer + len, "    Type: %sn",
  227.        ((cc->csh == TRUE)?((bt->cmi == TRUE)?"integrated"
  228.  :((bt->cm4 == TRUE)?"CM401X"
  229.  :((bt->cm4k == TRUE)?"CM4000"
  230.  :"-")))
  231.  :"-"));
  232. len += size; 
  233. pos = begin + len;
  234. for (x = 0; x <= 3; x++) {
  235.     size = sprintf(buffer + len, "    Bank%d: %dMB with%s ECCn",x,
  236.    mc->banksize[x] & 0x7f, 
  237.    (mc->banksize[x] & 0x80)?"":"out");
  238.     len += size; 
  239.     pos = begin + len;     
  240. }   
  241. size = sprintf(buffer + len, "Timer Mod.: %spresentn",
  242.        (cc->tmr == TRUE)?"":"not ");
  243. len += size; 
  244. pos = begin + len;
  245. size = sprintf(buffer + len, "NVRAM     : %spresentn",
  246.        (cc->nvr == TRUE)?"":"not ");
  247. len += size; 
  248. pos = begin + len;
  249. size = sprintf(buffer + len, "SmartROM  : %sabledn",
  250.        (bt->srom == TRUE)?"dis":"en");
  251. len += size; 
  252. pos = begin + len;
  253. size = sprintf(buffer + len, "Alarm     : %sn",
  254.        (bt->alrm == TRUE)?"on":"off");
  255. len += size; 
  256. pos = begin + len;
  257. if (pos < offset) {
  258.     len = 0;
  259.     begin = pos;
  260. }
  261. if (pos > offset + length)
  262.     goto stop_output; 
  263. if(SD(HBA_ptr)->do_latency == FALSE) { 
  264.     cmnd[0] = LOG_SENSE;
  265.     cmnd[1] = 0;
  266.     cmnd[2] = 0x32 + (3<<6); 
  267.     cmnd[3] = 0;
  268.     cmnd[4] = 0;
  269.     cmnd[5] = 0;
  270.     cmnd[6] = 0;
  271.     cmnd[7] = 0x01;
  272.     cmnd[8] = 0x44;
  273.     cmnd[9] = 0;
  274.     
  275.     scmd->sr_cmd_len = 10;
  276.     scmd->sr_data_direction = SCSI_DATA_READ;
  277.     /*
  278.      * Do the command and wait for it to finish.
  279.      */
  280.     scsi_wait_req (scmd, cmnd, buff2, 0x144,
  281.    1 * HZ, 1);
  282.     swap_statistics(buff2);
  283.     rhcs = (hst_cmd_stat *)(buff2 + 0x2c); 
  284.     whcs = (hst_cmd_stat *)(buff2 + 0x8c);  
  285.     
  286.     for (x = 0; x <= 11; x++) {
  287.         SD(HBA_ptr)->reads[x] += rhcs->sizes[x];
  288. SD(HBA_ptr)->writes[x] += whcs->sizes[x];
  289. SD(HBA_ptr)->reads[12] += rhcs->sizes[x];
  290. SD(HBA_ptr)->writes[12] += whcs->sizes[x];
  291.     }
  292.     size = sprintf(buffer + len, "Host<->Disk command statistics:n"
  293.    "         Reads:      Writes:n");
  294.     len += size; 
  295.     pos = begin + len;
  296.     for (x = 0; x <= 10; x++) {
  297.         size = sprintf(buffer+len,"%5dk:%12u %12un", 1 << x,
  298.        SD(HBA_ptr)->reads[x], 
  299.        SD(HBA_ptr)->writes[x]);
  300. len += size; 
  301. pos = begin + len;
  302.     }
  303.     size = sprintf(buffer+len,">1024k:%12u %12un",
  304.    SD(HBA_ptr)->reads[11], 
  305.    SD(HBA_ptr)->writes[11]);
  306.     len += size; 
  307.     pos = begin + len;
  308.     size = sprintf(buffer+len,"Sum   :%12u %12un",
  309.    SD(HBA_ptr)->reads[12], 
  310.    SD(HBA_ptr)->writes[12]);
  311.     len += size; 
  312.     pos = begin + len;
  313. }
  314. scsi_release_request(scmd);
  315. scsi_free_host_dev(SDev);
  316.     }
  317.     
  318.     if (pos < offset) {
  319. len = 0;
  320. begin = pos;
  321.     }
  322.     if (pos > offset + length)
  323. goto stop_output;
  324.     if(SD(HBA_ptr)->do_latency == TRUE) {
  325.         int factor = 1024/HZ;
  326. size = sprintf(buffer + len, "Host Latency Command Statistics:n"
  327.        "Current timer resolution: %2dmsn"
  328.        "         Reads:       Min:(ms)     Max:(ms)     Ave:(ms)n",
  329.        factor);
  330. len += size; 
  331. pos = begin + len;
  332. for (x = 0; x <= 10; x++) {
  333.     size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12un", 
  334.    1 << x,
  335.    SD(HBA_ptr)->reads_lat[x][0], 
  336.    (SD(HBA_ptr)->reads_lat[x][1] == 0xffffffff) 
  337.    ? 0:(SD(HBA_ptr)->reads_lat[x][1] * factor), 
  338.    SD(HBA_ptr)->reads_lat[x][2] * factor, 
  339.    SD(HBA_ptr)->reads_lat[x][3] * factor /
  340.    ((SD(HBA_ptr)->reads_lat[x][0])
  341.     ? SD(HBA_ptr)->reads_lat[x][0]:1));
  342.     len += size; 
  343.     pos = begin + len;
  344. }
  345. size = sprintf(buffer+len,">1024k:%12u %12u %12u %12un",
  346.    SD(HBA_ptr)->reads_lat[11][0], 
  347.    (SD(HBA_ptr)->reads_lat[11][1] == 0xffffffff)
  348.    ? 0:(SD(HBA_ptr)->reads_lat[11][1] * factor), 
  349.    SD(HBA_ptr)->reads_lat[11][2] * factor, 
  350.    SD(HBA_ptr)->reads_lat[11][3] * factor /
  351.    ((SD(HBA_ptr)->reads_lat[x][0])
  352.     ? SD(HBA_ptr)->reads_lat[x][0]:1));
  353. len += size; 
  354. pos = begin + len;
  355. if (pos < offset) {
  356.     len = 0;
  357.     begin = pos;
  358. }
  359. if (pos > offset + length)
  360.     goto stop_output;
  361. size = sprintf(buffer + len,
  362.        "         Writes:      Min:(ms)     Max:(ms)     Ave:(ms)n");
  363. len += size; 
  364. pos = begin + len;
  365. for (x = 0; x <= 10; x++) {
  366.     size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12un", 
  367.    1 << x,
  368.    SD(HBA_ptr)->writes_lat[x][0], 
  369.    (SD(HBA_ptr)->writes_lat[x][1] == 0xffffffff)
  370.    ? 0:(SD(HBA_ptr)->writes_lat[x][1] * factor), 
  371.    SD(HBA_ptr)->writes_lat[x][2] * factor, 
  372.    SD(HBA_ptr)->writes_lat[x][3] * factor /
  373.    ((SD(HBA_ptr)->writes_lat[x][0])
  374.     ? SD(HBA_ptr)->writes_lat[x][0]:1));
  375.     len += size; 
  376.     pos = begin + len;
  377. }
  378. size = sprintf(buffer+len,">1024k:%12u %12u %12u %12un",
  379.    SD(HBA_ptr)->writes_lat[11][0], 
  380.    (SD(HBA_ptr)->writes_lat[11][1] == 0xffffffff)
  381.    ? 0:(SD(HBA_ptr)->writes_lat[x][1] * factor), 
  382.    SD(HBA_ptr)->writes_lat[11][2] * factor, 
  383.    SD(HBA_ptr)->writes_lat[11][3] * factor /
  384.    ((SD(HBA_ptr)->writes_lat[x][0])
  385.     ? SD(HBA_ptr)->writes_lat[x][0]:1));
  386. len += size; 
  387. pos = begin + len;
  388. if (pos < offset) {
  389.     len = 0;
  390.     begin = pos;
  391. }
  392. if (pos > offset + length)
  393.     goto stop_output;
  394.     }
  395.     size = sprintf(buffer+len,"Attached devices: %sn", 
  396.    (HBA_ptr->host_queue)?"":"none");
  397.     len += size; 
  398.     pos = begin + len;
  399.     
  400.     for(scd = HBA_ptr->host_queue; scd; scd = scd->next) {
  401.     proc_print_scsidevice(scd, buffer, &size, len);
  402.     len += size; 
  403.     pos = begin + len;
  404.     
  405.     if (pos < offset) {
  406. len = 0;
  407. begin = pos;
  408.     }
  409.     if (pos > offset + length)
  410. goto stop_output;
  411.     }
  412.     
  413.  stop_output:
  414.     DBG(DBG_PROC, printk("2pos: %ld offset: %ld len: %dn", pos, offset, len));
  415.     *start=buffer+(offset-begin);   /* Start of wanted data */
  416.     len-=(offset-begin);     /* Start slop */
  417.     if(len>length)
  418. len = length;     /* Ending slop */
  419.     DBG(DBG_PROC, printk("3pos: %ld offset: %ld len: %dn", pos, offset, len));
  420.     
  421.     return (len);     
  422. }
  423. /*
  424.  * Overrides for Emacs so that we follow Linus's tabbing style.
  425.  * Emacs will notice this stuff at the end of the file and automatically
  426.  * adjust the settings for this buffer only.  This must remain at the end
  427.  * of the file.
  428.  * ---------------------------------------------------------------------------
  429.  * Local variables:
  430.  * c-indent-level: 4
  431.  * c-brace-imaginary-offset: 0
  432.  * c-brace-offset: -4
  433.  * c-argdecl-indent: 4
  434.  * c-label-offset: -4
  435.  * c-continued-statement-offset: 4
  436.  * c-continued-brace-offset: 0
  437.  * tab-width: 8
  438.  * End:
  439.  */