From b14c72127fbe8f97e49de7437520175673f7306a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:30 +0200 Subject: ide: drop dsc_handle argument from ide_pc_intr() * Add 'int dsc' argument to ->pc_callback method. * Call ide_tape_handle_dsc() internally in ide_tape_callback() if dsc argument is set and update ide_pc_intr() accordingly. There should be no functional changes caused by this patch. Cc: Borislav Petkov Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/scsi/ide-scsi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 90212ac33be3..b9bfec24e913 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -137,7 +137,7 @@ static void ide_scsi_hex_dump(u8 *data, int len) static int idescsi_end_request(ide_drive_t *, int, int); -static void ide_scsi_callback(ide_drive_t *drive) +static void ide_scsi_callback(ide_drive_t *drive, int dsc) { idescsi_scsi_t *scsi = drive_to_idescsi(drive); struct ide_atapi_pc *pc = scsi->pc; @@ -298,8 +298,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) struct ide_atapi_pc *pc = scsi->pc; return ide_pc_intr(drive, pc, idescsi_pc_intr, get_timeout(pc), - idescsi_expiry, NULL, NULL, NULL, - ide_io_buffers); + idescsi_expiry, NULL, NULL, ide_io_buffers); } static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) -- cgit v1.2.1 From 2b9efba48283f34083df6bc53f6752fba4e4d409 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:31 +0200 Subject: ide: add pointer to the current packet command to ide_drive_t * Add pointer to the current packet command (struct ide_atapi_pc *pc) to ide_drive_t and use it instead of the pointer in struct ide_*_obj. * Use drive->pc in ide_{issue,transfer}_pc() and ide_pc_intr() instead of 'pc' argument. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/scsi/ide-scsi.c | 58 ++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index b9bfec24e913..bb8b3b123c7d 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -82,7 +82,6 @@ typedef struct ide_scsi_obj { struct gendisk *disk; struct Scsi_Host *host; - struct ide_atapi_pc *pc; /* Current packet command */ unsigned long transform; /* SCSI cmd translation layer */ unsigned long log; /* log flags */ } idescsi_scsi_t; @@ -140,7 +139,7 @@ static int idescsi_end_request(ide_drive_t *, int, int); static void ide_scsi_callback(ide_drive_t *drive, int dsc) { idescsi_scsi_t *scsi = drive_to_idescsi(drive); - struct ide_atapi_pc *pc = scsi->pc; + struct ide_atapi_pc *pc = drive->pc; if (pc->flags & PC_FLAG_TIMEDOUT) debug_log("%s: got timed out packet %lu at %lu\n", __func__, @@ -267,7 +266,7 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) spin_unlock_irqrestore(host->host_lock, flags); kfree(pc); blk_put_request(rq); - scsi->pc = NULL; + drive->pc = NULL; return 0; } @@ -278,8 +277,7 @@ static inline unsigned long get_timeout(struct ide_atapi_pc *pc) static int idescsi_expiry(ide_drive_t *drive) { - idescsi_scsi_t *scsi = drive_to_idescsi(drive); - struct ide_atapi_pc *pc = scsi->pc; + struct ide_atapi_pc *pc = drive->pc; debug_log("%s called for %lu at %lu\n", __func__, pc->scsi_cmd->serial_number, jiffies); @@ -294,19 +292,14 @@ static int idescsi_expiry(ide_drive_t *drive) */ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) { - idescsi_scsi_t *scsi = drive_to_idescsi(drive); - struct ide_atapi_pc *pc = scsi->pc; - - return ide_pc_intr(drive, pc, idescsi_pc_intr, get_timeout(pc), + return ide_pc_intr(drive, idescsi_pc_intr, get_timeout(drive->pc), idescsi_expiry, NULL, NULL, ide_io_buffers); } static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) { - idescsi_scsi_t *scsi = drive_to_idescsi(drive); - - return ide_transfer_pc(drive, scsi->pc, idescsi_pc_intr, - get_timeout(scsi->pc), idescsi_expiry); + return ide_transfer_pc(drive, idescsi_pc_intr, + get_timeout(drive->pc), idescsi_expiry); } static inline int idescsi_set_direction(struct ide_atapi_pc *pc) @@ -351,12 +344,10 @@ static int idescsi_map_sg(ide_drive_t *drive, struct ide_atapi_pc *pc) static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc) { - idescsi_scsi_t *scsi = drive_to_idescsi(drive); - /* Set the current packet command */ - scsi->pc = pc; + drive->pc = pc; - return ide_issue_pc(drive, pc, idescsi_transfer_pc, + return ide_issue_pc(drive, idescsi_transfer_pc, get_timeout(pc), idescsi_expiry); } @@ -621,6 +612,8 @@ static int idescsi_eh_abort (struct scsi_cmnd *cmd) int busy; int ret = FAILED; + struct ide_atapi_pc *pc; + /* In idescsi_eh_abort we try to gently pry our command from the ide subsystem */ if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) @@ -641,26 +634,27 @@ static int idescsi_eh_abort (struct scsi_cmnd *cmd) spin_lock_irq(&ide_lock); /* If there is no pc running we're done (our interrupt took care of it) */ - if (!scsi->pc) { + pc = drive->pc; + if (pc == NULL) { ret = SUCCESS; goto ide_unlock; } /* It's somewhere in flight. Does ide subsystem agree? */ - if (scsi->pc->scsi_cmd->serial_number == cmd->serial_number && !busy && - elv_queue_empty(drive->queue) && HWGROUP(drive)->rq != scsi->pc->rq) { + if (pc->scsi_cmd->serial_number == cmd->serial_number && !busy && + elv_queue_empty(drive->queue) && HWGROUP(drive)->rq != pc->rq) { /* * FIXME - not sure this condition can ever occur */ printk (KERN_ERR "ide-scsi: cmd aborted!\n"); - if (blk_sense_request(scsi->pc->rq)) - kfree(scsi->pc->buf); + if (blk_sense_request(pc->rq)) + kfree(pc->buf); /* we need to call blk_put_request twice. */ - blk_put_request(scsi->pc->rq); - blk_put_request(scsi->pc->rq); - kfree(scsi->pc); - scsi->pc = NULL; + blk_put_request(pc->rq); + blk_put_request(pc->rq); + kfree(pc); + drive->pc = NULL; ret = SUCCESS; } @@ -682,6 +676,8 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd) int ready = 0; int ret = SUCCESS; + struct ide_atapi_pc *pc; + /* In idescsi_eh_reset we forcefully remove the command from the ide subsystem and reset the device. */ if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) @@ -696,7 +692,9 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd) spin_lock_irq(cmd->device->host->host_lock); spin_lock(&ide_lock); - if (!scsi->pc || (req = scsi->pc->rq) != HWGROUP(drive)->rq || !HWGROUP(drive)->handler) { + pc = drive->pc; + + if (pc == NULL || (req = pc->rq) != HWGROUP(drive)->rq || !HWGROUP(drive)->handler) { printk (KERN_WARNING "ide-scsi: No active request in idescsi_eh_reset\n"); spin_unlock(&ide_lock); spin_unlock_irq(cmd->device->host->host_lock); @@ -707,9 +705,9 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd) if (__blk_end_request(req, -EIO, 0)) BUG(); if (blk_sense_request(req)) - kfree(scsi->pc->buf); - kfree(scsi->pc); - scsi->pc = NULL; + kfree(pc->buf); + kfree(pc); + drive->pc = NULL; blk_put_request(req); /* now nuke the drive queue */ -- cgit v1.2.1 From 844b9468523c8c2c45b90df4efcabcbe4926b5ab Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:31 +0200 Subject: ide: drop 'timeout' and 'expiry' arguments from ide_pc_intr() * Move idescsi_expiry() to ide-atapi.c. * Move get_timeout() to . * Drop 'timeout' and 'expiry' arguments from ide_pc_intr(). While at it: * idescsi_expiry() -> ide_scsi_expiry() * get_timeout() -> ide_scsi_get_timeout() There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/scsi/ide-scsi.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index bb8b3b123c7d..f71d1b34c3b1 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -270,36 +270,19 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) return 0; } -static inline unsigned long get_timeout(struct ide_atapi_pc *pc) -{ - return max_t(unsigned long, WAIT_CMD, pc->timeout - jiffies); -} - -static int idescsi_expiry(ide_drive_t *drive) -{ - struct ide_atapi_pc *pc = drive->pc; - - debug_log("%s called for %lu at %lu\n", __func__, - pc->scsi_cmd->serial_number, jiffies); - - pc->flags |= PC_FLAG_TIMEDOUT; - - return 0; /* we do not want the ide subsystem to retry */ -} - /* * Our interrupt handler. */ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) { - return ide_pc_intr(drive, idescsi_pc_intr, get_timeout(drive->pc), - idescsi_expiry, NULL, NULL, ide_io_buffers); + return ide_pc_intr(drive, idescsi_pc_intr, NULL, NULL, ide_io_buffers); } static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) { return ide_transfer_pc(drive, idescsi_pc_intr, - get_timeout(drive->pc), idescsi_expiry); + ide_scsi_get_timeout(drive->pc), + ide_scsi_expiry); } static inline int idescsi_set_direction(struct ide_atapi_pc *pc) @@ -348,7 +331,7 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive, drive->pc = pc; return ide_issue_pc(drive, idescsi_transfer_pc, - get_timeout(pc), idescsi_expiry); + ide_scsi_get_timeout(pc), ide_scsi_expiry); } /* -- cgit v1.2.1 From 6b0da28b2d0f4f4e2c55689fc062db569075ff60 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:32 +0200 Subject: ide: add ide_retry_pc() helper * Add ide_create_request_sense_cmd() and ide_retry_pc() helpers and convert ide-{atapi,floppy,tape}.c to use them. * Remove no longer used ide*_create_request_sense_cmd(), ide*_retry_pc() and 'retry_pc' argument from ide_pc_intr(). * Make ide_queue_pc_head() static. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/scsi/ide-scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index f71d1b34c3b1..ff2b19909838 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -275,7 +275,7 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) */ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) { - return ide_pc_intr(drive, idescsi_pc_intr, NULL, NULL, ide_io_buffers); + return ide_pc_intr(drive, idescsi_pc_intr, NULL, ide_io_buffers); } static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) -- cgit v1.2.1 From 85e39035ca381846b031690f4d1ac1f0660da0a2 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:32 +0200 Subject: ide: add ->pc_{update,io}_buffers methods Add ->pc_{update,io}_buffers methods to ide_drive_t and use them instead of {update,io}_buffers ide_pc_intr() arguments. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/scsi/ide-scsi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index ff2b19909838..b4ba40436c4f 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -275,7 +275,7 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) */ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) { - return ide_pc_intr(drive, idescsi_pc_intr, NULL, ide_io_buffers); + return ide_pc_intr(drive, idescsi_pc_intr); } static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) @@ -407,7 +407,9 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) set_bit(IDESCSI_LOG_CMD, &scsi->log); #endif /* IDESCSI_DEBUG_LOG */ - drive->pc_callback = ide_scsi_callback; + drive->pc_callback = ide_scsi_callback; + drive->pc_update_buffers = NULL; + drive->pc_io_buffers = ide_io_buffers; ide_proc_register_driver(drive, scsi->driver); } -- cgit v1.2.1 From aa5d2de7b080873f6d9ac3aede423c9713bf0caa Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:32 +0200 Subject: ide: make ide_pc_intr() static * Always use ide_pc_intr as a handler in ide_pc_intr(). * Remove no longer used ide*_pc_intr() and 'handler' argument from ide_{transfer_pc,pc_intr}(). * Make ide_pc_intr() static. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/scsi/ide-scsi.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index b4ba40436c4f..8733fe349254 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -270,18 +270,9 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) return 0; } -/* - * Our interrupt handler. - */ -static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) -{ - return ide_pc_intr(drive, idescsi_pc_intr); -} - static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) { - return ide_transfer_pc(drive, idescsi_pc_intr, - ide_scsi_get_timeout(drive->pc), + return ide_transfer_pc(drive, ide_scsi_get_timeout(drive->pc), ide_scsi_expiry); } -- cgit v1.2.1 From baf08f0be6d986521bb2fbdc7af51fc4847da734 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:32 +0200 Subject: ide: make ide_transfer_pc() static * Move ->ticks field from struct ide_floppy_obj to ide_drive_t. * Move idefloppy_transfer_pc() to ide-atapi.c and make ide_transfer_pc() use it. * Always use ide_transfer_pc as a handler in ide_issue_pc(). * Remove no longer used idefloppy_start_pc_transfer(), ide*_transfer_pc() and 'handler' argument from ide_issue_pc(). * Make ide_transfer_pc() static. While at it: * idefloppy_transfer_pc() -> ide_delayed_transfer_pc() * IDEFLOPPY_TICKS_DELAY -> IDEFLOPPY_PC_DELAY * ->ticks -> ->pc_delay There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/scsi/ide-scsi.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 8733fe349254..7d3d03f98914 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -270,12 +270,6 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) return 0; } -static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) -{ - return ide_transfer_pc(drive, ide_scsi_get_timeout(drive->pc), - ide_scsi_expiry); -} - static inline int idescsi_set_direction(struct ide_atapi_pc *pc) { switch (pc->c[0]) { @@ -321,8 +315,7 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive, /* Set the current packet command */ drive->pc = pc; - return ide_issue_pc(drive, idescsi_transfer_pc, - ide_scsi_get_timeout(pc), ide_scsi_expiry); + return ide_issue_pc(drive, ide_scsi_get_timeout(pc), ide_scsi_expiry); } /* -- cgit v1.2.1 From 97100fc816badbbc162644cfde7ad39ae9211fb4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:36 +0200 Subject: ide: add device flags Add 'unsigned long dev_flags' to ide_drive_t and convert bitfields to IDE_DFLAG_* flags. While at it: - IDE_DFLAG_ADDRESSING -> IDE_DFLAG_LBA48 - fixup some comments - remove needless g->flags zeroing from ide*_probe() There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/scsi/ide-scsi.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 7d3d03f98914..67e9ed95f669 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -331,7 +331,8 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r if (blk_sense_request(rq) || blk_special_request(rq)) { struct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special; - if (drive->using_dma && !idescsi_map_sg(drive, pc)) + if ((drive->dev_flags & IDE_DFLAG_USING_DMA) && + idescsi_map_sg(drive, pc) == 0) pc->flags |= PC_FLAG_DMA_OK; return idescsi_issue_pc(drive, pc); @@ -415,7 +416,7 @@ static void ide_scsi_remove(ide_drive_t *drive) ide_scsi_put(scsi); - drive->scsi = 0; + drive->dev_flags &= ~IDE_DFLAG_SCSI; } static int ide_scsi_probe(ide_drive_t *); @@ -767,7 +768,7 @@ static int ide_scsi_probe(ide_drive_t *drive) !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t)))) return -ENODEV; - drive->scsi = 1; + drive->dev_flags |= IDE_DFLAG_SCSI; g = alloc_disk(1 << PARTN_BITS); if (!g) @@ -808,7 +809,7 @@ static int ide_scsi_probe(ide_drive_t *drive) put_disk(g); out_host_put: - drive->scsi = 0; + drive->dev_flags &= ~IDE_DFLAG_SCSI; scsi_host_put(host); return err; } -- cgit v1.2.1 From 0ae4b3199ab1b6d511c6e0948e92049c272a346a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:37 +0200 Subject: ide: remove superfluous ->media field from ide_driver_t Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/scsi/ide-scsi.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 67e9ed95f669..c2995972052c 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -437,7 +437,6 @@ static ide_driver_t idescsi_driver = { .probe = ide_scsi_probe, .remove = ide_scsi_remove, .version = IDESCSI_VERSION, - .media = ide_scsi, .do_request = idescsi_do_request, .end_request = idescsi_end_request, .error = idescsi_atapi_error, -- cgit v1.2.1 From 4ab3d50224e35811b3351c28e63057595e8406e6 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:43 +0200 Subject: ide: set IDE_AFLAG_DRQ_INTERRUPT in do_identify() Set IDE_AFLAG_DRQ_INTERRUPT in do_identify() instead of ATAPI device drivers *_setup() methods. While at it: - use ata_id_cdb_intr() There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/scsi/ide-scsi.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index c2995972052c..740bad435995 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -385,8 +385,6 @@ static const struct ide_proc_devset idescsi_settings[] = { */ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) { - if ((drive->id[ATA_ID_CONFIG] & 0x0060) == 0x20) - set_bit(IDE_AFLAG_DRQ_INTERRUPT, &drive->atapi_flags); clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); #if IDESCSI_DEBUG_LOG set_bit(IDESCSI_LOG_CMD, &scsi->log); -- cgit v1.2.1