root/drivers/scsi/eata_dma_proc.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. swap_statistics
  2. eata_set_info
  3. eata_proc_info

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

/* [previous][next][first][last][top][bottom][index][help] */