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         /* Used for mutex if loading devices after boot */
 185         scmd.request.sem = NULL;
 186         scmd.request.rq_status = RQ_SCSI_BUSY;
 187         
 188         scsi_do_cmd (&scmd, cmnd, buff + 0x144, 0x66,  
 189                      eata_scsi_done, 1 * HZ, 1);
 190         /*
 191          * Wait for command to finish. Use simple wait if we are
 192          * booting, else do it right and use a mutex
 193          */     
 194         if (current->pid == 0) {
 195             while (scmd.request.rq_status != RQ_SCSI_DONE)
 196                 barrier();
 197         } else if (scmd.request.rq_status != RQ_SCSI_DONE) {
 198             struct semaphore sem = MUTEX_LOCKED;
 199             
 200             scmd.request.sem = &sem;
 201             down(&sem);
 202             
 203             /* Hmm.. Have to ask about this one */
 204             while (scmd.request.rq_status != RQ_SCSI_DONE)
 205               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.rq_status = RQ_SCSI_BUSY; /* 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.rq_status != RQ_SCSI_DONE)
 336                 barrier();
 337         else if (scmd.request.rq_status != RQ_SCSI_DONE) {
 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.rq_status != RQ_SCSI_DONE)
 345               schedule();
 346         }
 347         
 348         swap_statistics(buff2);
 349         rhcs = (hst_cmd_stat *)(buff2 + 0x2c); 
 350         whcs = (hst_cmd_stat *)(buff2 + 0x8c);           
 351         
 352         for (x = 0; x <= 11; x++) {
 353             SD(HBA_ptr)->reads[x] += rhcs->sizes[x];
 354             SD(HBA_ptr)->writes[x] += whcs->sizes[x];
 355             SD(HBA_ptr)->reads[12] += rhcs->sizes[x];
 356             SD(HBA_ptr)->writes[12] += whcs->sizes[x];
 357         }
 358         size = sprintf(buffer + len, "Host<->Disk command statistics:\n"
 359                        "         Reads:      Writes:\n");
 360         len += size; 
 361         pos = begin + len;
 362         for (x = 0; x <= 10; x++) {
 363             size = sprintf(buffer+len,"%5dk:%12u %12u\n", 1 << x,
 364                            SD(HBA_ptr)->reads[x], 
 365                            SD(HBA_ptr)->writes[x]);
 366             len += size; 
 367             pos = begin + len;
 368         }
 369         size = sprintf(buffer+len,">1024k:%12u %12u\n",
 370                        SD(HBA_ptr)->reads[11], 
 371                        SD(HBA_ptr)->writes[11]);
 372         len += size; 
 373         pos = begin + len;
 374         size = sprintf(buffer+len,"Sum   :%12u %12u\n",
 375                        SD(HBA_ptr)->reads[12], 
 376                        SD(HBA_ptr)->writes[12]);
 377         len += size; 
 378         pos = begin + len;
 379     }
 380     
 381     if (pos < offset) {
 382         len = 0;
 383         begin = pos;
 384     }
 385     if (pos > offset + length)
 386         goto stop_output;
 387 
 388     if(SD(HBA_ptr)->do_latency == TRUE) {
 389         size = sprintf(buffer + len, "Host Latency Command Statistics:\n"
 390                        "Current timer resolution: 10ms\n"
 391                        "         Reads:       Min:(ms)     Max:(ms)     Ave:(ms)\n");
 392         len += size; 
 393         pos = begin + len;
 394         for (x = 0; x <= 10; x++) {
 395             size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12u\n", 
 396                            1 << x,
 397                            SD(HBA_ptr)->reads_lat[x][0], 
 398                            (SD(HBA_ptr)->reads_lat[x][1] == 0xffffffff) 
 399                            ? 0:(SD(HBA_ptr)->reads_lat[x][1] * 10), 
 400                            SD(HBA_ptr)->reads_lat[x][2] * 10, 
 401                            SD(HBA_ptr)->reads_lat[x][3] * 10 /
 402                            ((SD(HBA_ptr)->reads_lat[x][0])
 403                             ? SD(HBA_ptr)->reads_lat[x][0]:1));
 404             len += size; 
 405             pos = begin + len;
 406         }
 407         size = sprintf(buffer+len,">1024k:%12u %12u %12u %12u\n",
 408                            SD(HBA_ptr)->reads_lat[11][0], 
 409                            (SD(HBA_ptr)->reads_lat[11][1] == 0xffffffff)
 410                            ? 0:(SD(HBA_ptr)->reads_lat[11][1] * 10), 
 411                            SD(HBA_ptr)->reads_lat[11][2] * 10, 
 412                            SD(HBA_ptr)->reads_lat[11][3] * 10 /
 413                            ((SD(HBA_ptr)->reads_lat[x][0])
 414                             ? SD(HBA_ptr)->reads_lat[x][0]:1));
 415         len += size; 
 416         pos = begin + len;
 417 
 418         if (pos < offset) {
 419             len = 0;
 420             begin = pos;
 421         }
 422         if (pos > offset + length)
 423             goto stop_output;
 424 
 425         size = sprintf(buffer + len,
 426                        "         Writes:      Min:(ms)     Max:(ms)     Ave:(ms)\n");
 427         len += size; 
 428         pos = begin + len;
 429         for (x = 0; x <= 10; x++) {
 430             size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12u\n", 
 431                            1 << x,
 432                            SD(HBA_ptr)->writes_lat[x][0], 
 433                            (SD(HBA_ptr)->writes_lat[x][1] == 0xffffffff)
 434                            ? 0:(SD(HBA_ptr)->writes_lat[x][1] * 10), 
 435                            SD(HBA_ptr)->writes_lat[x][2] * 10, 
 436                            SD(HBA_ptr)->writes_lat[x][3] * 10 /
 437                            ((SD(HBA_ptr)->writes_lat[x][0])
 438                             ? SD(HBA_ptr)->writes_lat[x][0]:1));
 439             len += size; 
 440             pos = begin + len;
 441         }
 442         size = sprintf(buffer+len,">1024k:%12u %12u %12u %12u\n",
 443                            SD(HBA_ptr)->writes_lat[11][0], 
 444                            (SD(HBA_ptr)->writes_lat[11][1] == 0xffffffff)
 445                            ? 0:(SD(HBA_ptr)->writes_lat[x][1] * 10), 
 446                            SD(HBA_ptr)->writes_lat[11][2] * 10, 
 447                            SD(HBA_ptr)->writes_lat[11][3] * 10/
 448                            ((SD(HBA_ptr)->writes_lat[x][0])
 449                             ? SD(HBA_ptr)->writes_lat[x][0]:1));
 450         len += size; 
 451         pos = begin + len;
 452 
 453         if (pos < offset) {
 454             len = 0;
 455             begin = pos;
 456         }
 457         if (pos > offset + length)
 458             goto stop_output;
 459     }
 460 
 461 #if 0
 462     scd = scsi_devices;
 463     
 464     size = sprintf(buffer+len,"Attached devices: %s\n", (scd)?"":"none");
 465     len += size; 
 466     pos = begin + len;
 467     
 468     while (scd) {
 469         if (scd->host == HBA_ptr) {
 470             proc_print_scsidevice(scd, buffer, &size, len);
 471             len += size; 
 472             pos = begin + len;
 473             
 474             if (pos < offset) {
 475                 len = 0;
 476                 begin = pos;
 477             }
 478             if (pos > offset + length)
 479                 goto stop_output;
 480         }
 481         scd = scd->next;
 482     }
 483 #endif
 484     
 485  stop_output:
 486     DBG(DBG_PROC, printk("2pos: %ld offset: %ld len: %d\n", pos, offset, len));
 487     *start=buffer+(offset-begin);   /* Start of wanted data */
 488     len-=(offset-begin);            /* Start slop */
 489     if(len>length)
 490         len = length;               /* Ending slop */
 491     DBG(DBG_PROC, printk("3pos: %ld offset: %ld len: %d\n", pos, offset, len));
 492     
 493     return (len);     
 494 }
 495 
 496 /*
 497  * Overrides for Emacs so that we follow Linus's tabbing style.
 498  * Emacs will notice this stuff at the end of the file and automatically
 499  * adjust the settings for this buffer only.  This must remain at the end
 500  * of the file.
 501  * ---------------------------------------------------------------------------
 502  * Local variables:
 503  * c-indent-level: 4
 504  * c-brace-imaginary-offset: 0
 505  * c-brace-offset: -4
 506  * c-argdecl-indent: 4
 507  * c-label-offset: -4
 508  * c-continued-statement-offset: 4
 509  * c-continued-brace-offset: 0
 510  * tab-width: 8
 511  * End:
 512  */

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