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.rq_status = RQ_SCSI_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.rq_status != RQ_SCSI_DONE)
 194                 barrier();
 195         } else if (scmd.request.rq_status != RQ_SCSI_DONE) {
 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.rq_status != RQ_SCSI_DONE)
 203               schedule();
 204         }
 205 
 206         size = sprintf(buffer + len, "IRQ: %2d, %s triggered\n", cc->interrupt,
 207                        (cc->intt == TRUE)?"level":"edge");
 208         len += size; 
 209         pos = begin + len;
 210         if (HBA_ptr->dma_channel == 0xff)
 211             size = sprintf(buffer + len, "DMA: BUSMASTER\n");
 212         else
 213             size = sprintf(buffer + len, "DMA: %d\n", HBA_ptr->dma_channel);
 214         len += size; 
 215         pos = begin + len;
 216         size = sprintf(buffer + len, "CPU: MC680%02d %dMHz\n", bt->cpu_type,
 217                        bt->cpu_speed);
 218         len += size; 
 219         pos = begin + len;
 220         size = sprintf(buffer + len, "Base IO : %#.4x\n", (u32) HBA_ptr->base);
 221         len += size; 
 222         pos = begin + len;
 223         size = sprintf(buffer + len, "Host Bus: %s\n", 
 224                        (SD(HBA_ptr)->bustype == IS_PCI)?"PCI ":
 225                        (SD(HBA_ptr)->bustype == IS_EISA)?"EISA":"ISA ");
 226         
 227         len += size; 
 228         pos = begin + len;
 229         size = sprintf(buffer + len, "SCSI Bus:%s%s Speed: %sMB/sec. %s\n",
 230                        (sb->wide == TRUE)?" WIDE":"", 
 231                        (sb->dif == TRUE)?" DIFFERENTIAL":"",
 232                        (sb->speed == 0)?"5":(sb->speed == 1)?"10":"20",
 233                        (sb->ext == TRUE)?"With external cable detection":"");
 234         len += size; 
 235         pos = begin + len;
 236         size = sprintf(buffer + len, "SCSI channel expansion Module: %s present\n",
 237                        (bt->sx1 == TRUE)?"SX1 (one channel)":
 238                        ((bt->sx2 == TRUE)?"SX2 (two channels)":"not"));
 239         len += size; 
 240         pos = begin + len;
 241         size = sprintf(buffer + len, "SmartRAID hardware: %spresent.\n",
 242                        (cc->srs == TRUE)?"":"not ");
 243         len += size; 
 244         pos = begin + len;
 245         size = sprintf(buffer + len, "    Type: %s\n",
 246                        ((cc->key == TRUE)?((bt->dmi == TRUE)?"integrated"
 247                                            :((bt->dm4 == TRUE)?"DM401X"
 248                                            :(bt->dm4k == TRUE)?"DM4000"
 249                                            :"-"))
 250                                            :"-"));
 251         len += size; 
 252         pos = begin + len;
 253         
 254         size = sprintf(buffer + len, "    Max array groups:              %d\n",
 255                        (al->code == 0x0e)?al->max_groups:7);
 256         len += size; 
 257         pos = begin + len;
 258         size = sprintf(buffer + len, "    Max drives per RAID 0 array:   %d\n",
 259                        (al->code == 0x0e)?al->raid0_drv:7);
 260         len += size; 
 261         pos = begin + len;
 262         size = sprintf(buffer + len, "    Max drives per RAID 3/5 array: %d\n",
 263                        (al->code == 0x0e)?al->raid35_drv:7);
 264         len += size; 
 265         pos = begin + len;
 266         size = sprintf(buffer + len, "Cache Module: %spresent.\n",
 267                        (cc->csh)?"":"not ");
 268         len += size; 
 269         pos = begin + len;
 270         size = sprintf(buffer + len, "    Type: %s\n",
 271                        ((cc->csh == TRUE)?((bt->cmi == TRUE)?"integrated"
 272                                          :((bt->cm4 == TRUE)?"CM401X"
 273                                          :((bt->cm4k == TRUE)?"CM4000"
 274                                          :"-")))
 275                                          :"-"));
 276         len += size; 
 277         pos = begin + len;
 278         for (x = 0; x <= 3; x++) {
 279             size = sprintf(buffer + len, "    Bank%d: %dMB with%s ECC\n",x,
 280                            mc->banksize[x] & 0x7f, 
 281                            (mc->banksize[x] & 0x80)?"":"out");
 282             len += size; 
 283             pos = begin + len;      
 284         }   
 285         size = sprintf(buffer + len, "Timer Mod.: %spresent\n",
 286                        (cc->tmr == TRUE)?"":"not ");
 287         len += size; 
 288         pos = begin + len;
 289         size = sprintf(buffer + len, "NVRAM     : %spresent\n",
 290                        (cc->nvr == TRUE)?"":"not ");
 291         len += size; 
 292         pos = begin + len;
 293         size = sprintf(buffer + len, "SmartROM  : %sabled\n",
 294                        (bt->srom == TRUE)?"dis":"en");
 295         len += size; 
 296         pos = begin + len;
 297         size = sprintf(buffer + len, "Alarm     : %s\n",
 298                        (bt->alrm == TRUE)?"on":"off");
 299         len += size; 
 300         pos = begin + len;
 301         
 302         if (pos < offset) {
 303             len = 0;
 304             begin = pos;
 305         }
 306         if (pos > offset + length)
 307             goto stop_output; 
 308         
 309         cmnd[0] = LOG_SENSE;
 310         cmnd[1] = 0;
 311         cmnd[2] = 0x32 + (3<<6); 
 312         cmnd[3] = 0;
 313         cmnd[4] = 0;
 314         cmnd[5] = 0;
 315         cmnd[6] = 0;
 316         cmnd[7] = 0x01;
 317         cmnd[8] = 0x44;
 318         cmnd[9] = 0;
 319  
 320         scmd.cmd_len = 10;
 321 
 322         /* Used for mutex if loading devices after boot */
 323         scmd.request.sem = NULL;
 324         scmd.request.rq_status = RQ_SCSI_BUSY; /* Mark busy */
 325         
 326         scsi_do_cmd (&scmd, cmnd, buff2, 0x144,  
 327                      eata_scsi_done, 1 * HZ, 1);
 328         /*
 329          * Wait for command to finish. Use simple wait if we are
 330          * booting, else do it right and use a mutex
 331          */     
 332         if (current->pid == 0)
 333             while (scmd.request.rq_status != RQ_SCSI_DONE)
 334                 barrier();
 335         else if (scmd.request.rq_status != RQ_SCSI_DONE) {
 336             struct semaphore sem = MUTEX_LOCKED;
 337             
 338             scmd.request.sem = &sem;
 339             down(&sem);
 340             
 341             /* Hmm.. Have to ask about this one */
 342             while (scmd.request.rq_status != RQ_SCSI_DONE)
 343               schedule();
 344         }
 345         
 346         swap_statistics(buff2);
 347         rhcs = (hst_cmd_stat *)(buff2 + 0x2c); 
 348         whcs = (hst_cmd_stat *)(buff2 + 0x8c);           
 349         
 350         for (x = 0; x <= 11; x++) {
 351             SD(HBA_ptr)->reads[x] += rhcs->sizes[x];
 352             SD(HBA_ptr)->writes[x] += whcs->sizes[x];
 353             SD(HBA_ptr)->reads[12] += rhcs->sizes[x];
 354             SD(HBA_ptr)->writes[12] += whcs->sizes[x];
 355         }
 356         size = sprintf(buffer + len, "Host<->Disk command statistics:\n"
 357                        "         Reads:      Writes:\n");
 358         len += size; 
 359         pos = begin + len;
 360         for (x = 0; x <= 10; x++) {
 361             size = sprintf(buffer+len,"%5dk:%12u %12u\n", 1 << x,
 362                            SD(HBA_ptr)->reads[x], 
 363                            SD(HBA_ptr)->writes[x]);
 364             len += size; 
 365             pos = begin + len;
 366         }
 367         size = sprintf(buffer+len,">1024k:%12u %12u\n",
 368                        SD(HBA_ptr)->reads[11], 
 369                        SD(HBA_ptr)->writes[11]);
 370         len += size; 
 371         pos = begin + len;
 372         size = sprintf(buffer+len,"Sum   :%12u %12u\n",
 373                        SD(HBA_ptr)->reads[12], 
 374                        SD(HBA_ptr)->writes[12]);
 375         len += size; 
 376         pos = begin + len;
 377     }
 378     
 379     if (pos < offset) {
 380         len = 0;
 381         begin = pos;
 382     }
 383     if (pos > offset + length)
 384         goto stop_output;
 385 
 386     if(SD(HBA_ptr)->do_latency == TRUE) {
 387         size = sprintf(buffer + len, "Host Latency Command Statistics:\n"
 388                        "Current timer resolution: 10ms\n"
 389                        "         Reads:       Min:(ms)     Max:(ms)     Ave:(ms)\n");
 390         len += size; 
 391         pos = begin + len;
 392         for (x = 0; x <= 10; x++) {
 393             size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12u\n", 
 394                            1 << x,
 395                            SD(HBA_ptr)->reads_lat[x][0], 
 396                            (SD(HBA_ptr)->reads_lat[x][1] == 0xffffffff) 
 397                            ? 0:(SD(HBA_ptr)->reads_lat[x][1] * 10), 
 398                            SD(HBA_ptr)->reads_lat[x][2] * 10, 
 399                            SD(HBA_ptr)->reads_lat[x][3] * 10 /
 400                            ((SD(HBA_ptr)->reads_lat[x][0])
 401                             ? SD(HBA_ptr)->reads_lat[x][0]:1));
 402             len += size; 
 403             pos = begin + len;
 404         }
 405         size = sprintf(buffer+len,">1024k:%12u %12u %12u %12u\n",
 406                            SD(HBA_ptr)->reads_lat[11][0], 
 407                            (SD(HBA_ptr)->reads_lat[11][1] == 0xffffffff)
 408                            ? 0:(SD(HBA_ptr)->reads_lat[11][1] * 10), 
 409                            SD(HBA_ptr)->reads_lat[11][2] * 10, 
 410                            SD(HBA_ptr)->reads_lat[11][3] * 10 /
 411                            ((SD(HBA_ptr)->reads_lat[x][0])
 412                             ? SD(HBA_ptr)->reads_lat[x][0]:1));
 413         len += size; 
 414         pos = begin + len;
 415 
 416         if (pos < offset) {
 417             len = 0;
 418             begin = pos;
 419         }
 420         if (pos > offset + length)
 421             goto stop_output;
 422 
 423         size = sprintf(buffer + len,
 424                        "         Writes:      Min:(ms)     Max:(ms)     Ave:(ms)\n");
 425         len += size; 
 426         pos = begin + len;
 427         for (x = 0; x <= 10; x++) {
 428             size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12u\n", 
 429                            1 << x,
 430                            SD(HBA_ptr)->writes_lat[x][0], 
 431                            (SD(HBA_ptr)->writes_lat[x][1] == 0xffffffff)
 432                            ? 0:(SD(HBA_ptr)->writes_lat[x][1] * 10), 
 433                            SD(HBA_ptr)->writes_lat[x][2] * 10, 
 434                            SD(HBA_ptr)->writes_lat[x][3] * 10 /
 435                            ((SD(HBA_ptr)->writes_lat[x][0])
 436                             ? SD(HBA_ptr)->writes_lat[x][0]:1));
 437             len += size; 
 438             pos = begin + len;
 439         }
 440         size = sprintf(buffer+len,">1024k:%12u %12u %12u %12u\n",
 441                            SD(HBA_ptr)->writes_lat[11][0], 
 442                            (SD(HBA_ptr)->writes_lat[11][1] == 0xffffffff)
 443                            ? 0:(SD(HBA_ptr)->writes_lat[x][1] * 10), 
 444                            SD(HBA_ptr)->writes_lat[11][2] * 10, 
 445                            SD(HBA_ptr)->writes_lat[11][3] * 10/
 446                            ((SD(HBA_ptr)->writes_lat[x][0])
 447                             ? SD(HBA_ptr)->writes_lat[x][0]:1));
 448         len += size; 
 449         pos = begin + len;
 450 
 451         if (pos < offset) {
 452             len = 0;
 453             begin = pos;
 454         }
 455         if (pos > offset + length)
 456             goto stop_output;
 457     }
 458 
 459     scd = scsi_devices;
 460     
 461     size = sprintf(buffer+len,"Attached devices: %s\n", (scd)?"":"none");
 462     len += size; 
 463     pos = begin + len;
 464     
 465     while (scd) {
 466         if (scd->host == HBA_ptr) {
 467             proc_print_scsidevice(scd, buffer, &size, len);
 468             len += size; 
 469             pos = begin + len;
 470             
 471             if (pos < offset) {
 472                 len = 0;
 473                 begin = pos;
 474             }
 475             if (pos > offset + length)
 476                 goto stop_output;
 477         }
 478         scd = scd->next;
 479     }
 480     
 481  stop_output:
 482     DBG(DBG_PROC, printk("2pos: %ld offset: %ld len: %d\n", pos, offset, len));
 483     *start=buffer+(offset-begin);   /* Start of wanted data */
 484     len-=(offset-begin);            /* Start slop */
 485     if(len>length)
 486         len = length;               /* Ending slop */
 487     DBG(DBG_PROC, printk("3pos: %ld offset: %ld len: %d\n", pos, offset, len));
 488     
 489     return (len);     
 490 }
 491 
 492 /*
 493  * Overrides for Emacs so that we follow Linus's tabbing style.
 494  * Emacs will notice this stuff at the end of the file and automatically
 495  * adjust the settings for this buffer only.  This must remain at the end
 496  * of the file.
 497  * ---------------------------------------------------------------------------
 498  * Local variables:
 499  * c-indent-level: 4
 500  * c-brace-imaginary-offset: 0
 501  * c-brace-offset: -4
 502  * c-argdecl-indent: 4
 503  * c-label-offset: -4
 504  * c-continued-statement-offset: 4
 505  * c-continued-brace-offset: 0
 506  * tab-width: 8
 507  * End:
 508  */

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