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

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