# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.166 -> 1.167 # drivers/scsi/sd.c 1.18 -> 1.19 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/02/28 jejb@malley.il.steeleye.com 1.167 # changes in sd driver # # Drive cache set to write back if possible. # -------------------------------------------- # diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c --- a/drivers/scsi/sd.c Thu Feb 28 20:04:49 2002 +++ b/drivers/scsi/sd.c Thu Feb 28 20:04:49 2002 @@ -741,7 +741,7 @@ char nbuff[6]; unsigned char *buffer; unsigned long spintime_value = 0; - int the_result, retries, spintime; + int the_result, retries, spintime, mode_retries; int sector_size; Scsi_Request *SRpnt; @@ -858,6 +858,105 @@ else printk("ready\n"); } + + mode_retries = 2; /* make two attempts to change the cache type */ + + retry_mode_select: + retries = 3; + do { + + memset((void *) &cmd[0], 0, 10); + cmd[0] = MODE_SENSE; + cmd[1] = (rscsi_disks[i].device->scsi_level <= SCSI_2) ? + ((rscsi_disks[i].device->lun << 5) & 0xe0) : 0; + cmd[1] |= 0x08; /* DBD */ + cmd[2] = 0x08; /* current values, cache page */ + cmd[4] = 24; /* allocation length */ + + + memset((void *) buffer, 0, 24); + SRpnt->sr_cmd_len = 0; + SRpnt->sr_sense_buffer[0] = 0; + SRpnt->sr_sense_buffer[2] = 0; + + SRpnt->sr_data_direction = SCSI_DATA_READ; + scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer, + 24, SD_TIMEOUT, MAX_RETRIES); + + the_result = SRpnt->sr_result; + retries--; + + } while (the_result && retries); + + if (the_result) { + printk("%s : MODE SENSE failed.\n" + "%s : status = %x, message = %02x, host = %d, driver = %02x \n", + nbuff, nbuff, + status_byte(the_result), + msg_byte(the_result), + host_byte(the_result), + driver_byte(the_result) + ); + if (driver_byte(the_result) & DRIVER_SENSE) + print_req_sense("sd", SRpnt); + else + printk("%s : sense not available. \n", nbuff); + } else { + const char *types[] = { "write through", "none", "write back", "write back, no read (daft)" }; + int ct = 0; + + ct = (buffer[6] & 0x01 /* RCD */) | ((buffer[6] & 0x04 /* WCE */) >> 1); + + printk("%s : checking drive cache: %s \n", nbuff, types[ct]); + if(ct != 0x0 && mode_retries-- == 0) { + printk("%s : FAILED to change cache to write back, continuing\n", nbuff); + } + else if(ct != 0x0) { + retries = 3; + buffer[6] &= (~0x05); /* clear RCD and WCE */ + do { + memset((void *) &cmd[0], 0, 10); + cmd[0] = MODE_SELECT; + cmd[1] = (rscsi_disks[i].device->scsi_level <= SCSI_2) ? + ((rscsi_disks[i].device->lun << 5) & 0xe0) : 0; + cmd[1] |= 0x10; /* PF */ + cmd[4] = 24; /* allocation length */ + + + SRpnt->sr_cmd_len = 0; + SRpnt->sr_sense_buffer[0] = 0; + SRpnt->sr_sense_buffer[2] = 0; + + SRpnt->sr_data_direction = SCSI_DATA_WRITE; + scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer, + 24, SD_TIMEOUT, MAX_RETRIES); + + the_result = SRpnt->sr_result; + retries--; + + } while (the_result && retries); + + if (the_result) { + printk("%s : MODE SELECT failed.\n" + "%s : status = %x, message = %02x, host = %d, driver = %02x \n", + nbuff, nbuff, + status_byte(the_result), + msg_byte(the_result), + host_byte(the_result), + driver_byte(the_result) + ); + if (driver_byte(the_result) & DRIVER_SENSE) + print_req_sense("sd", SRpnt); + else + printk("%s : sense not available. \n", nbuff); + } else { + printk("%s : changing drive cache to write through\n", nbuff); + } + goto retry_mode_select; + } + + } + retries = 3; do { cmd[0] = READ_CAPACITY;