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

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