--- R29/drivers/scsi/sd.c 2004-11-11 10:24:17.000000000 +0000 +++ R63/drivers/scsi/sd.c 2005-07-02 08:01:14.000000000 +0100 @@ -61,6 +61,10 @@ #include +//pete +#include +// + /* * static const char RCSid[] = "$Header:"; */ @@ -81,6 +85,9 @@ #define N_USED_SD_MAJORS (N_USED_SCSI_DISKS / SCSI_DISKS_PER_MAJOR) #define MAX_RETRIES 5 +//pete +#define SCSI_SEND_CMND_INTERVAL 5*HZ +// /* * Time out in seconds for disks and Magneto-opticals (which are slower). @@ -89,11 +96,16 @@ #define SD_TIMEOUT (30 * HZ) #define SD_MOD_TIMEOUT (75 * HZ) +// /* grant */ //#define GUID_EQUAL(x,y) (x[0]==y[0] && x[1]==y[1] && x[2]==y[2]) +//pete +static int port2_attached; +pid_t sd_mc_thread_pid; +DECLARE_COMPLETION(sd_mc_thread_exited); +// static Scsi_Disk *rscsi_disks; -//static Scsi_Disk *rscsi_disks; static struct gendisk *sd_gendisks; static int *sd_sizes; static int *sd_blocksizes; @@ -104,7 +116,9 @@ static int fop_revalidate_scsidisk(kdev_t); static int sd_init_onedisk(int); - +//pete +static int sd_send_cmnd_one(int); +// static int sd_init(void); static void sd_finish(void); @@ -113,6 +127,7 @@ static void sd_detach(Scsi_Device *); static int sd_init_command(Scsi_Cmnd *); + static struct Scsi_Device_Template sd_template = { name:"disk", tag:"sd", @@ -783,6 +798,11 @@ unsigned int the_result; int sector_size; Scsi_Request *SRpnt; + + //pete + char flash[12]="flash_"; + char hdd[10]="hdd_"; + // /* * Get the name of the disk, in case we need to log it somewhere. @@ -1053,6 +1073,7 @@ "%u %d-byte hdwr sectors (%u MB)\n", nbuff, rscsi_disks[i].capacity, hard_sector, (sz - sz/625 + 974)/1950); + } /* Rescale capacity to 512-byte units */ @@ -1065,6 +1086,55 @@ if (sector_size == 256) rscsi_disks[i].capacity >>= 1; } + // add by super, moified by pete + if (rscsi_disks[i].device->removable){ + if(0x32 == rscsi_disks[i].device->host->hostt->port){ + printk("is removable disk \n"); + *IXP425_GPIO_GPOUTR &= 0xfffb; + //port2_attached |= 1<<(i-1); + remove_proc_entry("flash_sda",NULL); + create_proc_read_entry("flash_sda", + 0, + NULL, + NULL, + NULL + ); + }else{ + strcat(flash,nbuff); + printk("is removable disk \n"); + *IXP425_GPIO_GPOUTR &= 0xfff7; + port2_attached |= 1<<(i-1); + remove_proc_entry(flash,NULL); + create_proc_read_entry(flash, + 0, + NULL, + NULL, + NULL + ); + } + }else { + printk("%x port connect!!!!!\n",rscsi_disks[i].device->host->hostt->port); + if(0x32 == rscsi_disks[i].device->host->hostt->port){ + *IXP425_GPIO_GPOUTR &= 0xfffb; + create_proc_read_entry("hdd_sda", + 0, + NULL, + NULL, + NULL + ); + }else{ + *IXP425_GPIO_GPOUTR &= 0xfff7; + port2_attached |= 1<<(i-1); + strcat(hdd,nbuff); + create_proc_read_entry(hdd, + 0, + NULL, + NULL, + NULL + ); + } + } + //end /* @@ -1124,6 +1194,140 @@ return i; } +//pete +static int sd_send_cmnd_one(int i) +{ + unsigned char cmd[10]; + char nbuff[6]; + unsigned char *buffer; + unsigned int the_result; + Scsi_Request *SRpnt; + + char media[24]; + /* + * Get the name of the disk, in case we need to log it somewhere. + */ + sd_devname(i, nbuff); + + /* + * If the device is offline, don't try and read capacity or any + * of the other niceties. + */ + if (rscsi_disks[i].device->online == FALSE) + return i; + + /* + * We need to retry the READ_CAPACITY because a UNIT_ATTENTION is + * considered a fatal error, and many devices report such an error + * just after a scsi bus reset. + */ + + SRpnt = scsi_allocate_request(rscsi_disks[i].device); + if (!SRpnt) { + printk(KERN_WARNING "(sd_init_onedisk:) Request allocation failure.\n"); + return i; + } + + buffer = (unsigned char *) scsi_malloc(512); + if (!buffer) { + printk(KERN_WARNING "(sd_init_onedisk:) Memory allocation failure.\n"); + scsi_release_request(SRpnt); + return i; + } + + cmd[0] = TEST_UNIT_READY; /* use this command to test media change */ + cmd[1] = (rscsi_disks[i].device->scsi_level <= SCSI_2) ? + ((rscsi_disks[i].device->lun << 5) & 0xe0) : 0; + memset((void *) &cmd[2], 0, 8); + SRpnt->sr_cmd_len = 0; + SRpnt->sr_sense_buffer[0] = 0; + SRpnt->sr_sense_buffer[2] = 0; + SRpnt->sr_data_direction = SCSI_DATA_NONE; + + scsi_wait_req (SRpnt, (void *) cmd, (void *) buffer, + 0/*512*/, SD_TIMEOUT, MAX_RETRIES); + + the_result = SRpnt->sr_result; + + sprintf(media, "sd%c_media_not_present", 'a' + i); + + /* -- code: 0x70, key: 0x2, ASC: 0x3a, ASCQ: 0x0 + this indicates Unit not ready: media not present */ + if( the_result != 0 + && ((driver_byte(the_result) & DRIVER_SENSE) != 0) + && SRpnt->sr_sense_buffer[0] == 0x70 + && (SRpnt->sr_sense_buffer[2]& 0xf) == NOT_READY + && SRpnt->sr_sense_buffer[12] == 0x3A + && SRpnt->sr_sense_buffer[13] == 0x0 ) { + //printk("sd%c media not present!\n", 'a' + i); + remove_proc_entry(media, NULL); + create_proc_read_entry(media, + 0, + NULL, + NULL, + NULL + ); + }else if(the_result == 0){ /* need more conditions? */ + remove_proc_entry(media, NULL); + } + + scsi_release_request(SRpnt); + SRpnt = NULL; + + scsi_free(buffer, 512); + return i; +} + +static int sd_send_cmnd_thread(void) +{ + int i; + + siginitsetinv(¤t->blocked, 0); + + //lock_kernel(); + + /* + * This thread doesn't need any user-level access, + * so get rid of all our resources.. + */ + exit_files(current); + current->files = init_task.files; + atomic_inc(¤t->files->count); + daemonize(); + reparent_to_init(); + + /* avoid getting signals */ + spin_lock_irq(¤t->sigmask_lock); + flush_signals(current); + sigfillset(¤t->blocked); + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + /* set our name for identification purposes */ + sprintf(current->comm, "sd-mc-thread"); + + //unlock_kernel(); + + do{ + /* If all scsi disks are removed, there will be no scsi host, so we should exit this thread. */ + if(next_scsi_host == 0) + break; + + for (i = 0; i < sd_template.dev_max; ++i) + if ( rscsi_disks[i].device) { + sd_send_cmnd_one(i); + } + + /* Now sleep for 5 seconds */ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(SCSI_SEND_CMND_INTERVAL); + }while(!signal_pending(current)); + + complete_and_exit(&sd_mc_thread_exited, 0); + return 0; +} +// + /* * The sd_init() function looks at all SCSI drives present, determines * their size, and reads partition table entries for them. @@ -1189,8 +1393,9 @@ * commands if they know what they're doing and they ask for it * explicitly via the SHpnt->max_sectors API. */ - sd_max_sectors[i] = 8*8; //For GL811E Chip. - //sd_max_sectors[i] = MAX_SEGMENTS*8; + //super + sd_max_sectors[i] = 8*8; + // sd_max_sectors[i] = MAX_SEGMENTS*8; } for (i = 0; i < N_USED_SD_MAJORS; i++) { @@ -1299,6 +1504,15 @@ : 4; /* 4 sector read-ahead */ } + //pete + //printk("-------------------in sd_finish------------------\n"); + if(next_scsi_host == 1){ + /* We just need *ONE* thread */ + sd_mc_thread_pid = kernel_thread(sd_send_cmnd_thread, NULL, CLONE_VM); + if(sd_mc_thread_pid < 0) + printk("Unable to start sd send command thread\n"); + } + // return; } @@ -1324,9 +1538,26 @@ SDp->attached--; return 1; } - for (dpnt = rscsi_disks, i = 0; i < sd_template.dev_max; i++, dpnt++) - if ( SDp == dpnt->device || !dpnt->device) /* grant */ - break; + + //Pete + if(SDp->host->host_no == 0){ + dpnt = rscsi_disks; + if(dpnt->device){ + SDp->attached--; + return 1; + } + i = 0; + } + else{ + //start from rscsi_disk[1]. + dpnt = rscsi_disks; + dpnt++; + i = 1; + for (; i < sd_template.dev_max; i++, dpnt++) + if (SDp == dpnt->device||!dpnt->device){ + break; + } + } if (i >= sd_template.dev_max) { printk(KERN_WARNING "scsi_devices corrupt (sd)," @@ -1335,18 +1566,7 @@ SDp->attached--; return 1; } - /* check different disks by grant */ - // i = SDp->removable;//super modify - printk("the host no is %d\n",SDp->host->host_no); - i = 1 - SDp->host->host_no; - if ( rscsi_disks[i].device )//&& - // !GUID_EQUAL( (struct us_data *)rscsi_disks[i].device->host->hostt->proc_dir->guid, - // (struct us_data *)SDp->host->hostt->proc_dir->guid) ) - { - sd_detach( rscsi_disks[i].device ); - printk("* sd_detach\n"); - } - printk("* sd_attach:%d\n",i); + rscsi_disks[i].device = SDp; rscsi_disks[i].has_part_table = 0; sd_template.nr_dev++; @@ -1356,6 +1576,9 @@ if (SDp->removable) SD_GENDISK(i).flags[devnum] |= GENHD_FL_REMOVABLE; sd_devname(i, nbuff); + //pete + strcpy(SDp->node, nbuff); + // printk("Attached scsi %sdisk %s at scsi%d, channel %d, id %d, lun %d\n", SDp->removable ? "removable " : "", nbuff, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun); @@ -1435,29 +1658,65 @@ int i, j; int max_p; int start; + //pete + char flash[12]; + char hdd[10]; + char media[26]; + // if (rscsi_disks == NULL) return; + for (dpnt = rscsi_disks, i = 0; i < sd_template.dev_max; i++, dpnt++) if (dpnt->device == SDp) { + + #if 1 + //pete + sprintf(media, "sd%c_media_not_present", 'a' + i); + + switch(SDp->host->hostt->port){ + case 0x31: + port2_attached ^= 1<<(i-1); + if(port2_attached < 0) + port2_attached = 0; + if(port2_attached == 0) + *IXP425_GPIO_GPOUTR |= 0x8; + if(SDp->removable == 1){ + sprintf(flash, "flash_sd%c", 'a' + i); + remove_proc_entry(flash, NULL); + remove_proc_entry(media, NULL); + }else{ + sprintf(hdd, "hdd_sd%c", 'a' + i); + remove_proc_entry(hdd,NULL); + remove_proc_entry(media, NULL); + } + break; + case 0x32: + *IXP425_GPIO_GPOUTR |= 0x4; + if(SDp->removable == 1){ + remove_proc_entry("flash_sda",NULL); + } + else + remove_proc_entry("hdd_sda",NULL); + break; + default: + break; + } + #endif + // /* If we are disconnecting a disk driver, sync and invalidate * everything */ sdgd = &SD_GENDISK(i); max_p = sd_gendisk.max_p; start = i << sd_gendisk.minor_shift; -printk("max_p is %d ;start is %d\n",max_p,start); - for (j = max_p - 1; j >= 0; j--) { int index = start + j; - // printk("invalidate_device index = %d\n",index); - invalidate_device(MKDEV_SD_PARTITION(index), 1); + invalidate_device(MKDEV_SD_PARTITION(index), 0); sdgd->part[SD_MINOR_NUMBER(index)].start_sect = 0; sdgd->part[SD_MINOR_NUMBER(index)].nr_sects = 0; sd_sizes[index] = 0; - // printk("MKDEV_SD_PARTITION ok\n"); - } devfs_register_partitions (sdgd, SD_MINOR_NUMBER (start), 1);