Commit 5463a13c authored by James Bottomley's avatar James Bottomley

Merge

parents a8c759e0 c9761c4d
...@@ -431,6 +431,11 @@ int unregister_cdrom(struct cdrom_device_info *unreg) ...@@ -431,6 +431,11 @@ int unregister_cdrom(struct cdrom_device_info *unreg)
topCdromPtr = cdi->next; topCdromPtr = cdi->next;
cdi->ops->n_minors--; cdi->ops->n_minors--;
devfs_unregister (cdi->de); devfs_unregister (cdi->de);
if (atomic_read (&cdi->cdrom_driverfs_dev.refcount)) {
device_remove_file (&cdi->cdrom_driverfs_dev, "name");
device_remove_file (&cdi->cdrom_driverfs_dev, "kdev");
put_device (&cdi->cdrom_driverfs_dev);
}
devfs_dealloc_unique_number (&cdrom_numspace, cdi->number); devfs_dealloc_unique_number (&cdrom_numspace, cdi->number);
cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name); cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name);
return 0; return 0;
......
This diff is collapsed.
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#define _53C700_H #define _53C700_H
/* Turn on for general debugging---too verbose for normal use */ /* Turn on for general debugging---too verbose for normal use */
#undef NCR_700_DEBUG #undef NCR_700_DEBUG
/* Debug the tag queues, checking hash queue allocation and deallocation /* Debug the tag queues, checking hash queue allocation and deallocation
* and search for duplicate tags */ * and search for duplicate tags */
#undef NCR_700_TAG_DEBUG #undef NCR_700_TAG_DEBUG
...@@ -189,8 +189,7 @@ struct NCR_700_command_slot { ...@@ -189,8 +189,7 @@ struct NCR_700_command_slot {
#define NCR_700_SLOT_BUSY (1|NCR_700_SLOT_MAGIC) /* slot has command active on HA */ #define NCR_700_SLOT_BUSY (1|NCR_700_SLOT_MAGIC) /* slot has command active on HA */
#define NCR_700_SLOT_QUEUED (2|NCR_700_SLOT_MAGIC) /* slot has command to be made active on HA */ #define NCR_700_SLOT_QUEUED (2|NCR_700_SLOT_MAGIC) /* slot has command to be made active on HA */
__u8 state; __u8 state;
#define NCR_700_NO_TAG 0xdead int tag;
__u16 tag;
__u32 resume_offset; __u32 resume_offset;
Scsi_Cmnd *cmnd; Scsi_Cmnd *cmnd;
/* The pci_mapped address of the actual command in cmnd */ /* The pci_mapped address of the actual command in cmnd */
......
...@@ -1635,14 +1635,14 @@ static int aha1542_old_abort(Scsi_Cmnd * SCpnt) ...@@ -1635,14 +1635,14 @@ static int aha1542_old_abort(Scsi_Cmnd * SCpnt)
if (HOSTDATA(SCpnt->host)->SCint[i]) { if (HOSTDATA(SCpnt->host)->SCint[i]) {
if (HOSTDATA(SCpnt->host)->SCint[i] == SCpnt) { if (HOSTDATA(SCpnt->host)->SCint[i] == SCpnt) {
printk(KERN_ERR "Timed out command pending for %s\n", printk(KERN_ERR "Timed out command pending for %s\n",
kdevname(SCpnt->request.rq_dev)); kdevname(SCpnt->request->rq_dev));
if (HOSTDATA(SCpnt->host)->mb[i].status) { if (HOSTDATA(SCpnt->host)->mb[i].status) {
printk(KERN_ERR "OGMB still full - restarting\n"); printk(KERN_ERR "OGMB still full - restarting\n");
aha1542_out(SCpnt->host->io_port, &ahacmd, 1); aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
}; };
} else } else
printk(KERN_ERR "Other pending command %s\n", printk(KERN_ERR "Other pending command %s\n",
kdevname(SCpnt->request.rq_dev)); kdevname(SCpnt->request->rq_dev));
} }
#endif #endif
......
...@@ -1006,13 +1006,13 @@ print_sense_internal(const char * devclass, ...@@ -1006,13 +1006,13 @@ print_sense_internal(const char * devclass,
void print_sense(const char * devclass, Scsi_Cmnd * SCpnt) void print_sense(const char * devclass, Scsi_Cmnd * SCpnt)
{ {
print_sense_internal(devclass, SCpnt->sense_buffer, print_sense_internal(devclass, SCpnt->sense_buffer,
SCpnt->request.rq_dev); SCpnt->request->rq_dev);
} }
void print_req_sense(const char * devclass, Scsi_Request * SRpnt) void print_req_sense(const char * devclass, Scsi_Request * SRpnt)
{ {
print_sense_internal(devclass, SRpnt->sr_sense_buffer, print_sense_internal(devclass, SRpnt->sr_sense_buffer,
SRpnt->sr_request.rq_dev); SRpnt->sr_request->rq_dev);
} }
#if (CONSTANTS & CONST_MSG) #if (CONSTANTS & CONST_MSG)
......
...@@ -1563,7 +1563,7 @@ static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { ...@@ -1563,7 +1563,7 @@ static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
if (linked_comm && SCpnt->device->queue_depth > 2 if (linked_comm && SCpnt->device->queue_depth > 2
&& TLDEV(SCpnt->device->type)) { && TLDEV(SCpnt->device->type)) {
HD(j)->cp_stat[i] = READY; HD(j)->cp_stat[i] = READY;
flush_dev(SCpnt->device, SCpnt->request.sector, j, FALSE); flush_dev(SCpnt->device, SCpnt->request->sector, j, FALSE);
return 0; return 0;
} }
...@@ -1875,11 +1875,11 @@ static inline int reorder(unsigned int j, unsigned long cursec, ...@@ -1875,11 +1875,11 @@ static inline int reorder(unsigned int j, unsigned long cursec,
if (!cpp->din) input_only = FALSE; if (!cpp->din) input_only = FALSE;
if (SCpnt->request.sector < minsec) minsec = SCpnt->request.sector; if (SCpnt->request->sector < minsec) minsec = SCpnt->request->sector;
if (SCpnt->request.sector > maxsec) maxsec = SCpnt->request.sector; if (SCpnt->request->sector > maxsec) maxsec = SCpnt->request->sector;
sl[n] = SCpnt->request.sector; sl[n] = SCpnt->request->sector;
ioseek += SCpnt->request.nr_sectors; ioseek += SCpnt->request->nr_sectors;
if (!n) continue; if (!n) continue;
...@@ -1907,7 +1907,7 @@ static inline int reorder(unsigned int j, unsigned long cursec, ...@@ -1907,7 +1907,7 @@ static inline int reorder(unsigned int j, unsigned long cursec,
if (!input_only) for (n = 0; n < n_ready; n++) { if (!input_only) for (n = 0; n < n_ready; n++) {
k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt; k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
ll[n] = SCpnt->request.nr_sectors; pl[n] = SCpnt->pid; ll[n] = SCpnt->request->nr_sectors; pl[n] = SCpnt->pid;
if (!n) continue; if (!n) continue;
...@@ -1935,7 +1935,7 @@ static inline int reorder(unsigned int j, unsigned long cursec, ...@@ -1935,7 +1935,7 @@ static inline int reorder(unsigned int j, unsigned long cursec,
" cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n", " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n",
(ihdlr ? "ihdlr" : "qcomm"), SCpnt->channel, SCpnt->target, (ihdlr ? "ihdlr" : "qcomm"), SCpnt->channel, SCpnt->target,
SCpnt->lun, SCpnt->pid, k, flushcount, n_ready, SCpnt->lun, SCpnt->pid, k, flushcount, n_ready,
SCpnt->request.sector, SCpnt->request.nr_sectors, cursec, SCpnt->request->sector, SCpnt->request->nr_sectors, cursec,
YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only), YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only),
YESNO(overlap), cpp->din); YESNO(overlap), cpp->din);
} }
...@@ -2073,7 +2073,7 @@ static inline void ihdlr(int irq, unsigned int j) { ...@@ -2073,7 +2073,7 @@ static inline void ihdlr(int irq, unsigned int j) {
if (linked_comm && SCpnt->device->queue_depth > 2 if (linked_comm && SCpnt->device->queue_depth > 2
&& TLDEV(SCpnt->device->type)) && TLDEV(SCpnt->device->type))
flush_dev(SCpnt->device, SCpnt->request.sector, j, TRUE); flush_dev(SCpnt->device, SCpnt->request->sector, j, TRUE);
tstatus = status_byte(spp->target_status); tstatus = status_byte(spp->target_status);
......
...@@ -230,6 +230,7 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j) ...@@ -230,6 +230,7 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j)
retval->select_queue_depths = tpnt->select_queue_depths; retval->select_queue_depths = tpnt->select_queue_depths;
retval->max_sectors = tpnt->max_sectors; retval->max_sectors = tpnt->max_sectors;
retval->use_blk_tcq = tpnt->use_blk_tcq;
if(!scsi_hostlist) if(!scsi_hostlist)
scsi_hostlist = retval; scsi_hostlist = retval;
......
...@@ -286,6 +286,12 @@ typedef struct SHT ...@@ -286,6 +286,12 @@ typedef struct SHT
unsigned highmem_io:1; unsigned highmem_io:1;
/*
* True if the driver wishes to use the generic block layer
* tag queueing functions
*/
unsigned use_blk_tcq:1;
/* /*
* Name of proc directory * Name of proc directory
*/ */
...@@ -386,6 +392,7 @@ struct Scsi_Host ...@@ -386,6 +392,7 @@ struct Scsi_Host
unsigned unchecked_isa_dma:1; unsigned unchecked_isa_dma:1;
unsigned use_clustering:1; unsigned use_clustering:1;
unsigned highmem_io:1; unsigned highmem_io:1;
unsigned use_blk_tcq:1;
/* /*
* Host has rejected a command because it was busy. * Host has rejected a command because it was busy.
...@@ -418,6 +425,11 @@ struct Scsi_Host ...@@ -418,6 +425,11 @@ struct Scsi_Host
*/ */
struct pci_dev *pci_dev; struct pci_dev *pci_dev;
/*
* Support for driverfs filesystem
*/
struct device host_driverfs_dev;
/* /*
* We should ensure that this is aligned, both for better performance * We should ensure that this is aligned, both for better performance
* and also because some compilers (m68k) don't automatically force * and also because some compilers (m68k) don't automatically force
...@@ -478,6 +490,7 @@ static inline void scsi_set_pci_device(struct Scsi_Host *SHpnt, ...@@ -478,6 +490,7 @@ static inline void scsi_set_pci_device(struct Scsi_Host *SHpnt,
struct pci_dev *pdev) struct pci_dev *pdev)
{ {
SHpnt->pci_dev = pdev; SHpnt->pci_dev = pdev;
SHpnt->host_driverfs_dev.parent=&pdev->dev;
} }
...@@ -516,6 +529,7 @@ struct Scsi_Device_Template ...@@ -516,6 +529,7 @@ struct Scsi_Device_Template
void (*detach)(Scsi_Device *); void (*detach)(Scsi_Device *);
int (*init_command)(Scsi_Cmnd *); /* Used by new queueing code. int (*init_command)(Scsi_Cmnd *); /* Used by new queueing code.
Selects command for blkdevs */ Selects command for blkdevs */
struct device_driver scsi_driverfs_driver;
}; };
void scsi_initialize_queue(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt); void scsi_initialize_queue(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt);
...@@ -555,6 +569,26 @@ extern int scsi_unregister_host(Scsi_Host_Template *); ...@@ -555,6 +569,26 @@ extern int scsi_unregister_host(Scsi_Host_Template *);
#define SD_EXTRA_DEVS CONFIG_SD_EXTRA_DEVS #define SD_EXTRA_DEVS CONFIG_SD_EXTRA_DEVS
#define SR_EXTRA_DEVS CONFIG_SR_EXTRA_DEVS #define SR_EXTRA_DEVS CONFIG_SR_EXTRA_DEVS
/**
* scsi_find_device - find a device given the host
* @channel: SCSI channel (zero if only one channel)
* @pun: SCSI target number (physical unit number)
* @lun: SCSI Logical Unit Number
**/
static inline Scsi_Device *scsi_find_device(struct Scsi_Host *host,
int channel, int pun, int lun) {
Scsi_Device *SDpnt;
for(SDpnt = host->host_queue;
SDpnt != NULL;
SDpnt = SDpnt->next)
if(SDpnt->channel == channel && SDpnt->id == pun
&& SDpnt->lun ==lun)
break;
return SDpnt;
}
#endif #endif
/* /*
* Overrides for Emacs so that we follow Linus's tabbing style. * Overrides for Emacs so that we follow Linus's tabbing style.
......
...@@ -668,7 +668,7 @@ static inline int should_transform(struct ata_device *drive, Scsi_Cmnd *cmd) ...@@ -668,7 +668,7 @@ static inline int should_transform(struct ata_device *drive, Scsi_Cmnd *cmd)
struct Scsi_Host *host = drive->driver_data; struct Scsi_Host *host = drive->driver_data;
idescsi_scsi_t *scsi = idescsi_private(host); idescsi_scsi_t *scsi = idescsi_private(host);
if (major(cmd->request.rq_dev) == SCSI_GENERIC_MAJOR) if (major(cmd->request->rq_dev) == SCSI_GENERIC_MAJOR)
return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
return test_bit(IDESCSI_TRANSFORM, &scsi->transform); return test_bit(IDESCSI_TRANSFORM, &scsi->transform);
} }
......
...@@ -270,7 +270,7 @@ static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt) ...@@ -270,7 +270,7 @@ static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt)
/* Wakeup from interrupt */ /* Wakeup from interrupt */
static void osst_sleep_done (Scsi_Cmnd * SCpnt) static void osst_sleep_done (Scsi_Cmnd * SCpnt)
{ {
unsigned int dev = TAPE_NR(SCpnt->request.rq_dev); unsigned int dev = TAPE_NR(SCpnt->request->rq_dev);
OS_Scsi_Tape * STp; OS_Scsi_Tape * STp;
if (os_scsi_tapes && (STp = os_scsi_tapes[dev])) { if (os_scsi_tapes && (STp = os_scsi_tapes[dev])) {
...@@ -285,13 +285,13 @@ static void osst_sleep_done (Scsi_Cmnd * SCpnt) ...@@ -285,13 +285,13 @@ static void osst_sleep_done (Scsi_Cmnd * SCpnt)
} }
else else
(STp->buffer)->midlevel_result = SCpnt->result; (STp->buffer)->midlevel_result = SCpnt->result;
SCpnt->request.rq_status = RQ_SCSI_DONE; SCpnt->request->rq_status = RQ_SCSI_DONE;
(STp->buffer)->last_SRpnt = SCpnt->sc_request; (STp->buffer)->last_SRpnt = SCpnt->sc_request;
#if DEBUG #if DEBUG
STp->write_pending = 0; STp->write_pending = 0;
#endif #endif
complete(SCpnt->request.waiting); complete(SCpnt->request->waiting);
} }
#if DEBUG #if DEBUG
else if (debugging) else if (debugging)
...@@ -313,7 +313,7 @@ static Scsi_Request * osst_do_scsi(Scsi_Request *SRpnt, OS_Scsi_Tape *STp, ...@@ -313,7 +313,7 @@ static Scsi_Request * osst_do_scsi(Scsi_Request *SRpnt, OS_Scsi_Tape *STp,
#endif #endif
if (SRpnt == NULL) { if (SRpnt == NULL) {
if ((SRpnt = scsi_allocate_request(STp->device)) == NULL) { if ((SRpnt = scsi_allocate_request(STp->device)) == NULL) {
printk(KERN_ERR "osst%d:E: Can't get SCSI request.\n", TAPE_NR(STp->devt)); printk(KERN_ERR "osst%d:E: Can't get SCSI request->\n", TAPE_NR(STp->devt));
if (signal_pending(current)) if (signal_pending(current))
(STp->buffer)->syscall_result = (-EINTR); (STp->buffer)->syscall_result = (-EINTR);
else else
...@@ -336,15 +336,15 @@ static Scsi_Request * osst_do_scsi(Scsi_Request *SRpnt, OS_Scsi_Tape *STp, ...@@ -336,15 +336,15 @@ static Scsi_Request * osst_do_scsi(Scsi_Request *SRpnt, OS_Scsi_Tape *STp,
bp = (STp->buffer)->b_data; bp = (STp->buffer)->b_data;
SRpnt->sr_data_direction = direction; SRpnt->sr_data_direction = direction;
SRpnt->sr_cmd_len = 0; SRpnt->sr_cmd_len = 0;
SRpnt->sr_request.waiting = &(STp->wait); SRpnt->sr_request->waiting = &(STp->wait);
SRpnt->sr_request.rq_status = RQ_SCSI_BUSY; SRpnt->sr_request->rq_status = RQ_SCSI_BUSY;
SRpnt->sr_request.rq_dev = STp->devt; SRpnt->sr_request->rq_dev = STp->devt;
scsi_do_req(SRpnt, (void *)cmd, bp, bytes, osst_sleep_done, timeout, retries); scsi_do_req(SRpnt, (void *)cmd, bp, bytes, osst_sleep_done, timeout, retries);
if (do_wait) { if (do_wait) {
wait_for_completion(SRpnt->sr_request.waiting); wait_for_completion(SRpnt->sr_request->waiting);
SRpnt->sr_request.waiting = NULL; SRpnt->sr_request->waiting = NULL;
STp->buffer->syscall_result = osst_chk_result(STp, SRpnt); STp->buffer->syscall_result = osst_chk_result(STp, SRpnt);
#ifdef OSST_INJECT_ERRORS #ifdef OSST_INJECT_ERRORS
if (STp->buffer->syscall_result == 0 && if (STp->buffer->syscall_result == 0 &&
...@@ -377,7 +377,7 @@ static void osst_write_behind_check(OS_Scsi_Tape *STp) ...@@ -377,7 +377,7 @@ static void osst_write_behind_check(OS_Scsi_Tape *STp)
STp->nbr_finished++; STp->nbr_finished++;
#endif #endif
wait_for_completion(&(STp->wait)); wait_for_completion(&(STp->wait));
(STp->buffer)->last_SRpnt->sr_request.waiting = NULL; (STp->buffer)->last_SRpnt->sr_request->waiting = NULL;
STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt); STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt);
......
...@@ -4236,7 +4236,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, srb_t * sp) ...@@ -4236,7 +4236,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, srb_t * sp)
/* Set transfer direction (READ and WRITE) */ /* Set transfer direction (READ and WRITE) */
/* Linux doesn't tell us */ /* Linux doesn't tell us */
/* /*
* For block devices, cmd->request.cmd has the operation * For block devices, cmd->request->cmd has the operation
* For character devices, this isn't always set properly, so * For character devices, this isn't always set properly, so
* we need to check data_cmnd[0]. This catches the conditions * we need to check data_cmnd[0]. This catches the conditions
* for st.c, but not sg. Generic commands are pass down to us. * for st.c, but not sg. Generic commands are pass down to us.
...@@ -6241,7 +6241,7 @@ qla1280_print_scsi_cmd(Scsi_Cmnd * cmd) ...@@ -6241,7 +6241,7 @@ qla1280_print_scsi_cmd(Scsi_Cmnd * cmd)
cmd->tag, cmd->flags, cmd->transfersize); cmd->tag, cmd->flags, cmd->transfersize);
printk(" Pid=%li, SP=0x%p\n", cmd->pid, CMD_SP(cmd)); printk(" Pid=%li, SP=0x%p\n", cmd->pid, CMD_SP(cmd));
printk(" underflow size = 0x%x, direction=0x%x, req.cmd=0x%x \n", printk(" underflow size = 0x%x, direction=0x%x, req.cmd=0x%x \n",
cmd->underflow, sp->dir, cmd->request.cmd); cmd->underflow, sp->dir, cmd->request->cmd);
} }
/************************************************************************** /**************************************************************************
......
...@@ -258,11 +258,20 @@ __setup("scsi_logging=", scsi_logging_setup); ...@@ -258,11 +258,20 @@ __setup("scsi_logging=", scsi_logging_setup);
static void scsi_wait_done(Scsi_Cmnd * SCpnt) static void scsi_wait_done(Scsi_Cmnd * SCpnt)
{ {
struct request *req; struct request *req = SCpnt->request;
struct request_queue *q = &SCpnt->device->request_queue;
unsigned long flags;
req = &SCpnt->request; ASSERT_LOCK(q->queue_lock, 0);
req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
spin_lock_irqsave(q->queue_lock, flags);
if(blk_rq_tagged(req))
blk_queue_end_tag(q, req);
spin_unlock_irqrestore(q->queue_lock, flags);
if (req->waiting) if (req->waiting)
complete(req->waiting); complete(req->waiting);
} }
...@@ -295,17 +304,19 @@ static spinlock_t device_request_lock = SPIN_LOCK_UNLOCKED; ...@@ -295,17 +304,19 @@ static spinlock_t device_request_lock = SPIN_LOCK_UNLOCKED;
Scsi_Request *scsi_allocate_request(Scsi_Device * device) Scsi_Request *scsi_allocate_request(Scsi_Device * device)
{ {
Scsi_Request *SRpnt = NULL; Scsi_Request *SRpnt = NULL;
const int offset = ALIGN(sizeof(Scsi_Request), 4);
const int size = offset + sizeof(struct request);
if (!device) if (!device)
panic("No device passed to scsi_allocate_request().\n"); panic("No device passed to scsi_allocate_request().\n");
SRpnt = (Scsi_Request *) kmalloc(sizeof(Scsi_Request), GFP_ATOMIC); SRpnt = (Scsi_Request *) kmalloc(size, GFP_ATOMIC);
if( SRpnt == NULL ) if( SRpnt == NULL )
{ {
return NULL; return NULL;
} }
memset(SRpnt, 0, size);
memset(SRpnt, 0, sizeof(Scsi_Request)); SRpnt->sr_request = (struct request *)(((char *)SRpnt) + offset);
SRpnt->sr_device = device; SRpnt->sr_device = device;
SRpnt->sr_host = device->host; SRpnt->sr_host = device->host;
SRpnt->sr_magic = SCSI_REQ_MAGIC; SRpnt->sr_magic = SCSI_REQ_MAGIC;
...@@ -433,7 +444,7 @@ Scsi_Cmnd *scsi_allocate_device(Scsi_Device * device, int wait, ...@@ -433,7 +444,7 @@ Scsi_Cmnd *scsi_allocate_device(Scsi_Device * device, int wait,
* Now we can check for a free command block for this device. * Now we can check for a free command block for this device.
*/ */
for (SCpnt = device->device_queue; SCpnt; SCpnt = SCpnt->next) { for (SCpnt = device->device_queue; SCpnt; SCpnt = SCpnt->next) {
if (SCpnt->request.rq_status == RQ_INACTIVE) if (SCpnt->request == NULL)
break; break;
} }
} }
...@@ -502,9 +513,7 @@ Scsi_Cmnd *scsi_allocate_device(Scsi_Device * device, int wait, ...@@ -502,9 +513,7 @@ Scsi_Cmnd *scsi_allocate_device(Scsi_Device * device, int wait,
} }
} }
SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->request = NULL;
SCpnt->request.waiting = NULL; /* And no one is waiting for this
* to complete */
atomic_inc(&SCpnt->host->host_active); atomic_inc(&SCpnt->host->host_active);
atomic_inc(&SCpnt->device->device_active); atomic_inc(&SCpnt->device->device_active);
...@@ -547,7 +556,7 @@ inline void __scsi_release_command(Scsi_Cmnd * SCpnt) ...@@ -547,7 +556,7 @@ inline void __scsi_release_command(Scsi_Cmnd * SCpnt)
SDpnt = SCpnt->device; SDpnt = SCpnt->device;
SCpnt->request.rq_status = RQ_INACTIVE; SCpnt->request = NULL;
SCpnt->state = SCSI_STATE_UNUSED; SCpnt->state = SCSI_STATE_UNUSED;
SCpnt->owner = SCSI_OWNER_NOBODY; SCpnt->owner = SCSI_OWNER_NOBODY;
atomic_dec(&SCpnt->host->host_active); atomic_dec(&SCpnt->host->host_active);
...@@ -770,13 +779,13 @@ void scsi_wait_req (Scsi_Request * SRpnt, const void *cmnd , ...@@ -770,13 +779,13 @@ void scsi_wait_req (Scsi_Request * SRpnt, const void *cmnd ,
DECLARE_COMPLETION(wait); DECLARE_COMPLETION(wait);
request_queue_t *q = &SRpnt->sr_device->request_queue; request_queue_t *q = &SRpnt->sr_device->request_queue;
SRpnt->sr_request.waiting = &wait; SRpnt->sr_request->waiting = &wait;
SRpnt->sr_request.rq_status = RQ_SCSI_BUSY; SRpnt->sr_request->rq_status = RQ_SCSI_BUSY;
scsi_do_req (SRpnt, (void *) cmnd, scsi_do_req (SRpnt, (void *) cmnd,
buffer, bufflen, scsi_wait_done, timeout, retries); buffer, bufflen, scsi_wait_done, timeout, retries);
generic_unplug_device(q); generic_unplug_device(q);
wait_for_completion(&wait); wait_for_completion(&wait);
SRpnt->sr_request.waiting = NULL; SRpnt->sr_request->waiting = NULL;
if( SRpnt->sr_command != NULL ) if( SRpnt->sr_command != NULL )
{ {
scsi_release_command(SRpnt->sr_command); scsi_release_command(SRpnt->sr_command);
...@@ -927,8 +936,7 @@ void scsi_init_cmd_from_req(Scsi_Cmnd * SCpnt, Scsi_Request * SRpnt) ...@@ -927,8 +936,7 @@ void scsi_init_cmd_from_req(Scsi_Cmnd * SCpnt, Scsi_Request * SRpnt)
SCpnt->cmd_len = SRpnt->sr_cmd_len; SCpnt->cmd_len = SRpnt->sr_cmd_len;
SCpnt->use_sg = SRpnt->sr_use_sg; SCpnt->use_sg = SRpnt->sr_use_sg;
memcpy((void *) &SCpnt->request, (const void *) &SRpnt->sr_request, SCpnt->request = SRpnt->sr_request;
sizeof(SRpnt->sr_request));
memcpy((void *) SCpnt->data_cmnd, (const void *) SRpnt->sr_cmnd, memcpy((void *) SCpnt->data_cmnd, (const void *) SRpnt->sr_cmnd,
sizeof(SCpnt->data_cmnd)); sizeof(SCpnt->data_cmnd));
SCpnt->reset_chain = NULL; SCpnt->reset_chain = NULL;
...@@ -1458,7 +1466,7 @@ void scsi_build_commandblocks(Scsi_Device * SDpnt) ...@@ -1458,7 +1466,7 @@ void scsi_build_commandblocks(Scsi_Device * SDpnt)
SCpnt->target = SDpnt->id; SCpnt->target = SDpnt->id;
SCpnt->lun = SDpnt->lun; SCpnt->lun = SDpnt->lun;
SCpnt->channel = SDpnt->channel; SCpnt->channel = SDpnt->channel;
SCpnt->request.rq_status = RQ_INACTIVE; SCpnt->request = NULL;
SCpnt->use_sg = 0; SCpnt->use_sg = 0;
SCpnt->old_use_sg = 0; SCpnt->old_use_sg = 0;
SCpnt->old_cmd_len = 0; SCpnt->old_cmd_len = 0;
...@@ -1910,6 +1918,11 @@ int scsi_register_host(Scsi_Host_Template * tpnt) ...@@ -1910,6 +1918,11 @@ int scsi_register_host(Scsi_Host_Template * tpnt)
} }
printk(KERN_INFO "scsi%d : %s\n", /* And print a little message */ printk(KERN_INFO "scsi%d : %s\n", /* And print a little message */
shpnt->host_no, name); shpnt->host_no, name);
strncpy(shpnt->host_driverfs_dev.name,name,
DEVICE_NAME_SIZE-1);
sprintf(shpnt->host_driverfs_dev.bus_id,
"scsi%d",
shpnt->host_no);
} }
} }
...@@ -1918,6 +1931,8 @@ int scsi_register_host(Scsi_Host_Template * tpnt) ...@@ -1918,6 +1931,8 @@ int scsi_register_host(Scsi_Host_Template * tpnt)
*/ */
for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) { for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) {
if (shpnt->hostt == tpnt) { if (shpnt->hostt == tpnt) {
/* first register parent with driverfs */
device_register(&shpnt->host_driverfs_dev);
scan_scsis(shpnt, 0, 0, 0, 0); scan_scsis(shpnt, 0, 0, 0, 0);
if (shpnt->select_queue_depths != NULL) { if (shpnt->select_queue_depths != NULL) {
(shpnt->select_queue_depths) (shpnt, shpnt->host_queue); (shpnt->select_queue_depths) (shpnt, shpnt->host_queue);
...@@ -2030,16 +2045,16 @@ int scsi_unregister_host(Scsi_Host_Template * tpnt) ...@@ -2030,16 +2045,16 @@ int scsi_unregister_host(Scsi_Host_Template * tpnt)
SCpnt = SCpnt->next) { SCpnt = SCpnt->next) {
online_status = SDpnt->online; online_status = SDpnt->online;
SDpnt->online = FALSE; SDpnt->online = FALSE;
if (SCpnt->request.rq_status != RQ_INACTIVE) { if (SCpnt->request && SCpnt->request->rq_status != RQ_INACTIVE) {
printk(KERN_ERR "SCSI device not inactive - rq_status=%d, target=%d, pid=%ld, state=%d, owner=%d.\n", printk(KERN_ERR "SCSI device not inactive - rq_status=%d, target=%d, pid=%ld, state=%d, owner=%d.\n",
SCpnt->request.rq_status, SCpnt->target, SCpnt->pid, SCpnt->request->rq_status, SCpnt->target, SCpnt->pid,
SCpnt->state, SCpnt->owner); SCpnt->state, SCpnt->owner);
for (SDpnt1 = shpnt->host_queue; SDpnt1; for (SDpnt1 = shpnt->host_queue; SDpnt1;
SDpnt1 = SDpnt1->next) { SDpnt1 = SDpnt1->next) {
for (SCpnt = SDpnt1->device_queue; SCpnt; for (SCpnt = SDpnt1->device_queue; SCpnt;
SCpnt = SCpnt->next) SCpnt = SCpnt->next)
if (SCpnt->request.rq_status == RQ_SCSI_DISCONNECTING) if (SCpnt->request->rq_status == RQ_SCSI_DISCONNECTING)
SCpnt->request.rq_status = RQ_INACTIVE; SCpnt->request->rq_status = RQ_INACTIVE;
} }
SDpnt->online = online_status; SDpnt->online = online_status;
printk(KERN_ERR "Device busy???\n"); printk(KERN_ERR "Device busy???\n");
...@@ -2050,7 +2065,8 @@ int scsi_unregister_host(Scsi_Host_Template * tpnt) ...@@ -2050,7 +2065,8 @@ int scsi_unregister_host(Scsi_Host_Template * tpnt)
* continue on. * continue on.
*/ */
SCpnt->state = SCSI_STATE_DISCONNECTING; SCpnt->state = SCSI_STATE_DISCONNECTING;
SCpnt->request.rq_status = RQ_SCSI_DISCONNECTING; /* Mark as busy */ if(SCpnt->request)
SCpnt->request->rq_status = RQ_SCSI_DISCONNECTING; /* Mark as busy */
} }
} }
} }
...@@ -2072,6 +2088,7 @@ int scsi_unregister_host(Scsi_Host_Template * tpnt) ...@@ -2072,6 +2088,7 @@ int scsi_unregister_host(Scsi_Host_Template * tpnt)
goto err_out; goto err_out;
} }
devfs_unregister (SDpnt->de); devfs_unregister (SDpnt->de);
put_device(&SDpnt->sdev_driverfs_dev);
} }
} }
...@@ -2122,6 +2139,7 @@ int scsi_unregister_host(Scsi_Host_Template * tpnt) ...@@ -2122,6 +2139,7 @@ int scsi_unregister_host(Scsi_Host_Template * tpnt)
/* Remove the /proc/scsi directory entry */ /* Remove the /proc/scsi directory entry */
sprintf(name,"%d",shpnt->host_no); sprintf(name,"%d",shpnt->host_no);
remove_proc_entry(name, tpnt->proc_dir); remove_proc_entry(name, tpnt->proc_dir);
put_device(&shpnt->host_driverfs_dev);
if (tpnt->release) if (tpnt->release)
(*tpnt->release) (shpnt); (*tpnt->release) (shpnt);
else { else {
...@@ -2360,11 +2378,11 @@ static void scsi_dump_status(int level) ...@@ -2360,11 +2378,11 @@ static void scsi_dump_status(int level)
SCpnt->target, SCpnt->target,
SCpnt->lun, SCpnt->lun,
kdevname(SCpnt->request.rq_dev), kdevname(SCpnt->request->rq_dev),
SCpnt->request.sector, SCpnt->request->sector,
SCpnt->request.nr_sectors, SCpnt->request->nr_sectors,
(long)SCpnt->request.current_nr_sectors, (long)SCpnt->request->current_nr_sectors,
SCpnt->request.rq_status, SCpnt->request->rq_status,
SCpnt->use_sg, SCpnt->use_sg,
SCpnt->retries, SCpnt->retries,
...@@ -2470,6 +2488,34 @@ void scsi_free_sgtable(struct scatterlist *sgl, int index) ...@@ -2470,6 +2488,34 @@ void scsi_free_sgtable(struct scatterlist *sgl, int index)
mempool_free(sgl, sgp->pool); mempool_free(sgl, sgp->pool);
} }
static int scsi_bus_match(struct device *scsi_driverfs_dev,
struct device_driver *scsi_driverfs_drv)
{
char *p=0;
if (!strcmp("sd", scsi_driverfs_drv->name)) {
if ((p = strstr(scsi_driverfs_dev->bus_id, ":disc")) ||
(p = strstr(scsi_driverfs_dev->bus_id, ":p"))) {
return 1;
}
} else if (!strcmp("sg", scsi_driverfs_drv->name)) {
if (strstr(scsi_driverfs_dev->bus_id, ":gen"))
return 1;
} else if (!strcmp("sr",scsi_driverfs_drv->name)) {
if (strstr(scsi_driverfs_dev->bus_id,":cd"))
return 1;
} else if (!strcmp("st",scsi_driverfs_drv->name)) {
if (strstr(scsi_driverfs_dev->bus_id,":mt"))
return 1;
}
return 0;
}
struct bus_type scsi_driverfs_bus_type = {
name: "scsi",
match: scsi_bus_match,
};
static int __init init_scsi(void) static int __init init_scsi(void)
{ {
struct proc_dir_entry *generic; struct proc_dir_entry *generic;
...@@ -2516,6 +2562,8 @@ static int __init init_scsi(void) ...@@ -2516,6 +2562,8 @@ static int __init init_scsi(void)
printk(KERN_INFO "scsi: host order: %s\n", scsihosts); printk(KERN_INFO "scsi: host order: %s\n", scsihosts);
scsi_host_no_init (scsihosts); scsi_host_no_init (scsihosts);
bus_register(&scsi_driverfs_bus_type);
/* Where we handle work queued by scsi_done */ /* Where we handle work queued by scsi_done */
open_softirq(SCSI_SOFTIRQ, scsi_softirq, NULL); open_softirq(SCSI_SOFTIRQ, scsi_softirq, NULL);
...@@ -2677,16 +2725,18 @@ int ...@@ -2677,16 +2725,18 @@ int
scsi_reset_provider(Scsi_Device *dev, int flag) scsi_reset_provider(Scsi_Device *dev, int flag)
{ {
Scsi_Cmnd SC, *SCpnt = &SC; Scsi_Cmnd SC, *SCpnt = &SC;
struct request req;
int rtn; int rtn;
SCpnt->request = &req;
memset(&SCpnt->eh_timeout, 0, sizeof(SCpnt->eh_timeout)); memset(&SCpnt->eh_timeout, 0, sizeof(SCpnt->eh_timeout));
SCpnt->host = dev->host; SCpnt->host = dev->host;
SCpnt->device = dev; SCpnt->device = dev;
SCpnt->target = dev->id; SCpnt->target = dev->id;
SCpnt->lun = dev->lun; SCpnt->lun = dev->lun;
SCpnt->channel = dev->channel; SCpnt->channel = dev->channel;
SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->request->rq_status = RQ_SCSI_BUSY;
SCpnt->request.waiting = NULL; SCpnt->request->waiting = NULL;
SCpnt->use_sg = 0; SCpnt->use_sg = 0;
SCpnt->old_use_sg = 0; SCpnt->old_use_sg = 0;
SCpnt->old_cmd_len = 0; SCpnt->old_cmd_len = 0;
......
...@@ -417,6 +417,8 @@ extern unsigned int scsi_need_isa_buffer; /* True if some devices need indirecti ...@@ -417,6 +417,8 @@ extern unsigned int scsi_need_isa_buffer; /* True if some devices need indirecti
extern volatile int in_scan_scsis; extern volatile int in_scan_scsis;
extern const unsigned char scsi_command_size[8]; extern const unsigned char scsi_command_size[8];
extern struct bus_type scsi_driverfs_bus_type;
/* /*
* These are the error handling functions defined in scsi_error.c * These are the error handling functions defined in scsi_error.c
...@@ -566,6 +568,7 @@ struct scsi_device { ...@@ -566,6 +568,7 @@ struct scsi_device {
atomic_t device_active; /* commands checked out for device */ atomic_t device_active; /* commands checked out for device */
volatile unsigned short device_busy; /* commands actually active on low-level */ volatile unsigned short device_busy; /* commands actually active on low-level */
Scsi_Cmnd *device_queue; /* queue of SCSI Command structures */ Scsi_Cmnd *device_queue; /* queue of SCSI Command structures */
Scsi_Cmnd *current_cmnd; /* currently active command */
unsigned int id, lun, channel; unsigned int id, lun, channel;
...@@ -622,6 +625,7 @@ struct scsi_device { ...@@ -622,6 +625,7 @@ struct scsi_device {
// Flag to allow revalidate to succeed in sd_open // Flag to allow revalidate to succeed in sd_open
int allow_revalidate; int allow_revalidate;
struct device sdev_driverfs_dev;
}; };
...@@ -662,7 +666,7 @@ struct scsi_request { ...@@ -662,7 +666,7 @@ struct scsi_request {
struct Scsi_Host *sr_host; struct Scsi_Host *sr_host;
Scsi_Device *sr_device; Scsi_Device *sr_device;
Scsi_Cmnd *sr_command; Scsi_Cmnd *sr_command;
struct request sr_request; /* A copy of the command we are struct request *sr_request; /* A copy of the command we are
working on */ working on */
unsigned sr_bufflen; /* Size of data buffer */ unsigned sr_bufflen; /* Size of data buffer */
void *sr_buffer; /* Data buffer */ void *sr_buffer; /* Data buffer */
...@@ -773,8 +777,8 @@ struct scsi_cmnd { ...@@ -773,8 +777,8 @@ struct scsi_cmnd {
transferred less actual number transferred less actual number
transferred (0 if not supported) */ transferred (0 if not supported) */
struct request request; /* A copy of the command we are struct request *request; /* The command we are
working on */ working on */
unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE]; /* obtained by REQUEST SENSE unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE]; /* obtained by REQUEST SENSE
* when CHECK CONDITION is * when CHECK CONDITION is
...@@ -856,4 +860,87 @@ struct scsi_cmnd { ...@@ -856,4 +860,87 @@ struct scsi_cmnd {
extern int scsi_reset_provider(Scsi_Device *, int); extern int scsi_reset_provider(Scsi_Device *, int);
/**
* scsi_activate_tcq - turn on tag command queueing
* @SDpnt: device to turn on TCQ for
* @depth: queue depth
*
* Notes:
* Eventually, I hope depth would be the maximum depth
* the device could cope with and the real queue depth
* would be adjustable from 0 to depth.
**/
static inline void scsi_activate_tcq(Scsi_Device *SDpnt, int depth) {
request_queue_t *q = &SDpnt->request_queue;
if(SDpnt->tagged_supported && !blk_queue_tagged(q)) {
blk_queue_init_tags(q, depth);
SDpnt->tagged_queue = 1;
}
}
/**
* scsi_deactivate_tcq - turn off tag command queueing
* @SDpnt: device to turn off TCQ for
**/
static inline void scsi_deactivate_tcq(Scsi_Device *SDpnt) {
blk_queue_free_tags(&SDpnt->request_queue);
SDpnt->tagged_queue = 0;
}
#define MSG_SIMPLE_TAG 0x20
#define MSG_HEAD_TAG 0x21
#define MSG_ORDERED_TAG 0x22
#define SCSI_NO_TAG (-1) /* identify no tag in use */
/**
* scsi_populate_tag_msg - place a tag message in a buffer
* @SCpnt: pointer to the Scsi_Cmnd for the tag
* @msg: pointer to the area to place the tag
*
* Notes:
* designed to create the correct type of tag message for the
* particular request. Returns the size of the tag message.
* May return 0 if TCQ is disabled for this device.
**/
static inline int scsi_populate_tag_msg(Scsi_Cmnd *SCpnt, char *msg) {
struct request *req = SCpnt->request;
if(!blk_rq_tagged(req))
return 0;
if(req->flags & REQ_BARRIER)
*msg++ = MSG_ORDERED_TAG;
else
*msg++ = MSG_SIMPLE_TAG;
*msg++ = SCpnt->request->tag;
return 2;
}
/**
* scsi_find_tag - find a tagged command by device
* @SDpnt: pointer to the ScSI device
* @tag: the tag number
*
* Notes:
* Only works with tags allocated by the generic blk layer.
**/
static inline Scsi_Cmnd *scsi_find_tag(Scsi_Device *SDpnt, int tag) {
struct request *req;
if(tag == SCSI_NO_TAG)
/* single command, look in space */
return SDpnt->current_cmnd;
req = blk_queue_find_tag(&SDpnt->request_queue, tag);
if(req == NULL)
return NULL;
return (Scsi_Cmnd *)req->special;
}
#endif #endif
...@@ -694,7 +694,7 @@ static int scsi_debug_read(Scsi_Cmnd * SCpnt, int upper_blk, int block, ...@@ -694,7 +694,7 @@ static int scsi_debug_read(Scsi_Cmnd * SCpnt, int upper_blk, int block,
{ {
int delay = SCSI_SETUP_LATENCY; int delay = SCSI_SETUP_LATENCY;
delay += SCpnt->request.nr_sectors * SCSI_DATARATE; delay += SCpnt->request->nr_sectors * SCSI_DATARATE;
if (delay) if (delay)
usleep(delay); usleep(delay);
} }
......
...@@ -319,7 +319,7 @@ void scsi_eh_done(Scsi_Cmnd * SCpnt) ...@@ -319,7 +319,7 @@ void scsi_eh_done(Scsi_Cmnd * SCpnt)
return; return;
} }
SCpnt->request.rq_status = RQ_SCSI_DONE; SCpnt->request->rq_status = RQ_SCSI_DONE;
SCpnt->owner = SCSI_OWNER_ERROR_HANDLER; SCpnt->owner = SCSI_OWNER_ERROR_HANDLER;
SCpnt->eh_state = SUCCESS; SCpnt->eh_state = SUCCESS;
...@@ -346,7 +346,7 @@ void scsi_eh_done(Scsi_Cmnd * SCpnt) ...@@ -346,7 +346,7 @@ void scsi_eh_done(Scsi_Cmnd * SCpnt)
STATIC STATIC
void scsi_eh_action_done(Scsi_Cmnd * SCpnt, int answer) void scsi_eh_action_done(Scsi_Cmnd * SCpnt, int answer)
{ {
SCpnt->request.rq_status = RQ_SCSI_DONE; SCpnt->request->rq_status = RQ_SCSI_DONE;
SCpnt->owner = SCSI_OWNER_ERROR_HANDLER; SCpnt->owner = SCSI_OWNER_ERROR_HANDLER;
SCpnt->eh_state = (answer ? SUCCESS : FAILED); SCpnt->eh_state = (answer ? SUCCESS : FAILED);
...@@ -601,7 +601,7 @@ STATIC void scsi_send_eh_cmnd(Scsi_Cmnd * SCpnt, int timeout) ...@@ -601,7 +601,7 @@ STATIC void scsi_send_eh_cmnd(Scsi_Cmnd * SCpnt, int timeout)
* Set up the semaphore so we wait for the command to complete. * Set up the semaphore so we wait for the command to complete.
*/ */
SCpnt->host->eh_action = &sem; SCpnt->host->eh_action = &sem;
SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->request->rq_status = RQ_SCSI_BUSY;
spin_lock_irqsave(SCpnt->host->host_lock, flags); spin_lock_irqsave(SCpnt->host->host_lock, flags);
host->hostt->queuecommand(SCpnt, scsi_eh_done); host->hostt->queuecommand(SCpnt, scsi_eh_done);
...@@ -633,7 +633,7 @@ STATIC void scsi_send_eh_cmnd(Scsi_Cmnd * SCpnt, int timeout) ...@@ -633,7 +633,7 @@ STATIC void scsi_send_eh_cmnd(Scsi_Cmnd * SCpnt, int timeout)
SCpnt->host->hostt->eh_abort_handler(SCpnt); SCpnt->host->hostt->eh_abort_handler(SCpnt);
spin_unlock_irqrestore(SCpnt->host->host_lock, flags); spin_unlock_irqrestore(SCpnt->host->host_lock, flags);
SCpnt->request.rq_status = RQ_SCSI_DONE; SCpnt->request->rq_status = RQ_SCSI_DONE;
SCpnt->owner = SCSI_OWNER_ERROR_HANDLER; SCpnt->owner = SCSI_OWNER_ERROR_HANDLER;
SCpnt->eh_state = FAILED; SCpnt->eh_state = FAILED;
......
...@@ -76,12 +76,10 @@ static void __scsi_insert_special(request_queue_t *q, struct request *rq, ...@@ -76,12 +76,10 @@ static void __scsi_insert_special(request_queue_t *q, struct request *rq,
* must not attempt merges on this) and that it acts as a soft * must not attempt merges on this) and that it acts as a soft
* barrier * barrier
*/ */
rq->flags = REQ_SPECIAL | REQ_BARRIER; rq->flags &= REQ_QUEUED;
rq->flags |= REQ_SPECIAL | REQ_BARRIER;
rq->special = data; rq->special = data;
rq->q = NULL;
rq->bio = rq->biotail = NULL;
rq->nr_phys_segments = 0;
/* /*
* We have the option of inserting the head or the tail of the queue. * We have the option of inserting the head or the tail of the queue.
...@@ -90,6 +88,9 @@ static void __scsi_insert_special(request_queue_t *q, struct request *rq, ...@@ -90,6 +88,9 @@ static void __scsi_insert_special(request_queue_t *q, struct request *rq,
* device, or a host that is unable to accept a particular command. * device, or a host that is unable to accept a particular command.
*/ */
spin_lock_irqsave(q->queue_lock, flags); spin_lock_irqsave(q->queue_lock, flags);
/* If command is tagged, release the tag */
if(blk_rq_tagged(rq))
blk_queue_end_tag(q, rq);
_elv_add_request(q, rq, !at_head, 0); _elv_add_request(q, rq, !at_head, 0);
q->request_fn(q); q->request_fn(q);
spin_unlock_irqrestore(q->queue_lock, flags); spin_unlock_irqrestore(q->queue_lock, flags);
...@@ -120,7 +121,7 @@ int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int at_head) ...@@ -120,7 +121,7 @@ int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int at_head)
{ {
request_queue_t *q = &SCpnt->device->request_queue; request_queue_t *q = &SCpnt->device->request_queue;
__scsi_insert_special(q, &SCpnt->request, SCpnt, at_head); __scsi_insert_special(q, SCpnt->request, SCpnt, at_head);
return 0; return 0;
} }
...@@ -148,7 +149,7 @@ int scsi_insert_special_req(Scsi_Request * SRpnt, int at_head) ...@@ -148,7 +149,7 @@ int scsi_insert_special_req(Scsi_Request * SRpnt, int at_head)
{ {
request_queue_t *q = &SRpnt->sr_device->request_queue; request_queue_t *q = &SRpnt->sr_device->request_queue;
__scsi_insert_special(q, &SRpnt->sr_request, SRpnt, at_head); __scsi_insert_special(q, SRpnt->sr_request, SRpnt, at_head);
return 0; return 0;
} }
...@@ -259,8 +260,10 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt) ...@@ -259,8 +260,10 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
* in which case we need to request the blocks that come after * in which case we need to request the blocks that come after
* the bad sector. * the bad sector.
*/ */
SCpnt->request.special = (void *) SCpnt; SCpnt->request->special = (void *) SCpnt;
_elv_add_request(q, &SCpnt->request, 0, 0); if(blk_rq_tagged(SCpnt->request))
blk_queue_end_tag(q, SCpnt->request);
_elv_add_request(q, SCpnt->request, 0, 0);
} }
/* /*
...@@ -356,15 +359,18 @@ static Scsi_Cmnd *__scsi_end_request(Scsi_Cmnd * SCpnt, ...@@ -356,15 +359,18 @@ static Scsi_Cmnd *__scsi_end_request(Scsi_Cmnd * SCpnt,
int frequeue) int frequeue)
{ {
request_queue_t *q = &SCpnt->device->request_queue; request_queue_t *q = &SCpnt->device->request_queue;
struct request *req = &SCpnt->request; struct request *req = SCpnt->request;
int flags;
ASSERT_LOCK(q->queue_lock, 0); ASSERT_LOCK(q->queue_lock, 0);
spin_lock_irqsave(q->queue_lock, flags);
/* /*
* If there are blocks left over at the end, set up the command * If there are blocks left over at the end, set up the command
* to queue the remainder of them. * to queue the remainder of them.
*/ */
if (end_that_request_first(req, uptodate, sectors)) { if (end_that_request_first(req, uptodate, sectors)) {
spin_unlock_irqrestore(q->queue_lock, flags);
if (!requeue) if (!requeue)
return SCpnt; return SCpnt;
...@@ -376,15 +382,15 @@ static Scsi_Cmnd *__scsi_end_request(Scsi_Cmnd * SCpnt, ...@@ -376,15 +382,15 @@ static Scsi_Cmnd *__scsi_end_request(Scsi_Cmnd * SCpnt,
return SCpnt; return SCpnt;
} }
/*
* This request is done. If there is someone blocked waiting for this
* request, wake them up.
*/
if (req->waiting)
complete(req->waiting);
add_blkdev_randomness(major(req->rq_dev)); add_blkdev_randomness(major(req->rq_dev));
if(blk_rq_tagged(req))
blk_queue_end_tag(q, req);
end_that_request_last(req);
spin_unlock_irqrestore(q->queue_lock, flags);
/* /*
* This will goose the queue request function at the end, so we don't * This will goose the queue request function at the end, so we don't
* need to worry about launching another command. * need to worry about launching another command.
...@@ -441,7 +447,7 @@ Scsi_Cmnd *scsi_end_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors) ...@@ -441,7 +447,7 @@ Scsi_Cmnd *scsi_end_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors)
*/ */
static void scsi_release_buffers(Scsi_Cmnd * SCpnt) static void scsi_release_buffers(Scsi_Cmnd * SCpnt)
{ {
struct request *req = &SCpnt->request; struct request *req = SCpnt->request;
ASSERT_LOCK(SCpnt->host->host_lock, 0); ASSERT_LOCK(SCpnt->host->host_lock, 0);
...@@ -491,7 +497,7 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors, ...@@ -491,7 +497,7 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
int result = SCpnt->result; int result = SCpnt->result;
int this_count = SCpnt->bufflen >> 9; int this_count = SCpnt->bufflen >> 9;
request_queue_t *q = &SCpnt->device->request_queue; request_queue_t *q = &SCpnt->device->request_queue;
struct request *req = &SCpnt->request; struct request *req = SCpnt->request;
/* /*
* We must do one of several things here: * We must do one of several things here:
...@@ -675,7 +681,7 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors, ...@@ -675,7 +681,7 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
if (result) { if (result) {
struct Scsi_Device_Template *STpnt; struct Scsi_Device_Template *STpnt;
STpnt = scsi_get_request_dev(&SCpnt->request); STpnt = scsi_get_request_dev(SCpnt->request);
printk("SCSI %s error : host %d channel %d id %d lun %d return code = %x\n", printk("SCSI %s error : host %d channel %d id %d lun %d return code = %x\n",
(STpnt ? STpnt->name : "device"), (STpnt ? STpnt->name : "device"),
SCpnt->device->host->host_no, SCpnt->device->host->host_no,
...@@ -868,7 +874,7 @@ void scsi_request_fn(request_queue_t * q) ...@@ -868,7 +874,7 @@ void scsi_request_fn(request_queue_t * q)
* the remainder of a partially fulfilled request that can * the remainder of a partially fulfilled request that can
* come up when there is a medium error. We have to treat * come up when there is a medium error. We have to treat
* these two cases differently. We differentiate by looking * these two cases differently. We differentiate by looking
* at request.cmd, as this tells us the real story. * at request->cmd, as this tells us the real story.
*/ */
if (req->flags & REQ_SPECIAL) { if (req->flags & REQ_SPECIAL) {
STpnt = NULL; STpnt = NULL;
...@@ -904,6 +910,9 @@ void scsi_request_fn(request_queue_t * q) ...@@ -904,6 +910,9 @@ void scsi_request_fn(request_queue_t * q)
*/ */
if (!SCpnt) if (!SCpnt)
break; break;
/* pull a tag out of the request if we have one */
SCpnt->tag = req->tag;
} else { } else {
blk_dump_rq_flags(req, "SCSI bad req"); blk_dump_rq_flags(req, "SCSI bad req");
break; break;
...@@ -924,18 +933,15 @@ void scsi_request_fn(request_queue_t * q) ...@@ -924,18 +933,15 @@ void scsi_request_fn(request_queue_t * q)
* reason to search the list, because all of the commands * reason to search the list, because all of the commands
* in this queue are for the same device. * in this queue are for the same device.
*/ */
blkdev_dequeue_request(req); if(!(blk_queue_tagged(q) && (blk_queue_start_tag(q, req) == 0)))
blkdev_dequeue_request(req);
if (req != &SCpnt->request && req != &SRpnt->sr_request ) { /* note the overloading of req->special. When the tag
memcpy(&SCpnt->request, req, sizeof(struct request)); * is active it always means SCpnt. If the tag goes
* back for re-queueing, it may be reset */
req->special = SCpnt;
SCpnt->request = req;
/*
* We have copied the data out of the request block -
* it is now in a field in SCpnt. Release the request
* block.
*/
blkdev_release_request(req);
}
/* /*
* Now it is finally safe to release the lock. We are * Now it is finally safe to release the lock. We are
* not going to noodle the request list until this * not going to noodle the request list until this
...@@ -945,7 +951,7 @@ void scsi_request_fn(request_queue_t * q) ...@@ -945,7 +951,7 @@ void scsi_request_fn(request_queue_t * q)
req = NULL; req = NULL;
spin_unlock_irq(q->queue_lock); spin_unlock_irq(q->queue_lock);
if (SCpnt->request.flags & REQ_CMD) { if (SCpnt->request->flags & REQ_CMD) {
/* /*
* This will do a couple of things: * This will do a couple of things:
* 1) Fill in the actual SCSI command. * 1) Fill in the actual SCSI command.
...@@ -959,7 +965,7 @@ void scsi_request_fn(request_queue_t * q) ...@@ -959,7 +965,7 @@ void scsi_request_fn(request_queue_t * q)
* request to be rejected immediately. * request to be rejected immediately.
*/ */
if (STpnt == NULL) if (STpnt == NULL)
STpnt = scsi_get_request_dev(&SCpnt->request); STpnt = scsi_get_request_dev(SCpnt->request);
/* /*
* This sets up the scatter-gather table (allocating if * This sets up the scatter-gather table (allocating if
...@@ -973,9 +979,11 @@ void scsi_request_fn(request_queue_t * q) ...@@ -973,9 +979,11 @@ void scsi_request_fn(request_queue_t * q)
SDpnt->starved = 1; SDpnt->starved = 1;
SHpnt->some_device_starved = 1; SHpnt->some_device_starved = 1;
} }
SCpnt->request.special = SCpnt; SCpnt->request->special = SCpnt;
SCpnt->request.flags |= REQ_SPECIAL; SCpnt->request->flags |= REQ_SPECIAL;
_elv_add_request(q, &SCpnt->request, 0, 0); if(blk_rq_tagged(SCpnt->request))
blk_queue_end_tag(q, SCpnt->request);
_elv_add_request(q, SCpnt->request, 0, 0);
break; break;
} }
...@@ -985,7 +993,7 @@ void scsi_request_fn(request_queue_t * q) ...@@ -985,7 +993,7 @@ void scsi_request_fn(request_queue_t * q)
if (!STpnt->init_command(SCpnt)) { if (!STpnt->init_command(SCpnt)) {
scsi_release_buffers(SCpnt); scsi_release_buffers(SCpnt);
SCpnt = __scsi_end_request(SCpnt, 0, SCpnt = __scsi_end_request(SCpnt, 0,
SCpnt->request.nr_sectors, 0, 0); SCpnt->request->nr_sectors, 0, 0);
if( SCpnt != NULL ) if( SCpnt != NULL )
{ {
panic("Should not have leftover blocks\n"); panic("Should not have leftover blocks\n");
......
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
*/ */
int scsi_init_io(Scsi_Cmnd *SCpnt) int scsi_init_io(Scsi_Cmnd *SCpnt)
{ {
struct request *req = &SCpnt->request; struct request *req = SCpnt->request;
struct scatterlist *sgpnt; struct scatterlist *sgpnt;
int count, gfp_mask; int count, gfp_mask;
......
This diff is collapsed.
...@@ -101,3 +101,8 @@ extern void scsi_add_timer(Scsi_Cmnd *, int, void ((*) (Scsi_Cmnd *))); ...@@ -101,3 +101,8 @@ extern void scsi_add_timer(Scsi_Cmnd *, int, void ((*) (Scsi_Cmnd *)));
extern int scsi_delete_timer(Scsi_Cmnd *); extern int scsi_delete_timer(Scsi_Cmnd *);
EXPORT_SYMBOL(scsi_add_timer); EXPORT_SYMBOL(scsi_add_timer);
EXPORT_SYMBOL(scsi_delete_timer); EXPORT_SYMBOL(scsi_delete_timer);
/*
* driverfs support for determining driver types
*/
EXPORT_SYMBOL(scsi_driverfs_bus_type);
...@@ -129,6 +129,7 @@ static void sd_rw_intr(Scsi_Cmnd * SCpnt); ...@@ -129,6 +129,7 @@ static void sd_rw_intr(Scsi_Cmnd * SCpnt);
static Scsi_Disk * sd_get_sdisk(int index); static Scsi_Disk * sd_get_sdisk(int index);
extern void driverfs_remove_partitions(struct gendisk *hd, int minor);
#if defined(CONFIG_PPC32) #if defined(CONFIG_PPC32)
/** /**
...@@ -327,13 +328,13 @@ static int sd_init_command(Scsi_Cmnd * SCpnt) ...@@ -327,13 +328,13 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
/* /*
* don't support specials for nwo * don't support specials for nwo
*/ */
if (!(SCpnt->request.flags & REQ_CMD)) if (!(SCpnt->request->flags & REQ_CMD))
return 0; return 0;
part_nr = SD_PARTITION(SCpnt->request.rq_dev); part_nr = SD_PARTITION(SCpnt->request->rq_dev);
dsk_nr = DEVICE_NR(SCpnt->request.rq_dev); dsk_nr = DEVICE_NR(SCpnt->request->rq_dev);
block = SCpnt->request.sector; block = SCpnt->request->sector;
this_count = SCpnt->request_bufflen >> 9; this_count = SCpnt->request_bufflen >> 9;
SCSI_LOG_HLQUEUE(1, printk("sd_command_init: dsk_nr=%d, block=%d, " SCSI_LOG_HLQUEUE(1, printk("sd_command_init: dsk_nr=%d, block=%d, "
...@@ -344,9 +345,9 @@ static int sd_init_command(Scsi_Cmnd * SCpnt) ...@@ -344,9 +345,9 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
/* >>>>> this change is not in the lk 2.5 series */ /* >>>>> this change is not in the lk 2.5 series */
if (part_nr >= (sd_template.dev_max << 4) || (part_nr & 0xf) || if (part_nr >= (sd_template.dev_max << 4) || (part_nr & 0xf) ||
!sdp || !sdp->online || !sdp || !sdp->online ||
block + SCpnt->request.nr_sectors > sd[part_nr].nr_sects) { block + SCpnt->request->nr_sectors > sd[part_nr].nr_sects) {
SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n",
SCpnt->request.nr_sectors)); SCpnt->request->nr_sectors));
SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt)); SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt));
return 0; return 0;
} }
...@@ -375,7 +376,7 @@ static int sd_init_command(Scsi_Cmnd * SCpnt) ...@@ -375,7 +376,7 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
* for this. * for this.
*/ */
if (sdp->sector_size == 1024) { if (sdp->sector_size == 1024) {
if ((block & 1) || (SCpnt->request.nr_sectors & 1)) { if ((block & 1) || (SCpnt->request->nr_sectors & 1)) {
printk(KERN_ERR "sd: Bad block number requested"); printk(KERN_ERR "sd: Bad block number requested");
return 0; return 0;
} else { } else {
...@@ -384,7 +385,7 @@ static int sd_init_command(Scsi_Cmnd * SCpnt) ...@@ -384,7 +385,7 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
} }
} }
if (sdp->sector_size == 2048) { if (sdp->sector_size == 2048) {
if ((block & 3) || (SCpnt->request.nr_sectors & 3)) { if ((block & 3) || (SCpnt->request->nr_sectors & 3)) {
printk(KERN_ERR "sd: Bad block number requested"); printk(KERN_ERR "sd: Bad block number requested");
return 0; return 0;
} else { } else {
...@@ -393,7 +394,7 @@ static int sd_init_command(Scsi_Cmnd * SCpnt) ...@@ -393,7 +394,7 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
} }
} }
if (sdp->sector_size == 4096) { if (sdp->sector_size == 4096) {
if ((block & 7) || (SCpnt->request.nr_sectors & 7)) { if ((block & 7) || (SCpnt->request->nr_sectors & 7)) {
printk(KERN_ERR "sd: Bad block number requested"); printk(KERN_ERR "sd: Bad block number requested");
return 0; return 0;
} else { } else {
...@@ -401,25 +402,25 @@ static int sd_init_command(Scsi_Cmnd * SCpnt) ...@@ -401,25 +402,25 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
this_count = this_count >> 3; this_count = this_count >> 3;
} }
} }
if (rq_data_dir(&SCpnt->request) == WRITE) { if (rq_data_dir(SCpnt->request) == WRITE) {
if (!sdp->writeable) { if (!sdp->writeable) {
return 0; return 0;
} }
SCpnt->cmnd[0] = WRITE_6; SCpnt->cmnd[0] = WRITE_6;
SCpnt->sc_data_direction = SCSI_DATA_WRITE; SCpnt->sc_data_direction = SCSI_DATA_WRITE;
} else if (rq_data_dir(&SCpnt->request) == READ) { } else if (rq_data_dir(SCpnt->request) == READ) {
SCpnt->cmnd[0] = READ_6; SCpnt->cmnd[0] = READ_6;
SCpnt->sc_data_direction = SCSI_DATA_READ; SCpnt->sc_data_direction = SCSI_DATA_READ;
} else { } else {
printk(KERN_ERR "sd: Unknown command %lx\n", printk(KERN_ERR "sd: Unknown command %lx\n",
SCpnt->request.flags); SCpnt->request->flags);
/* overkill panic("Unknown sd command %lx\n", SCpnt->request.flags); */ /* overkill panic("Unknown sd command %lx\n", SCpnt->request->flags); */
return 0; return 0;
} }
SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n", SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n",
nbuff, (rq_data_dir(&SCpnt->request) == WRITE) ? nbuff, (rq_data_dir(SCpnt->request) == WRITE) ?
"writing" : "reading", this_count, SCpnt->request.nr_sectors)); "writing" : "reading", this_count, SCpnt->request->nr_sectors));
SCpnt->cmnd[1] = (SCpnt->device->scsi_level <= SCSI_2) ? SCpnt->cmnd[1] = (SCpnt->device->scsi_level <= SCSI_2) ?
((SCpnt->lun << 5) & 0xe0) : 0; ((SCpnt->lun << 5) & 0xe0) : 0;
...@@ -664,7 +665,7 @@ static void sd_rw_intr(Scsi_Cmnd * SCpnt) ...@@ -664,7 +665,7 @@ static void sd_rw_intr(Scsi_Cmnd * SCpnt)
#if CONFIG_SCSI_LOGGING #if CONFIG_SCSI_LOGGING
char nbuff[6]; char nbuff[6];
SCSI_LOG_HLCOMPLETE(1, sd_dskname(DEVICE_NR(SCpnt->request.rq_dev), SCSI_LOG_HLCOMPLETE(1, sd_dskname(DEVICE_NR(SCpnt->request->rq_dev),
nbuff)); nbuff));
SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: %s: res=0x%x\n", SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: %s: res=0x%x\n",
nbuff, result)); nbuff, result));
...@@ -690,8 +691,8 @@ static void sd_rw_intr(Scsi_Cmnd * SCpnt) ...@@ -690,8 +691,8 @@ static void sd_rw_intr(Scsi_Cmnd * SCpnt)
(SCpnt->sense_buffer[4] << 16) | (SCpnt->sense_buffer[4] << 16) |
(SCpnt->sense_buffer[5] << 8) | (SCpnt->sense_buffer[5] << 8) |
SCpnt->sense_buffer[6]; SCpnt->sense_buffer[6];
if (SCpnt->request.bio != NULL) if (SCpnt->request->bio != NULL)
block_sectors = bio_sectors(SCpnt->request.bio); block_sectors = bio_sectors(SCpnt->request->bio);
switch (SCpnt->device->sector_size) { switch (SCpnt->device->sector_size) {
case 1024: case 1024:
error_sector <<= 1; error_sector <<= 1;
...@@ -716,7 +717,7 @@ static void sd_rw_intr(Scsi_Cmnd * SCpnt) ...@@ -716,7 +717,7 @@ static void sd_rw_intr(Scsi_Cmnd * SCpnt)
} }
error_sector &= ~(block_sectors - 1); error_sector &= ~(block_sectors - 1);
good_sectors = error_sector - SCpnt->request.sector; good_sectors = error_sector - SCpnt->request->sector;
if (good_sectors < 0 || good_sectors >= this_count) if (good_sectors < 0 || good_sectors >= this_count)
good_sectors = 0; good_sectors = 0;
break; break;
...@@ -1277,12 +1278,15 @@ static int sd_init() ...@@ -1277,12 +1278,15 @@ static int sd_init()
init_mem_lth(sd_gendisks[k].de_arr, N); init_mem_lth(sd_gendisks[k].de_arr, N);
init_mem_lth(sd_gendisks[k].flags, N); init_mem_lth(sd_gendisks[k].flags, N);
init_mem_lth(sd_gendisks[k].driverfs_dev_arr, N);
if (!sd_gendisks[k].de_arr || !sd_gendisks[k].flags) if (!sd_gendisks[k].de_arr || !sd_gendisks[k].flags ||
!sd_gendisks[k].driverfs_dev_arr)
goto cleanup_gendisks; goto cleanup_gendisks;
zero_mem_lth(sd_gendisks[k].de_arr, N); zero_mem_lth(sd_gendisks[k].de_arr, N);
zero_mem_lth(sd_gendisks[k].flags, N); zero_mem_lth(sd_gendisks[k].flags, N);
zero_mem_lth(sd_gendisks[k].driverfs_dev_arr, N);
sd_gendisks[k].major = SD_MAJOR(k); sd_gendisks[k].major = SD_MAJOR(k);
sd_gendisks[k].major_name = "sd"; sd_gendisks[k].major_name = "sd";
...@@ -1291,7 +1295,6 @@ static int sd_init() ...@@ -1291,7 +1295,6 @@ static int sd_init()
sd_gendisks[k].sizes = sd_sizes + k * (N << 4); sd_gendisks[k].sizes = sd_sizes + k * (N << 4);
sd_gendisks[k].nr_real = 0; sd_gendisks[k].nr_real = 0;
} }
return 0; return 0;
#undef init_mem_lth #undef init_mem_lth
...@@ -1302,6 +1305,7 @@ static int sd_init() ...@@ -1302,6 +1305,7 @@ static int sd_init()
for (k = 0; k < N_USED_SD_MAJORS; k++) { for (k = 0; k < N_USED_SD_MAJORS; k++) {
vfree(sd_gendisks[k].de_arr); vfree(sd_gendisks[k].de_arr);
vfree(sd_gendisks[k].flags); vfree(sd_gendisks[k].flags);
vfree(sd_gendisks[k].driverfs_dev_arr);
} }
cleanup_mem: cleanup_mem:
vfree(sd_gendisks); vfree(sd_gendisks);
...@@ -1436,6 +1440,8 @@ static int sd_attach(Scsi_Device * sdp) ...@@ -1436,6 +1440,8 @@ static int sd_attach(Scsi_Device * sdp)
SD_GENDISK(dsk_nr).nr_real++; SD_GENDISK(dsk_nr).nr_real++;
devnum = dsk_nr % SCSI_DISKS_PER_MAJOR; devnum = dsk_nr % SCSI_DISKS_PER_MAJOR;
SD_GENDISK(dsk_nr).de_arr[devnum] = sdp->de; SD_GENDISK(dsk_nr).de_arr[devnum] = sdp->de;
SD_GENDISK(dsk_nr).driverfs_dev_arr[devnum] =
&sdp->sdev_driverfs_dev;
if (sdp->removable) if (sdp->removable)
SD_GENDISK(dsk_nr).flags[devnum] |= GENHD_FL_REMOVABLE; SD_GENDISK(dsk_nr).flags[devnum] |= GENHD_FL_REMOVABLE;
sd_dskname(dsk_nr, diskname); sd_dskname(dsk_nr, diskname);
...@@ -1535,6 +1541,8 @@ static void sd_detach(Scsi_Device * sdp) ...@@ -1535,6 +1541,8 @@ static void sd_detach(Scsi_Device * sdp)
max_p = 1 << sd_gendisk.minor_shift; max_p = 1 << sd_gendisk.minor_shift;
start = dsk_nr << sd_gendisk.minor_shift; start = dsk_nr << sd_gendisk.minor_shift;
dev = MKDEV_SD_PARTITION(start); dev = MKDEV_SD_PARTITION(start);
driverfs_remove_partitions(&SD_GENDISK (dsk_nr),
SD_MINOR_NUMBER (start));
wipe_partitions(dev); wipe_partitions(dev);
for (j = max_p - 1; j >= 0; j--) for (j = max_p - 1; j >= 0; j--)
sd_sizes[start + j] = 0; sd_sizes[start + j] = 0;
...@@ -1556,9 +1564,16 @@ static void sd_detach(Scsi_Device * sdp) ...@@ -1556,9 +1564,16 @@ static void sd_detach(Scsi_Device * sdp)
**/ **/
static int __init init_sd(void) static int __init init_sd(void)
{ {
int rc;
SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n")); SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n"));
sd_template.module = THIS_MODULE; sd_template.module = THIS_MODULE;
return scsi_register_device(&sd_template); rc = scsi_register_device(&sd_template);
if (!rc) {
sd_template.scsi_driverfs_driver.name = (char *)sd_template.tag;
sd_template.scsi_driverfs_driver.bus = &scsi_driverfs_bus_type;
driver_register(&sd_template.scsi_driverfs_driver);
}
return rc;
} }
/** /**
...@@ -1591,6 +1606,7 @@ static void __exit exit_sd(void) ...@@ -1591,6 +1606,7 @@ static void __exit exit_sd(void)
sd_template.dev_max = 0; sd_template.dev_max = 0;
if (sd_gendisks != &sd_gendisk) if (sd_gendisks != &sd_gendisk)
vfree(sd_gendisks); vfree(sd_gendisks);
remove_driver(&sd_template.scsi_driverfs_driver);
} }
static Scsi_Disk * sd_get_sdisk(int index) static Scsi_Disk * sd_get_sdisk(int index)
......
...@@ -194,6 +194,7 @@ typedef struct sg_device /* holds the state of each scsi generic device */ ...@@ -194,6 +194,7 @@ typedef struct sg_device /* holds the state of each scsi generic device */
volatile char detached; /* 0->attached, 1->detached pending removal */ volatile char detached; /* 0->attached, 1->detached pending removal */
volatile char exclude; /* opened for exclusive access */ volatile char exclude; /* opened for exclusive access */
char sgdebug; /* 0->off, 1->sense, 9->dump dev, 10-> all devs */ char sgdebug; /* 0->off, 1->sense, 9->dump dev, 10-> all devs */
struct device sg_driverfs_dev;
} Sg_device; /* 36 bytes long on i386 */ } Sg_device; /* 36 bytes long on i386 */
...@@ -695,7 +696,7 @@ static int sg_common_write(Sg_fd * sfp, Sg_request * srp, ...@@ -695,7 +696,7 @@ static int sg_common_write(Sg_fd * sfp, Sg_request * srp,
srp->my_cmdp = SRpnt; srp->my_cmdp = SRpnt;
q = &SRpnt->sr_device->request_queue; q = &SRpnt->sr_device->request_queue;
SRpnt->sr_request.rq_dev = sdp->i_rdev; SRpnt->sr_request->rq_dev = sdp->i_rdev;
SRpnt->sr_sense_buffer[0] = 0; SRpnt->sr_sense_buffer[0] = 0;
SRpnt->sr_cmd_len = hp->cmd_len; SRpnt->sr_cmd_len = hp->cmd_len;
if (! (hp->flags & SG_FLAG_LUN_INHIBIT)) { if (! (hp->flags & SG_FLAG_LUN_INHIBIT)) {
...@@ -1222,7 +1223,7 @@ static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt) ...@@ -1222,7 +1223,7 @@ static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt)
SRpnt->sr_bufflen = 0; SRpnt->sr_bufflen = 0;
SRpnt->sr_buffer = NULL; SRpnt->sr_buffer = NULL;
SRpnt->sr_underflow = 0; SRpnt->sr_underflow = 0;
SRpnt->sr_request.rq_dev = mk_kdev(0, 0); /* "sg" _disowns_ request blk */ SRpnt->sr_request->rq_dev = mk_kdev(0, 0); /* "sg" _disowns_ request blk */
srp->my_cmdp = NULL; srp->my_cmdp = NULL;
srp->done = 1; srp->done = 1;
...@@ -1370,6 +1371,29 @@ static int __init sg_def_reserved_size_setup(char *str) ...@@ -1370,6 +1371,29 @@ static int __init sg_def_reserved_size_setup(char *str)
__setup("sg_def_reserved_size=", sg_def_reserved_size_setup); __setup("sg_def_reserved_size=", sg_def_reserved_size_setup);
#endif #endif
/* Driverfs file support */
static ssize_t sg_device_kdev_read(struct device *driverfs_dev, char *page,
size_t count, loff_t off)
{
Sg_device * sdp=list_entry(driverfs_dev, Sg_device, sg_driverfs_dev);
return off ? 0 : sprintf(page, "%x\n",sdp->i_rdev.value);
}
static struct driver_file_entry sg_device_kdev_file = {
name: "kdev",
mode: S_IRUGO,
show: sg_device_kdev_read,
};
static ssize_t sg_device_type_read(struct device *driverfs_dev, char *page,
size_t count, loff_t off)
{
return off ? 0 : sprintf (page, "CHR\n");
}
static struct driver_file_entry sg_device_type_file = {
name: "type",
mode: S_IRUGO,
show: sg_device_type_read,
};
static int sg_attach(Scsi_Device * scsidp) static int sg_attach(Scsi_Device * scsidp)
{ {
...@@ -1428,6 +1452,18 @@ static int sg_attach(Scsi_Device * scsidp) ...@@ -1428,6 +1452,18 @@ static int sg_attach(Scsi_Device * scsidp)
sdp->detached = 0; sdp->detached = 0;
sdp->sg_tablesize = scsidp->host ? scsidp->host->sg_tablesize : 0; sdp->sg_tablesize = scsidp->host ? scsidp->host->sg_tablesize : 0;
sdp->i_rdev = mk_kdev(SCSI_GENERIC_MAJOR, k); sdp->i_rdev = mk_kdev(SCSI_GENERIC_MAJOR, k);
memset(&sdp->sg_driverfs_dev, 0, sizeof(struct device));
sprintf(sdp->sg_driverfs_dev.bus_id, "%s:gen",
scsidp->sdev_driverfs_dev.bus_id);
sprintf(sdp->sg_driverfs_dev.name, "%sgeneric",
scsidp->sdev_driverfs_dev.name);
sdp->sg_driverfs_dev.parent = &scsidp->sdev_driverfs_dev;
sdp->sg_driverfs_dev.bus = &scsi_driverfs_bus_type;
device_register(&sdp->sg_driverfs_dev);
device_create_file(&sdp->sg_driverfs_dev, &sg_device_type_file);
device_create_file(&sdp->sg_driverfs_dev, &sg_device_kdev_file);
sdp->de = devfs_register (scsidp->de, "generic", DEVFS_FL_DEFAULT, sdp->de = devfs_register (scsidp->de, "generic", DEVFS_FL_DEFAULT,
SCSI_GENERIC_MAJOR, k, SCSI_GENERIC_MAJOR, k,
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
...@@ -1496,6 +1532,9 @@ static void sg_detach(Scsi_Device * scsidp) ...@@ -1496,6 +1532,9 @@ static void sg_detach(Scsi_Device * scsidp)
} }
SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d, dirty\n", k)); SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d, dirty\n", k));
devfs_unregister (sdp->de); devfs_unregister (sdp->de);
device_remove_file(&sdp->sg_driverfs_dev,sg_device_type_file.name);
device_remove_file(&sdp->sg_driverfs_dev,sg_device_kdev_file.name);
put_device(&sdp->sg_driverfs_dev);
sdp->de = NULL; sdp->de = NULL;
if (NULL == sdp->headfp) { if (NULL == sdp->headfp) {
kfree((char *)sdp); kfree((char *)sdp);
...@@ -1505,6 +1544,7 @@ static void sg_detach(Scsi_Device * scsidp) ...@@ -1505,6 +1544,7 @@ static void sg_detach(Scsi_Device * scsidp)
else { /* nothing active, simple case */ else { /* nothing active, simple case */
SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d\n", k)); SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d\n", k));
devfs_unregister (sdp->de); devfs_unregister (sdp->de);
put_device(&sdp->sg_driverfs_dev);
kfree((char *)sdp); kfree((char *)sdp);
sg_dev_arr[k] = NULL; sg_dev_arr[k] = NULL;
} }
...@@ -1529,9 +1569,16 @@ MODULE_PARM(def_reserved_size, "i"); ...@@ -1529,9 +1569,16 @@ MODULE_PARM(def_reserved_size, "i");
MODULE_PARM_DESC(def_reserved_size, "size of buffer reserved for each fd"); MODULE_PARM_DESC(def_reserved_size, "size of buffer reserved for each fd");
static int __init init_sg(void) { static int __init init_sg(void) {
int rc;
if (def_reserved_size >= 0) if (def_reserved_size >= 0)
sg_big_buff = def_reserved_size; sg_big_buff = def_reserved_size;
return scsi_register_device(&sg_template); rc = scsi_register_device(&sg_template);
if (!rc) {
sg_template.scsi_driverfs_driver.name = (char *)sg_template.tag;
sg_template.scsi_driverfs_driver.bus = &scsi_driverfs_bus_type;
driver_register(&sg_template.scsi_driverfs_driver);
}
return rc;
} }
static void __exit exit_sg( void) static void __exit exit_sg( void)
...@@ -1546,6 +1593,7 @@ static void __exit exit_sg( void) ...@@ -1546,6 +1593,7 @@ static void __exit exit_sg( void)
sg_dev_arr = NULL; sg_dev_arr = NULL;
} }
sg_template.dev_max = 0; sg_template.dev_max = 0;
remove_driver(&sg_template.scsi_driverfs_driver);
} }
......
...@@ -197,11 +197,11 @@ static void rw_intr(Scsi_Cmnd * SCpnt) ...@@ -197,11 +197,11 @@ static void rw_intr(Scsi_Cmnd * SCpnt)
int this_count = SCpnt->bufflen >> 9; int this_count = SCpnt->bufflen >> 9;
int good_sectors = (result == 0 ? this_count : 0); int good_sectors = (result == 0 ? this_count : 0);
int block_sectors = 0; int block_sectors = 0;
int device_nr = DEVICE_NR(SCpnt->request.rq_dev); int device_nr = DEVICE_NR(SCpnt->request->rq_dev);
Scsi_CD *SCp = &scsi_CDs[device_nr]; Scsi_CD *SCp = &scsi_CDs[device_nr];
#ifdef DEBUG #ifdef DEBUG
printk("sr.c done: %x %p\n", result, SCpnt->request.bh->b_data); printk("sr.c done: %x %p\n", result, SCpnt->request->bh->b_data);
#endif #endif
/* /*
Handle MEDIUM ERRORs or VOLUME OVERFLOWs that indicate partial success. Handle MEDIUM ERRORs or VOLUME OVERFLOWs that indicate partial success.
...@@ -219,14 +219,14 @@ static void rw_intr(Scsi_Cmnd * SCpnt) ...@@ -219,14 +219,14 @@ static void rw_intr(Scsi_Cmnd * SCpnt)
(SCpnt->sense_buffer[4] << 16) | (SCpnt->sense_buffer[4] << 16) |
(SCpnt->sense_buffer[5] << 8) | (SCpnt->sense_buffer[5] << 8) |
SCpnt->sense_buffer[6]; SCpnt->sense_buffer[6];
if (SCpnt->request.bio != NULL) if (SCpnt->request->bio != NULL)
block_sectors = bio_sectors(SCpnt->request.bio); block_sectors = bio_sectors(SCpnt->request->bio);
if (block_sectors < 4) if (block_sectors < 4)
block_sectors = 4; block_sectors = 4;
if (SCp->device->sector_size == 2048) if (SCp->device->sector_size == 2048)
error_sector <<= 2; error_sector <<= 2;
error_sector &= ~(block_sectors - 1); error_sector &= ~(block_sectors - 1);
good_sectors = error_sector - SCpnt->request.sector; good_sectors = error_sector - SCpnt->request->sector;
if (good_sectors < 0 || good_sectors >= this_count) if (good_sectors < 0 || good_sectors >= this_count)
good_sectors = 0; good_sectors = 0;
/* /*
...@@ -266,14 +266,14 @@ static int sr_init_command(Scsi_Cmnd * SCpnt) ...@@ -266,14 +266,14 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
int dev, devm, block=0, this_count, s_size; int dev, devm, block=0, this_count, s_size;
Scsi_CD *SCp; Scsi_CD *SCp;
devm = minor(SCpnt->request.rq_dev); devm = minor(SCpnt->request->rq_dev);
dev = DEVICE_NR(SCpnt->request.rq_dev); dev = DEVICE_NR(SCpnt->request->rq_dev);
SCp = &scsi_CDs[dev]; SCp = &scsi_CDs[dev];
SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %d, block = %d\n", devm, block)); SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %d, block = %d\n", devm, block));
if (dev >= sr_template.nr_dev || !SCp->device || !SCp->device->online) { if (dev >= sr_template.nr_dev || !SCp->device || !SCp->device->online) {
SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", SCpnt->request.nr_sectors)); SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", SCpnt->request->nr_sectors));
SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt)); SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt));
return 0; return 0;
} }
...@@ -286,8 +286,8 @@ static int sr_init_command(Scsi_Cmnd * SCpnt) ...@@ -286,8 +286,8 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
return 0; return 0;
} }
if (!(SCpnt->request.flags & REQ_CMD)) { if (!(SCpnt->request->flags & REQ_CMD)) {
blk_dump_rq_flags(&SCpnt->request, "sr unsup command"); blk_dump_rq_flags(SCpnt->request, "sr unsup command");
return 0; return 0;
} }
...@@ -308,23 +308,23 @@ static int sr_init_command(Scsi_Cmnd * SCpnt) ...@@ -308,23 +308,23 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
return 0; return 0;
} }
if (rq_data_dir(&SCpnt->request) == WRITE) { if (rq_data_dir(SCpnt->request) == WRITE) {
if (!SCp->device->writeable) if (!SCp->device->writeable)
return 0; return 0;
SCpnt->cmnd[0] = WRITE_10; SCpnt->cmnd[0] = WRITE_10;
SCpnt->sc_data_direction = SCSI_DATA_WRITE; SCpnt->sc_data_direction = SCSI_DATA_WRITE;
} else if (rq_data_dir(&SCpnt->request) == READ) { } else if (rq_data_dir(SCpnt->request) == READ) {
SCpnt->cmnd[0] = READ_10; SCpnt->cmnd[0] = READ_10;
SCpnt->sc_data_direction = SCSI_DATA_READ; SCpnt->sc_data_direction = SCSI_DATA_READ;
} else { } else {
blk_dump_rq_flags(&SCpnt->request, "Unknown sr command"); blk_dump_rq_flags(SCpnt->request, "Unknown sr command");
return 0; return 0;
} }
/* /*
* request doesn't start on hw block boundary, add scatter pads * request doesn't start on hw block boundary, add scatter pads
*/ */
if ((SCpnt->request.sector % (s_size >> 9)) || (SCpnt->request_bufflen % s_size)) { if ((SCpnt->request->sector % (s_size >> 9)) || (SCpnt->request_bufflen % s_size)) {
printk("sr: unaligned transfer\n"); printk("sr: unaligned transfer\n");
return 0; return 0;
} }
...@@ -334,13 +334,13 @@ static int sr_init_command(Scsi_Cmnd * SCpnt) ...@@ -334,13 +334,13 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
SCSI_LOG_HLQUEUE(2, printk("sr%d : %s %d/%ld 512 byte blocks.\n", SCSI_LOG_HLQUEUE(2, printk("sr%d : %s %d/%ld 512 byte blocks.\n",
devm, devm,
(rq_data_dir(&SCpnt->request) == WRITE) ? "writing" : "reading", (rq_data_dir(SCpnt->request) == WRITE) ? "writing" : "reading",
this_count, SCpnt->request.nr_sectors)); this_count, SCpnt->request->nr_sectors));
SCpnt->cmnd[1] = (SCpnt->device->scsi_level <= SCSI_2) ? SCpnt->cmnd[1] = (SCpnt->device->scsi_level <= SCSI_2) ?
((SCpnt->lun << 5) & 0xe0) : 0; ((SCpnt->lun << 5) & 0xe0) : 0;
block = SCpnt->request.sector / (s_size >> 9); block = SCpnt->request->sector / (s_size >> 9);
if (this_count > 0xffff) if (this_count > 0xffff)
this_count = 0xffff; this_count = 0xffff;
...@@ -496,7 +496,7 @@ void get_sectorsize(int i) ...@@ -496,7 +496,7 @@ void get_sectorsize(int i)
cmd[1] = (SCp->device->scsi_level <= SCSI_2) ? cmd[1] = (SCp->device->scsi_level <= SCSI_2) ?
((SCp->device->lun << 5) & 0xe0) : 0; ((SCp->device->lun << 5) & 0xe0) : 0;
memset((void *) &cmd[2], 0, 8); memset((void *) &cmd[2], 0, 8);
SRpnt->sr_request.rq_status = RQ_SCSI_BUSY; /* Mark as really busy */ SRpnt->sr_request->rq_status = RQ_SCSI_BUSY; /* Mark as really busy */
SRpnt->sr_cmd_len = 0; SRpnt->sr_cmd_len = 0;
memset(buffer, 0, 8); memset(buffer, 0, 8);
...@@ -731,6 +731,32 @@ static int sr_init() ...@@ -731,6 +731,32 @@ static int sr_init()
return 1; return 1;
} }
/* Driverfs file support */
static ssize_t sr_device_kdev_read(struct device *driverfs_dev,
char *page, size_t count, loff_t off)
{
kdev_t kdev;
kdev.value=(int)driverfs_dev->driver_data;
return off ? 0 : sprintf(page, "%x\n",kdev.value);
}
static struct driver_file_entry sr_device_kdev_file = {
name: "kdev",
mode: S_IRUGO,
show: sr_device_kdev_read,
};
static ssize_t sr_device_type_read(struct device *driverfs_dev,
char *page, size_t count, loff_t off)
{
return off ? 0 : sprintf (page, "CHR\n");
}
static struct driver_file_entry sr_device_type_file = {
name: "type",
mode: S_IRUGO,
show: sr_device_type_read,
};
void sr_finish() void sr_finish()
{ {
int i; int i;
...@@ -776,6 +802,20 @@ void sr_finish() ...@@ -776,6 +802,20 @@ void sr_finish()
sprintf(name, "sr%d", i); sprintf(name, "sr%d", i);
strcpy(SCp->cdi.name, name); strcpy(SCp->cdi.name, name);
sprintf(SCp->cdi.cdrom_driverfs_dev.bus_id, "%s:cd",
SCp->device->sdev_driverfs_dev.bus_id);
sprintf(SCp->cdi.cdrom_driverfs_dev.name, "%scdrom",
SCp->device->sdev_driverfs_dev.name);
SCp->cdi.cdrom_driverfs_dev.parent =
&SCp->device->sdev_driverfs_dev;
SCp->cdi.cdrom_driverfs_dev.bus = &scsi_driverfs_bus_type;
SCp->cdi.cdrom_driverfs_dev.driver_data =
(void *)__mkdev(MAJOR_NR, i);
device_register(&SCp->cdi.cdrom_driverfs_dev);
device_create_file(&SCp->cdi.cdrom_driverfs_dev,
&sr_device_type_file);
device_create_file(&SCp->cdi.cdrom_driverfs_dev,
&sr_device_kdev_file);
SCp->cdi.de = devfs_register(SCp->device->de, "cd", SCp->cdi.de = devfs_register(SCp->device->de, "cd",
DEVFS_FL_DEFAULT, MAJOR_NR, i, DEVFS_FL_DEFAULT, MAJOR_NR, i,
S_IFBLK | S_IRUGO | S_IWUGO, S_IFBLK | S_IRUGO | S_IWUGO,
...@@ -816,7 +856,14 @@ static void sr_detach(Scsi_Device * SDp) ...@@ -816,7 +856,14 @@ static void sr_detach(Scsi_Device * SDp)
static int __init init_sr(void) static int __init init_sr(void)
{ {
return scsi_register_device(&sr_template); int rc;
rc = scsi_register_device(&sr_template);
if (!rc) {
sr_template.scsi_driverfs_driver.name = (char *)sr_template.tag;
sr_template.scsi_driverfs_driver.bus = &scsi_driverfs_bus_type;
driver_register(&sr_template.scsi_driverfs_driver);
}
return rc;
} }
static void __exit exit_sr(void) static void __exit exit_sr(void)
...@@ -833,6 +880,7 @@ static void __exit exit_sr(void) ...@@ -833,6 +880,7 @@ static void __exit exit_sr(void)
blk_clear(MAJOR_NR); blk_clear(MAJOR_NR);
sr_template.dev_max = 0; sr_template.dev_max = 0;
remove_driver(&sr_template.scsi_driverfs_driver);
} }
module_init(init_sr); module_init(init_sr);
......
...@@ -93,7 +93,7 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen ...@@ -93,7 +93,7 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen
SRpnt->sr_data_direction = readwrite; SRpnt->sr_data_direction = readwrite;
/* use ISA DMA buffer if necessary */ /* use ISA DMA buffer if necessary */
SRpnt->sr_request.buffer = buffer; SRpnt->sr_request->buffer = buffer;
if (buffer && SRpnt->sr_host->unchecked_isa_dma && if (buffer && SRpnt->sr_host->unchecked_isa_dma &&
(virt_to_phys(buffer) + buflength - 1 > ISA_DMA_THRESHOLD)) { (virt_to_phys(buffer) + buflength - 1 > ISA_DMA_THRESHOLD)) {
bounce_buffer = (char *) kmalloc(buflength, GFP_DMA); bounce_buffer = (char *) kmalloc(buflength, GFP_DMA);
...@@ -112,7 +112,7 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen ...@@ -112,7 +112,7 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen
scsi_wait_req(SRpnt, (void *) sr_cmd, (void *) buffer, buflength, scsi_wait_req(SRpnt, (void *) sr_cmd, (void *) buffer, buflength,
IOCTL_TIMEOUT, IOCTL_RETRIES); IOCTL_TIMEOUT, IOCTL_RETRIES);
req = &SRpnt->sr_request; req = SRpnt->sr_request;
if (SRpnt->sr_buffer && req->buffer && SRpnt->sr_buffer != req->buffer) { if (SRpnt->sr_buffer && req->buffer && SRpnt->sr_buffer != req->buffer) {
memcpy(req->buffer, SRpnt->sr_buffer, SRpnt->sr_bufflen); memcpy(req->buffer, SRpnt->sr_buffer, SRpnt->sr_bufflen);
kfree(SRpnt->sr_buffer); kfree(SRpnt->sr_buffer);
......
...@@ -229,7 +229,7 @@ static int st_chk_result(Scsi_Tape *STp, Scsi_Request * SRpnt) ...@@ -229,7 +229,7 @@ static int st_chk_result(Scsi_Tape *STp, Scsi_Request * SRpnt)
scode = 0; scode = 0;
} }
dev = TAPE_NR(SRpnt->sr_request.rq_dev); dev = TAPE_NR(SRpnt->sr_request->rq_dev);
DEB( DEB(
if (debugging) { if (debugging) {
printk(ST_DEB_MSG "st%d: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n", printk(ST_DEB_MSG "st%d: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n",
...@@ -306,7 +306,7 @@ static void st_sleep_done(Scsi_Cmnd * SCpnt) ...@@ -306,7 +306,7 @@ static void st_sleep_done(Scsi_Cmnd * SCpnt)
int remainder; int remainder;
Scsi_Tape *STp; Scsi_Tape *STp;
st_nbr = TAPE_NR(SCpnt->request.rq_dev); st_nbr = TAPE_NR(SCpnt->request->rq_dev);
read_lock(&st_dev_arr_lock); read_lock(&st_dev_arr_lock);
STp = scsi_tapes[st_nbr]; STp = scsi_tapes[st_nbr];
read_unlock(&st_dev_arr_lock); read_unlock(&st_dev_arr_lock);
...@@ -328,11 +328,11 @@ static void st_sleep_done(Scsi_Cmnd * SCpnt) ...@@ -328,11 +328,11 @@ static void st_sleep_done(Scsi_Cmnd * SCpnt)
(STp->buffer)->midlevel_result = INT_MAX; /* OK */ (STp->buffer)->midlevel_result = INT_MAX; /* OK */
} else } else
(STp->buffer)->midlevel_result = SCpnt->result; (STp->buffer)->midlevel_result = SCpnt->result;
SCpnt->request.rq_status = RQ_SCSI_DONE; SCpnt->request->rq_status = RQ_SCSI_DONE;
(STp->buffer)->last_SRpnt = SCpnt->sc_request; (STp->buffer)->last_SRpnt = SCpnt->sc_request;
DEB( STp->write_pending = 0; ) DEB( STp->write_pending = 0; )
complete(SCpnt->request.waiting); complete(SCpnt->request->waiting);
} }
...@@ -371,16 +371,16 @@ static Scsi_Request * ...@@ -371,16 +371,16 @@ static Scsi_Request *
bp = (STp->buffer)->b_data; bp = (STp->buffer)->b_data;
SRpnt->sr_data_direction = direction; SRpnt->sr_data_direction = direction;
SRpnt->sr_cmd_len = 0; SRpnt->sr_cmd_len = 0;
SRpnt->sr_request.waiting = &(STp->wait); SRpnt->sr_request->waiting = &(STp->wait);
SRpnt->sr_request.rq_status = RQ_SCSI_BUSY; SRpnt->sr_request->rq_status = RQ_SCSI_BUSY;
SRpnt->sr_request.rq_dev = STp->devt; SRpnt->sr_request->rq_dev = STp->devt;
scsi_do_req(SRpnt, (void *) cmd, bp, bytes, scsi_do_req(SRpnt, (void *) cmd, bp, bytes,
st_sleep_done, timeout, retries); st_sleep_done, timeout, retries);
if (do_wait) { if (do_wait) {
wait_for_completion(SRpnt->sr_request.waiting); wait_for_completion(SRpnt->sr_request->waiting);
SRpnt->sr_request.waiting = NULL; SRpnt->sr_request->waiting = NULL;
(STp->buffer)->syscall_result = st_chk_result(STp, SRpnt); (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
} }
return SRpnt; return SRpnt;
...@@ -403,7 +403,7 @@ static void write_behind_check(Scsi_Tape * STp) ...@@ -403,7 +403,7 @@ static void write_behind_check(Scsi_Tape * STp)
) /* end DEB */ ) /* end DEB */
wait_for_completion(&(STp->wait)); wait_for_completion(&(STp->wait));
(STp->buffer)->last_SRpnt->sr_request.waiting = NULL; (STp->buffer)->last_SRpnt->sr_request->waiting = NULL;
(STp->buffer)->syscall_result = st_chk_result(STp, (STp->buffer)->last_SRpnt); (STp->buffer)->syscall_result = st_chk_result(STp, (STp->buffer)->last_SRpnt);
scsi_release_request((STp->buffer)->last_SRpnt); scsi_release_request((STp->buffer)->last_SRpnt);
...@@ -3531,6 +3531,31 @@ __setup("st=", st_setup); ...@@ -3531,6 +3531,31 @@ __setup("st=", st_setup);
#endif #endif
/* Driverfs file support */
static ssize_t st_device_kdev_read(struct device *driverfs_dev,
char *page, size_t count, loff_t off)
{
kdev_t kdev;
kdev.value=(int)driverfs_dev->driver_data;
return off ? 0 : sprintf(page, "%x\n",kdev.value);
}
static struct driver_file_entry st_device_kdev_file = {
name: "kdev",
mode: S_IRUGO,
show: st_device_kdev_read,
};
static ssize_t st_device_type_read(struct device *driverfs_dev,
char *page, size_t count, loff_t off)
{
return off ? 0 : sprintf (page, "CHR\n");
}
static struct driver_file_entry st_device_type_file = {
name: "type",
mode: S_IRUGO,
show: st_device_type_read,
};
static struct file_operations st_fops = static struct file_operations st_fops =
{ {
...@@ -3632,6 +3657,18 @@ static int st_attach(Scsi_Device * SDp) ...@@ -3632,6 +3657,18 @@ static int st_attach(Scsi_Device * SDp)
/* Rewind entry */ /* Rewind entry */
sprintf (name, "mt%s", formats[mode]); sprintf (name, "mt%s", formats[mode]);
sprintf(tpnt->driverfs_dev_r[mode].bus_id, "%s:%s",
SDp->sdev_driverfs_dev.name, name);
sprintf(tpnt->driverfs_dev_r[mode].name, "%s%s",
SDp->sdev_driverfs_dev.name, name);
tpnt->driverfs_dev_r[mode].parent = &SDp->sdev_driverfs_dev;
tpnt->driverfs_dev_r[mode].bus = &scsi_driverfs_bus_type;
tpnt->driverfs_dev_r[mode].driver_data =
(void *)__mkdev(MAJOR_NR, i + (mode << 5));
device_register(&tpnt->driverfs_dev_r[mode]);
device_create_file(&tpnt->driverfs_dev_r[mode],
&st_device_type_file);
device_create_file(&tpnt->driverfs_dev_r[mode], &st_device_kdev_file);
tpnt->de_r[mode] = tpnt->de_r[mode] =
devfs_register (SDp->de, name, DEVFS_FL_DEFAULT, devfs_register (SDp->de, name, DEVFS_FL_DEFAULT,
MAJOR_NR, i + (mode << 5), MAJOR_NR, i + (mode << 5),
...@@ -3639,6 +3676,19 @@ static int st_attach(Scsi_Device * SDp) ...@@ -3639,6 +3676,19 @@ static int st_attach(Scsi_Device * SDp)
&st_fops, NULL); &st_fops, NULL);
/* No-rewind entry */ /* No-rewind entry */
sprintf (name, "mt%sn", formats[mode]); sprintf (name, "mt%sn", formats[mode]);
sprintf(tpnt->driverfs_dev_n[mode].bus_id, "%s:%s",
SDp->sdev_driverfs_dev.name, name);
sprintf(tpnt->driverfs_dev_n[mode].name, "%s%s",
SDp->sdev_driverfs_dev.name, name);
tpnt->driverfs_dev_n[mode].parent= &SDp->sdev_driverfs_dev;
tpnt->driverfs_dev_n[mode].bus = &scsi_driverfs_bus_type;
tpnt->driverfs_dev_n[mode].driver_data =
(void *)__mkdev(MAJOR_NR, i + (mode << 5) + 128);
device_register(&tpnt->driverfs_dev_n[mode]);
device_create_file(&tpnt->driverfs_dev_n[mode],
&st_device_type_file);
device_create_file(&tpnt->driverfs_dev_n[mode],
&st_device_kdev_file);
tpnt->de_n[mode] = tpnt->de_n[mode] =
devfs_register (SDp->de, name, DEVFS_FL_DEFAULT, devfs_register (SDp->de, name, DEVFS_FL_DEFAULT,
MAJOR_NR, i + (mode << 5) + 128, MAJOR_NR, i + (mode << 5) + 128,
...@@ -3738,8 +3788,18 @@ static void st_detach(Scsi_Device * SDp) ...@@ -3738,8 +3788,18 @@ static void st_detach(Scsi_Device * SDp)
for (mode = 0; mode < ST_NBR_MODES; ++mode) { for (mode = 0; mode < ST_NBR_MODES; ++mode) {
devfs_unregister (tpnt->de_r[mode]); devfs_unregister (tpnt->de_r[mode]);
tpnt->de_r[mode] = NULL; tpnt->de_r[mode] = NULL;
device_remove_file(&tpnt->driverfs_dev_r[mode],
st_device_type_file.name);
device_remove_file(&tpnt->driverfs_dev_r[mode],
st_device_kdev_file.name);
put_device(&tpnt->driverfs_dev_r[mode]);
devfs_unregister (tpnt->de_n[mode]); devfs_unregister (tpnt->de_n[mode]);
tpnt->de_n[mode] = NULL; tpnt->de_n[mode] = NULL;
device_remove_file(&tpnt->driverfs_dev_n[mode],
st_device_type_file.name);
device_remove_file(&tpnt->driverfs_dev_n[mode],
st_device_kdev_file.name);
put_device(&tpnt->driverfs_dev_n[mode]);
} }
if (tpnt->buffer) { if (tpnt->buffer) {
tpnt->buffer->orig_sg_segs = 0; tpnt->buffer->orig_sg_segs = 0;
...@@ -3770,8 +3830,16 @@ static int __init init_st(void) ...@@ -3770,8 +3830,16 @@ static int __init init_st(void)
verstr, st_fixed_buffer_size, st_write_threshold, verstr, st_fixed_buffer_size, st_write_threshold,
st_max_sg_segs); st_max_sg_segs);
if (devfs_register_chrdev(SCSI_TAPE_MAJOR, "st", &st_fops) >= 0) if (devfs_register_chrdev(SCSI_TAPE_MAJOR, "st", &st_fops) >= 0) {
return scsi_register_device(&st_template); if (scsi_register_device(&st_template) == 0) {
st_template.scsi_driverfs_driver.name =
(char *)st_template.tag;
st_template.scsi_driverfs_driver.bus =
&scsi_driverfs_bus_type;
driver_register(&st_template.scsi_driverfs_driver);
return 0;
}
}
printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", MAJOR_NR); printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", MAJOR_NR);
return 1; return 1;
...@@ -3790,6 +3858,7 @@ static void __exit exit_st(void) ...@@ -3790,6 +3858,7 @@ static void __exit exit_st(void)
kfree(scsi_tapes); kfree(scsi_tapes);
} }
st_template.dev_max = 0; st_template.dev_max = 0;
remove_driver(&st_template.scsi_driverfs_driver);
printk(KERN_INFO "st: Unloaded.\n"); printk(KERN_INFO "st: Unloaded.\n");
} }
......
...@@ -94,6 +94,8 @@ typedef struct { ...@@ -94,6 +94,8 @@ typedef struct {
int current_mode; int current_mode;
devfs_handle_t de_r[ST_NBR_MODES]; /* Rewind entries */ devfs_handle_t de_r[ST_NBR_MODES]; /* Rewind entries */
devfs_handle_t de_n[ST_NBR_MODES]; /* No-rewind entries */ devfs_handle_t de_n[ST_NBR_MODES]; /* No-rewind entries */
struct device driverfs_dev_r[ST_NBR_MODES];
struct device driverfs_dev_n[ST_NBR_MODES];
/* Status variables */ /* Status variables */
int partition; int partition;
......
...@@ -1217,7 +1217,7 @@ static void NCR5380_dma_complete( struct Scsi_Host *instance ) ...@@ -1217,7 +1217,7 @@ static void NCR5380_dma_complete( struct Scsi_Host *instance )
HOSTNO, NCR5380_read(BUS_AND_STATUS_REG), HOSTNO, NCR5380_read(BUS_AND_STATUS_REG),
NCR5380_read(STATUS_REG)); NCR5380_read(STATUS_REG));
if((sun3scsi_dma_finish(hostdata->connected->request.cmd))) { if((sun3scsi_dma_finish(hostdata->connected->request->cmd))) {
printk("scsi%d: overrun in UDC counter -- not prepared to deal with this!\n", HOSTNO); printk("scsi%d: overrun in UDC counter -- not prepared to deal with this!\n", HOSTNO);
printk("please e-mail sammy@oh.verio.com with a description of how this\n"); printk("please e-mail sammy@oh.verio.com with a description of how this\n");
printk("error was produced.\n"); printk("error was produced.\n");
...@@ -2016,9 +2016,9 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) ...@@ -2016,9 +2016,9 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
if((count > SUN3_DMA_MINSIZE) && (sun3_dma_setup_done if((count > SUN3_DMA_MINSIZE) && (sun3_dma_setup_done
!= cmd)) != cmd))
{ {
if((cmd->request.cmd == 0) || (cmd->request.cmd == 1)) { if((cmd->request->cmd == 0) || (cmd->request->cmd == 1)) {
sun3scsi_dma_setup(d, count, sun3scsi_dma_setup(d, count,
cmd->request.cmd); cmd->request->cmd);
sun3_dma_setup_done = cmd; sun3_dma_setup_done = cmd;
} }
} }
...@@ -2628,7 +2628,7 @@ static void NCR5380_reselect (struct Scsi_Host *instance) ...@@ -2628,7 +2628,7 @@ static void NCR5380_reselect (struct Scsi_Host *instance)
!= tmp)) != tmp))
{ {
sun3scsi_dma_setup(d, count, sun3scsi_dma_setup(d, count,
tmp->request.cmd); tmp->request->cmd);
sun3_dma_setup_done = tmp; sun3_dma_setup_done = tmp;
} }
#endif #endif
......
...@@ -518,7 +518,7 @@ static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance) ...@@ -518,7 +518,7 @@ static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance)
static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, Scsi_Cmnd *cmd, static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, Scsi_Cmnd *cmd,
int write_flag) int write_flag)
{ {
if((cmd->request.cmd == 0) || (cmd->request.cmd == 1)) if((cmd->request->cmd == 0) || (cmd->request->cmd == 1))
return wanted; return wanted;
else else
return 0; return 0;
......
...@@ -1206,7 +1206,7 @@ static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { ...@@ -1206,7 +1206,7 @@ static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
if (linked_comm && SCpnt->device->queue_depth > 2 if (linked_comm && SCpnt->device->queue_depth > 2
&& TLDEV(SCpnt->device->type)) { && TLDEV(SCpnt->device->type)) {
HD(j)->cp_stat[i] = READY; HD(j)->cp_stat[i] = READY;
flush_dev(SCpnt->device, SCpnt->request.sector, j, FALSE); flush_dev(SCpnt->device, SCpnt->request->sector, j, FALSE);
return 0; return 0;
} }
...@@ -1529,11 +1529,11 @@ static inline int reorder(unsigned int j, unsigned long cursec, ...@@ -1529,11 +1529,11 @@ static inline int reorder(unsigned int j, unsigned long cursec,
if (!(cpp->xdir == DTD_IN)) input_only = FALSE; if (!(cpp->xdir == DTD_IN)) input_only = FALSE;
if (SCpnt->request.sector < minsec) minsec = SCpnt->request.sector; if (SCpnt->request->sector < minsec) minsec = SCpnt->request->sector;
if (SCpnt->request.sector > maxsec) maxsec = SCpnt->request.sector; if (SCpnt->request->sector > maxsec) maxsec = SCpnt->request->sector;
sl[n] = SCpnt->request.sector; sl[n] = SCpnt->request->sector;
ioseek += SCpnt->request.nr_sectors; ioseek += SCpnt->request->nr_sectors;
if (!n) continue; if (!n) continue;
...@@ -1561,7 +1561,7 @@ static inline int reorder(unsigned int j, unsigned long cursec, ...@@ -1561,7 +1561,7 @@ static inline int reorder(unsigned int j, unsigned long cursec,
if (!input_only) for (n = 0; n < n_ready; n++) { if (!input_only) for (n = 0; n < n_ready; n++) {
k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt; k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
ll[n] = SCpnt->request.nr_sectors; pl[n] = SCpnt->pid; ll[n] = SCpnt->request->nr_sectors; pl[n] = SCpnt->pid;
if (!n) continue; if (!n) continue;
...@@ -1589,7 +1589,7 @@ static inline int reorder(unsigned int j, unsigned long cursec, ...@@ -1589,7 +1589,7 @@ static inline int reorder(unsigned int j, unsigned long cursec,
" cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n", " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n",
(ihdlr ? "ihdlr" : "qcomm"), SCpnt->channel, SCpnt->target, (ihdlr ? "ihdlr" : "qcomm"), SCpnt->channel, SCpnt->target,
SCpnt->lun, SCpnt->pid, k, flushcount, n_ready, SCpnt->lun, SCpnt->pid, k, flushcount, n_ready,
SCpnt->request.sector, SCpnt->request.nr_sectors, cursec, SCpnt->request->sector, SCpnt->request->nr_sectors, cursec,
YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only), YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only),
YESNO(overlap), cpp->xdir); YESNO(overlap), cpp->xdir);
} }
...@@ -1718,7 +1718,7 @@ static inline void ihdlr(int irq, unsigned int j) { ...@@ -1718,7 +1718,7 @@ static inline void ihdlr(int irq, unsigned int j) {
if (linked_comm && SCpnt->device->queue_depth > 2 if (linked_comm && SCpnt->device->queue_depth > 2
&& TLDEV(SCpnt->device->type)) && TLDEV(SCpnt->device->type))
flush_dev(SCpnt->device, SCpnt->request.sector, j, TRUE); flush_dev(SCpnt->device, SCpnt->request->sector, j, TRUE);
tstatus = status_byte(spp->target_status); tstatus = status_byte(spp->target_status);
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/raid/md.h> #include <linux/raid/md.h>
#include <linux/buffer_head.h> /* for invalidate_bdev() */ #include <linux/buffer_head.h> /* for invalidate_bdev() */
#include <linux/kmod.h>
#include "check.h" #include "check.h"
...@@ -225,6 +226,136 @@ void add_gd_partition(struct gendisk *hd, int minor, int start, int size) ...@@ -225,6 +226,136 @@ void add_gd_partition(struct gendisk *hd, int minor, int start, int size)
#endif #endif
} }
/* Driverfs file support */
static ssize_t partition_device_kdev_read(struct device *driverfs_dev,
char *page, size_t count, loff_t off)
{
kdev_t kdev;
kdev.value=(int)driverfs_dev->driver_data;
return off ? 0 : sprintf (page, "%x\n",kdev.value);
}
static struct driver_file_entry partition_device_kdev_file = {
name: "kdev",
mode: S_IRUGO,
show: partition_device_kdev_read,
};
static ssize_t partition_device_type_read(struct device *driverfs_dev,
char *page, size_t count, loff_t off)
{
return off ? 0 : sprintf (page, "BLK\n");
}
static struct driver_file_entry partition_device_type_file = {
name: "type",
mode: S_IRUGO,
show: partition_device_type_read,
};
void driverfs_create_partitions(struct gendisk *hd, int minor)
{
int pos = -1;
int devnum = minor >> hd->minor_shift;
char dirname[256];
struct device *parent = 0;
int max_p;
int part;
devfs_handle_t dir = 0;
/* get parent driverfs device structure */
if (hd->driverfs_dev_arr)
parent = hd->driverfs_dev_arr[devnum];
else /* if driverfs not supported by subsystem, skip partitions */
return;
/* get parent device node directory name */
if (hd->de_arr) {
dir = hd->de_arr[devnum];
if (dir)
pos = devfs_generate_path (dir, dirname,
sizeof dirname);
}
if (pos < 0) {
disk_name(hd, minor, dirname);
pos = 0;
}
max_p = (1 << hd->minor_shift);
/* for all partitions setup parents and device node names */
for(part=0; part < max_p; part++) {
if ((part == 0) || (hd->part[minor + part].nr_sects >= 1)) {
struct device * current_driverfs_dev =
&hd->part[minor+part].hd_driverfs_dev;
current_driverfs_dev->parent = parent;
/* handle disc case */
current_driverfs_dev->driver_data =
(void *)__mkdev(hd->major, minor+part);
if (part == 0) {
if (parent) {
sprintf(current_driverfs_dev->name,
"%sdisc", parent->name);
sprintf(current_driverfs_dev->bus_id,
"%s:disc", parent->bus_id);
} else {
sprintf(current_driverfs_dev->name,
"disc");
sprintf(current_driverfs_dev->bus_id,
"disc");
}
} else { /* this is a partition */
if (parent) {
sprintf(current_driverfs_dev->name,
"%spart%d", parent->name, part);
sprintf(current_driverfs_dev->bus_id,
"%s:p%d", parent->bus_id, part);
} else {
sprintf(current_driverfs_dev->name,
"part%d", part);
sprintf(current_driverfs_dev->bus_id,
"p%d" ,part);
}
}
if (parent) current_driverfs_dev->bus = parent->bus;
device_register(current_driverfs_dev);
device_create_file(current_driverfs_dev,
&partition_device_type_file);
device_create_file(current_driverfs_dev,
&partition_device_kdev_file);
}
}
return;
}
void driverfs_remove_partitions(struct gendisk *hd, int minor)
{
int max_p;
int part;
struct device * current_driverfs_dev;
max_p=(1 << hd->minor_shift);
/* for all parts setup parent relationships and device node names */
for(part=1; part < max_p; part++) {
if ((hd->part[minor + part].nr_sects >= 1)) {
current_driverfs_dev =
&hd->part[minor + part].hd_driverfs_dev;
device_remove_file(current_driverfs_dev,
partition_device_type_file.name);
device_remove_file(current_driverfs_dev,
partition_device_kdev_file.name);
put_device(current_driverfs_dev);
}
}
current_driverfs_dev = &hd->part[minor].hd_driverfs_dev;
device_remove_file(current_driverfs_dev,
partition_device_type_file.name);
device_remove_file(current_driverfs_dev,
partition_device_kdev_file.name);
put_device(current_driverfs_dev);
return;
}
static void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor) static void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor)
{ {
devfs_handle_t de = NULL; devfs_handle_t de = NULL;
...@@ -285,6 +416,13 @@ static void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor ...@@ -285,6 +416,13 @@ static void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor
truncate_inode_pages(bdev->bd_inode->i_mapping, 0); truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
bdput(bdev); bdput(bdev);
i = first_part_minor - 1; i = first_part_minor - 1;
/* Setup driverfs tree */
if (hd->sizes)
driverfs_create_partitions(hd, i);
else
driverfs_remove_partitions(hd, i);
devfs_register_partitions (hd, i, hd->sizes ? 0 : 1); devfs_register_partitions (hd, i, hd->sizes ? 0 : 1);
} }
......
...@@ -716,6 +716,7 @@ struct request_sense { ...@@ -716,6 +716,7 @@ struct request_sense {
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/devfs_fs_kernel.h> #include <linux/devfs_fs_kernel.h>
#include <linux/device.h>
struct cdrom_write_settings { struct cdrom_write_settings {
unsigned char fpacket; /* fixed/variable packets */ unsigned char fpacket; /* fixed/variable packets */
...@@ -730,6 +731,7 @@ struct cdrom_device_info { ...@@ -730,6 +731,7 @@ struct cdrom_device_info {
struct cdrom_device_info *next; /* next device_info for this major */ struct cdrom_device_info *next; /* next device_info for this major */
void *handle; /* driver-dependent data */ void *handle; /* driver-dependent data */
devfs_handle_t de; /* real driver should create this */ devfs_handle_t de; /* real driver should create this */
struct device cdrom_driverfs_dev; /* driverfs implementation */
int number; /* generic driver updates this */ int number; /* generic driver updates this */
/* specifications */ /* specifications */
kdev_t dev; /* device number */ kdev_t dev; /* device number */
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/major.h> #include <linux/major.h>
#include <linux/device.h>
enum { enum {
/* These three have identical behaviour; use the second one if DOS fdisk gets /* These three have identical behaviour; use the second one if DOS fdisk gets
...@@ -62,6 +63,7 @@ struct hd_struct { ...@@ -62,6 +63,7 @@ struct hd_struct {
unsigned long nr_sects; unsigned long nr_sects;
devfs_handle_t de; /* primary (master) devfs entry */ devfs_handle_t de; /* primary (master) devfs entry */
int number; /* stupid old code wastes space */ int number; /* stupid old code wastes space */
struct device hd_driverfs_dev; /* support driverfs hiearchy */
}; };
#define GENHD_FL_REMOVABLE 1 #define GENHD_FL_REMOVABLE 1
...@@ -80,6 +82,7 @@ struct gendisk { ...@@ -80,6 +82,7 @@ struct gendisk {
struct block_device_operations *fops; struct block_device_operations *fops;
devfs_handle_t *de_arr; /* one per physical disc */ devfs_handle_t *de_arr; /* one per physical disc */
struct device **driverfs_dev_arr;/* support driverfs hierarchy */
char *flags; /* one per physical disc */ char *flags; /* one per physical disc */
}; };
...@@ -241,6 +244,7 @@ char *disk_name (struct gendisk *hd, int minor, char *buf); ...@@ -241,6 +244,7 @@ char *disk_name (struct gendisk *hd, int minor, char *buf);
extern void devfs_register_partitions (struct gendisk *dev, int minor, extern void devfs_register_partitions (struct gendisk *dev, int minor,
int unregister); int unregister);
extern void driverfs_remove_partitions (struct gendisk *hd, int minor);
static inline unsigned int disk_index (kdev_t dev) static inline unsigned int disk_index (kdev_t dev)
{ {
......
...@@ -334,6 +334,7 @@ EXPORT_SYMBOL(bdev_read_only); ...@@ -334,6 +334,7 @@ EXPORT_SYMBOL(bdev_read_only);
EXPORT_SYMBOL(set_device_ro); EXPORT_SYMBOL(set_device_ro);
EXPORT_SYMBOL(bmap); EXPORT_SYMBOL(bmap);
EXPORT_SYMBOL(devfs_register_partitions); EXPORT_SYMBOL(devfs_register_partitions);
EXPORT_SYMBOL(driverfs_remove_partitions);
EXPORT_SYMBOL(blkdev_open); EXPORT_SYMBOL(blkdev_open);
EXPORT_SYMBOL(blkdev_get); EXPORT_SYMBOL(blkdev_get);
EXPORT_SYMBOL(blkdev_put); EXPORT_SYMBOL(blkdev_put);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment